How does one update and print a 'Rational' token in javacc? - linux

I have added the new token RATIONAL that recognises rational numbers on my JavaCC parser. How can I update the output part of the program to print the numeric value of the rational number?
For example ('2/5') value = 0.4, ('8/2') value = 4.0, ('4/0') value = infinity.
I will be grateful if anyone could help me. Thanks.

You need to further split the image of your RATIONAL token in order to have both numbers available for computation.
It's not clear from your question whether the parentheses and quotes are part of the defined syntax. If they are, you can easily define them as delimiters for a rational expression and define tokens for the numbers and the slash. In case of ambiguity with other places where numbers can appear, remember that lexical states are your friends.
If a rational expression is simply made of two numbers separated by a slash, then I'd recommend building an AST and evaluate it after the parsing is complete. You can alternatively evaluate it during the parsing, but the difficulty of this depends on the rest of your grammar.

Related

How do I parse a float from a string that might contain left-over characters without doing manual parsing?

How do I parse a float from a string that may contain left-over characters, and figure out where it ends, without doing manual parsing (e.g. parseFloat() in JS)?
An example would be the string "2e-1!". I want to evaluate the next float from the string such that I can split this string into "2e-1" and "!" (for example, if I wanted to implement a calculator.) How would I do this without writing a parser to see where the float ends, taking that as an &str, and then using .parse()?
I am aware that this means that I may have to parse nonstandard things such as "3e+1+e3" to 3e+1 (30) and "+e3". This is intended; I do not know all of the ways to format floating point numbers, especially the ones valid to Rust's parse::<f64>(), but I want to handle them regardless.
How can I do this, preferably without external libraries?
As mentioned in the comments, you need to either implement your own floating-point parser or use an external library. The parser in the standard library always errors out when it encounters additional junk in the input string – it doesn't even allow leading or trailing whitespace.
A good external crate to use is nom. It comes with an integrated parser for floating-point numbers that meets your requirements. Examples:
use nom::number::complete::double;
let parser = double::<_, ()>;
assert_eq!(parser("2.0 abc"), Ok((" abc", 2.0)));
let result = parser("Nanananananana hey, Jude!").unwrap();
assert_eq!(result.0, "ananananana hey, Jude!");
assert!(result.1.is_nan());
The parser expects the floating-point number at the very beginning of the string. If you want to allow leading whitespace, you can remove it first using trim_start().

Should I use n or * if I have exact number of things in the model?

