Re: how to solve this reduce/reduce conflict?

2022-09-21 Thread Akim Demaille
Hi,

> Le 21 sept. 2022 à 23:31, Lukas Arsalan  a écrit :
> 
> exp:
>"-" "num"{ $$ = -*new Float($2); std::cout << "NUMinv" << $$ 
> << std::endl; }
> |  "num"{ $$ = new Float($1); std::cout << "num" << $$ << 
> std::endl; }
> |  "-" exp  { $$ = -*$2; std::cout << "inv" << $$ << std::endl; }

This snippet is clearly ambiguous, since it allows two different parses of -1, 
which -Wcex nicely showed.

If I were you, I would handle this in the scanner.  IOW, the scanner should be 
extended to support signed literals, and process that initial `-`.  So the 
grammar would no longer include `exp: "num"`.

Your actions look quite badly typed.  And `std::endl` should seldom be used, 
`'\n'` is enough.

Cheers!


how to solve this reduce/reduce conflict?

2022-09-21 Thread Lukas Arsalan
Usually -2^2 is considered to be -4, because: the minus is interpreted as a 
unary operator with lower precedence, than ^ (power)... E.g.: 
http://www.isthe.com/chongo/tech/comp/calc/

_but_:
I would like to have a parser,
[1] that binds the sign of a number stronger than a ^ (power), and
[2] that binds the unary inversion-operator of an expression weaker than a ^ 
(power).

My parse works, but the bison manual says, that i shalt fix the conflict, 
because it is somehow worrisome.
https://www.gnu.org/software/bison/manual/html_node/Reduce_002fReduce.html

example:
[1] -2^2=(-2)^2=4
[2] a=2 ; -a^2=-(a^2)=-(2^2)=-4

In this yy-file is a reduce/reduce conflict:
%left "+" "-";
%right "^";
exp:
   "-" "num"    { $$ = -*new Float($2); std::cout << "NUMinv" << $$ << 
std::endl; }
|  "num"    { $$ = new Float($1); std::cout << "num" << $$ << 
std::endl; }
|  "+" exp  { $$ = $2; std::cout << "noninv" << $$ << std::endl; }
|  "-" exp  { $$ = -*$2; std::cout << "inv" << $$ << std::endl; }
|  exp "+" exp  { $$ = *$1 + $3; std::cout << "add" << $$ << std::endl; 
}
|  exp "-" exp  { $$ = *$1 - $3; std::cout << "sub" << $$ << std::endl; 
}
|  exp "^" exp  { $$ = *$1 ^ $3; std::cout << "pow" << $$ << std::endl; 
};

bison -Wcounterexamples says:
  Example: "-" "num" •
  First reduce derivation
    exp
    ↳ 4: "-" "num" •
  Second reduce derivation
    exp
    ↳ 7: "-" exp
 ↳ 5: "num" •

How can i solve that without a preprocessor, that wraps negative numbers (e. 
g.: "-4*(-2+-3)" --> "(-4)*((-2)+(-3))") with brackets?

-Arne