0

I want to design a parser that recognizes correctly written arithmetic expressions on rational numbers. The prepared analyzer should recognize rational numbers in the notation with a fractional dash, which consists of a numerator and denominator, separated by a sign, for example 2 | 3 (two thirds) or 12 | 5 (twelve fifths, i.e. two and two fifths).

Both negative and positive numbers should be recognized.

In addition, closing and opening brackets and the operators: +, -, *, / should be recognizable (addition, subtraction, multiplication and division respectively). For each correctly written expression, the program should print its numerical value to the standard output.

Right now I'm able to do similar code but with integers. I don't see a way to do this with rational numbers.

Do you have any suggestions?

I tried something like this but it won't work properly in all cases.

bot_max is the lowest denominator DIV is the character of division (int|int where | is division)

number : INT DIV INT {
  if($3 >= bot_max){
    bot_max = $3;
    $$ = $1;
    }
  else{
    $$ = ($1 * bot_max) / $3;
    }
  }
  | MINUS INT DIV INT {
  if($3 >= bot_max){
    bot_max = $4;
    $$ = $2;
    }
  else{
    $$ = ($2 * bot_max) / $4;
    }
  }
  ;
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
JustPawel
  • 165
  • 1
  • 9
  • What's the difference between `|` and `/` in your syntax? Can the operands of `|` only be literals (i.e. no `(1+2)|(3+4)`)? In that case, it'd still just be a special case of `/` though. Anyway, there's a lot of missing context for your code, so please post a [MCVE]. "bot_max is the lowest denominator" The lowest denominator of what? And why do you need it? – sepp2k May 10 '20 at 17:23
  • Sorry! I'll try to clarify. So input is for example: 2|1+4|1*5|2-18|5 And the output should be: 43|5 You can use both ```\``` and ```|``` but ```|``` is reserved for seperating two intigers in rational number. For example you can write that two fifth is 2|5 in this case – JustPawel May 10 '20 at 17:25
  • You mean `42|5`, right? Anyway, that doesn't really answer any of my questions. `2/1+4/1*5/2-18/5` would have the same result, right? So why have two operators for division? And why would you need to know the lowest denominator of anything to calculate that result? – sepp2k May 10 '20 at 17:34
  • No no, so for example we should be able to calculate 2|3/3|2 which is 1|1. Or 2|3/3|4 is 6|12 = 1|2, and so on – JustPawel May 10 '20 at 17:50
  • 1
    It would be a lot easier to write a reasonable answer if you'd provided a [mre] which describes how what your tried didn't work. As usual, I emphasize the word "minimal", which means "the smallest possible". It does not mean "some small piece of my program". Rather, it means, "a small complete program". Producing small programs is not only a good way to get help. It's a good way to help yourself. – rici May 10 '20 at 20:06
  • 1
    How are those eaxmples different from `(2/3)/(3/2)` or `(2/3)/(3/4)`? It looks like all you want is for `|` to be an alias for `/`, but with higher precedence? Or also disallow expressions as operands or `|`? – Chris Dodd May 10 '20 at 20:11
  • @ChrisDodd The result of `(2/3)/(3/2)` wouldn't be 1, so I think OP actually wants `|` to have *lower* precedence. – sepp2k May 10 '20 at 20:15
  • @sepp2k: With rational (not integer) arithmetic, `(2/3)/(3/2) == 1`. But you bring up a good point -- perhaps the OP wants to support both rational and integer arthmetic at the same time, and wants `/` to be integer division if the operands are integers, and rational division if the operands are rational? In which case he needs typed values in his evaluator. – Chris Dodd May 10 '20 at 20:21
  • @ChrisDodd With real or rational arithmetic the only way that a division of two operands results in 1 is if both operands are equal. `(2/3)/(3/2) = (2/3)*(2/3) = 4/9`. However, `2/(3/3)/2 = 2/1/2 = 2/2 = 1`. – sepp2k May 10 '20 at 20:27
  • You're right, I took the OP at his word when he said `2|3/3|2` would be 1, which it is not. – Chris Dodd May 10 '20 at 20:29
  • @ChrisDodd It would be if the precedence of `|` is lower than `/`. Thus my earlier comment. – sepp2k May 10 '20 at 20:31
  • You need a structure type to represent your rational values. You need a series of functions that perform arithmetic on those rational values, generating new rational values. And you'll need functions to convert to strings, etc. You write your code to use those functions. – Jonathan Leffler May 10 '20 at 21:43

0 Answers0