I need to create UML diagrams for homework about a game ( called Downfall). I have to create it so that it works on any number (n) of player.
If this is an exact number that appears in multiple places of the diagram, should I use n or *? I would use it in multiplicity parameters and in size of array.
For example: There are n sides, and if there is a dial on a side, there has to be dial on each side at that position, so the dial has n-1 connected dials.
TL;DR
You can use a constant, like n. I would though recommend using a self-explanatory constant name like numberOfPlayers or at least noOfPlayers to make it obvious that it is always the same constant.
The name of the constant should be written without quotes (to distinguish it from strings, which are presented in double-quotes).
You can also use expression like n-1 as long as it evaluates to a non-negative Integer all the time.
Full explanation
Let's go by the UML specification. All section and figure references are from it.
1. Multiplicity definition (7.5.3.2)
The multiplicity is defined as lowerValue and upperValue.
The lower and upper bounds for the multiplicity of a MultiplicityElement are specified by ValueSpecifications (see Clause 8), which must evaluate to an Integer value for the lowerBound and an UnlimitedNatural value for the upperBound (see Clause 21 on Primitive Types)
2. ValueSpecification definition
ValueSpecification is defined as either LiteralSpecification (8.2) or Expression or OpaqueExpression (both described in 8.3).
LiteralSpecification is essentially just a number in the case interesting for us, so it is not what you need. But it is not the only option as www.admiraalit.nl suggests in his answer.
3. Expression definition (8.3.3.1)
An Expression is a mechanism to provide a value through some textual representation and eventually computation (I'm simplifying here). For instance:
An Expression is evaluated by first evaluating each of its operands and then performing the operation denoted by the Expression symbol to the resulting operand values
If you use a simple expression without operands, it simply becomes a constant that is a template for your model. So feel free to use a constant as a multiplicity value, as long as the constant evaluates to non-negative Integer (or UnlimitedNatural in case of an upper Limit).
It may even be an expression that changes its value over the lifecycle of the object however ensuring that this kind of multiplicity is met all the time might become challenging.
According to the UML specification, n is syntactically a valid multiplicity (see Ister's answer), but to make sure it is also semantically correct, you would have to define the meaning of n somewhere. Usually, n is not used as a multiplicity in UML diagrams.
I would advise you to use * in this case. If the minimum number of players is 2, you may use 2..*.
Additionally, you may use notes or constraints, e.g. { the number of connected dials is equal to the number of sides minus one }. You may also use a formal constraint language, like OCL.

Infix to postfix read negative integers as negative

Im doing a calculator for schoolwork and everything works except my scanner, cause when it takes a negative integer it doesnt see it as a negative number it just sees the subtraction sign as a operator and I want it to see it like a part of the operand:
String exp = "8+4*-12-4";
String[] temp = new String[exp.length()];
temp =exp.split("(?<=[-+*/])|(?=[-+*/])");
this makes it correct if its only positive integers.
for example
input: 8+4*12-4
and the
output:[8, 4, 12, *, +, 4, -]
but with a negative number it doesnt get it right!
so thats what I want help with, thanks in advance
LinkedList <String>list= new LinkedList<String>();
just takes each of the characters in the string and adds each to the resulting list. Instead of doing this, you need to write syntax-aware code. If you can insist on white space between all tokens, then you can split on spaces with, for example, String.split. If not, the simplest alternative is to iterate over the characters in the string "by hand" and create the output that way.
While I suppose it is also possible to use String.split with a non-capturing positive lookahead to also split on operators, figuring out regular expressions to that level of mastery is more difficult than solving the problem in code. I can't give an example for the positive lookahead assertion implementation, as I don't want to take the time to run up a development envirionment, write the code, create test cases and debug it - since I don't think this is the approach you should take in any case.

Why does the W3C XML Schema specification allow integers to have leading zeros?

Recently I had an example where in a xml message integer fields contained leading zeros. Unfortunately these zeros had relevance. One could argue why in the schema definition integer was chosen. But that is not my question. I was a little surprised leading zeros where allowed at all. So I looked up the specs which of course told me the supertype is decimal. But as expected specification don't really tell you why certain choices where made. So my question is really what is the rationale for allowing leading zeros at all? I mean numbers generally don't have leading zeros.
On a side note I guess the only way to add a restriction on leading zeros is by a pattern.
My recollection is that the XML Schema working group allowed leading zeroes in XSD decimals because they are allowed in normal decimal notation: 1, 01, 001, 0001, etc. all denote the same number in normal numerical notation. (But I don't actually remember that it was discussed at any length, so perhaps this is just my reason for believing it was the right thing to do and other WG members had other reasons for being satisfied with it.)
You are correct to suggest that the root of the problem is the use of xsd:integer as a type for a notation using strings of digits in which leading zeroes are significant (as for example in U.S. zip codes); I think you may be over-generous to say that one could argue about that decision. What possible arguments could one bring forward in favor of such an obviously erroneous choice?
Although numbers often doesn't have leading zeroes, parsing numbers almost always allows leading zeroes.
You don't want to disallow leading zeroes for numbers completely, because you want the option to write a number like 0.12 and not only like .12. As you want to allow at least one leading zero for floating point numbers, it would feel a bit restrictive to only allow one leading zero, and only for floating point numbers.
Sometimes numbers do have leading zeroes, for example the components in a date in ISO8601 format; 2014-05-02. If you want to parse a component it's convenient if the leading zero is allowed, so that you don't have to write extra code to remove it before parsing.
The XML specification just uses the same sets of rules for parsing numbers that is generally used for most formats and in most programming languages.

Why do Haskell numerical literals need to start and end with digits?

In The Haskell 98 Report it's said that
A floating literal must contain digits both before and after the decimal point; this ensures that a decimal point cannot be mistaken for another use of the dot character.
What other use might this be? I can't imagine any such legal expression.
(To clarify the motivation: I'm aware that many people write numbers like 9.0 or 0.7 all the time without needing to, but I can't quite befriend myself with this. I'm ok with 0.7 rather then the more compact but otherwise no better .7, but outwritten trailing zeroes feel just wrong to me unless they express some quantity is precise up to tenths, which is seldom the case in the occasions Haskell makes me write 9.0-numbers.)
I forgot it's legal to write function composition without surrounding whitespaces! That's of course a possibility, though one could avoid this problem by parsing floating literals greedily, such that replicate 3 . pred$8 ≡ ((replicate 3) . pred) 8 but replicate 3.pred$8 ≡ (replicate 3.0 pred)8.
There is no expression where an integer literal is required to stand directly next to a ., without whitespace?
One example of other uses is a dot operator (or any other operator starting or ending with a dot): replicate 3.pred$8.
Another possible use is in range expressions: [1..10].
Also, you can (almost) always write 9 instead of 9.0, thus avoiding the need for . altogether.
One of the most prominent usages of (.) is the function composition. And so the haskell compiler interpretes a . 1 composing the function a with a number and does not know what to do; analogously the other way 'round. Other usage of (.) could be found here.
Other problems with .7 vs. 0.7 are not known to me.
I don't really seem much of a problem with allowing '9.' and '.7'. I think the current design is more of a reflection of the ideas of the original designers of Haskell.
While it could probably be disambiguated, I don't think there is much to be gained from allowing .7 and 7.. Code is meant to be read by people as well as machines, and it's much easier to accidentally miss a decimal point at either end of a literal than in the middle.
I'll take the extra readability over the saved byte any day.

Resources