문제

I have some difficulty figuring out how to fix this. Basically (and this could be valable for any operator, yet I'm using the '+' as an example), say we had this rule in the lexer source :

[+-]?[0-9]+  { yylval = atoi(yytext); return INTEGER; }

And, in the paser, we'd have

exp: INTEGER
    | exp '+' exp  { $$ = $1 + $3; }
    | // etc etc

Then, in the resulting calculator, if I do

2 + 2

It would work as expected and give me the number 4.

But if I do

2+2

i.e. without spaces between 2, + and the other 2, I have a syntax error. The reason is that "+2" itself is a token, so bison reads "exp exp" and doesn't find anything since it's not part of the parser rules.

But, the line

2++2

is fine, since bison does "2" + "+2".

My question is... how could we fix that behavior so that "2+2" works the same way as "2 + 2"?


EDIT: It seems this question, as is, was a duplicate of another one, as pointed out in a comment below. Well, I have partically found the answer, but still.

If we make it the parser's job, and define a custom precedence level for the unary rules like this:

exp:
    | // bla bla bla
    | '+' exp %prec UPLUS { $$ = +$2; }
    | '-' exp %prec UMINUS { $$ = -$2; }

I still see a problem. Indeed, we can technically do this, in the calculator:

2+++++2
4
2+++++++++++2
4
2++++3
5

Is there a way to avoid such an ugly syntax and trigger an error or at least a warning, so that only 2+2 is allowed, and, at worse, only 2+2 and 2++2, which are the only two choices that make sense there!

Thanks!

도움이 되었습니까?

해결책

Unary operators are best handled in the grammar, not the scanner. There's no reason to do it the hard way. Just allow unary operators '+" and '-' in the productions for 'primary'; ignore unary '+'; and output code to negate the operand if the number of unary '-' operators is odd.

And get rid of [-+]? in the lex specification. At present you seem to be trying to handle it in both places.

There's also no reason to prohibit spaces between unary operators and their operands, or to only allow one unary operator, which is what handling it in the lexer condemns you to doing. Do it in the grammar. Only.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top