问题
I am trying to do a simple if condition from an input file.
i will have something like
if(color = black)
No matter what i do i keep getting 1 shift / reduce I am very new to lex and yacc Do YACC grammars often have shift-reduce conflicts? and should i not worry about them?
My lex file will return every character in the file correctly so i wont show you the lex file
However, here is my yacc file:
%{
#include <ctype.h>
#include <stdio.h>
%}
|IF LPAREN COLOR EQ BLACK RPAREN {$$ = $1; printf("WONT COMPILE\n");}
;
in the yacc file i tried this but that is where i am getting the shift/ reduce
IF LPAREN COLOR EQ BLACK RPAREN {$$ = $1; printf("If statement\n");}
SOLVED
回答1:
I originally wrote a long answer about the “dangling else” ambiguity, but then I took a closer look at your grammar. Let’s cut it down to size a bit and demonstrate where the problems are:
%token IF COLOR BLACK
%%
statement
: statement command
| /*nothing*/
;
command
: IF {$$ = $1; printf ("IF\n");}
| ELSE {$$ = $1; printf("ELSE\n");}
| EQ {$$ = $1; printf("EQ\n");}
| THEN {$$ = $1; printf("THEN\n");}
| LPAREN {$$ = $1; printf("LPAREN\n");}
| RPAREN {$$ = $1; printf("RPAREN\n");}
| COLOR EQ BLACK {$$ = $3; printf("color is black\n");}
| IF LPAREN COLOR EQ BLACK RPAREN {$$ = $1; printf("WONT COMPILE\n");}
;
Just how do you expect the statement if(color = black)
to be parsed? Notice that the “color = black
” can reduce to a command
via COLOR EQ BLACK
or can be “shifted” onto the stack to become part of the longer parse IF LPAREN COLOR EQ BLACK RPAREN
.
That explains the specific warning you’re getting. Now, on to the rest of your grammar:
You don’t want to be writing your grammar so incomplete statements are meaningful. Notice that the single symbol “=
” is a complete valid command
and therefore a complete valid statement
—is that really what you want?
You’re going to want to rewrite this from scratch. Start simple:
%token NUMBER COMMAND IF THEN ELSE COLOR BLACK
%%
statement
: COMMAND NUMBER
| IF cond THEN statement
| /* nothing */
;
cond
: '(' COLOR '=' BLACK ')'
;
Not tested; but this should be enough to get you started. If you need to do something when you encounter a token, you can (for example) replace IF cond THEN COMMAND
with if cond then command
and add rules like
if : IF { printf("%s\n", "IF"); }
;
then: THEN { printf("%s\n", "THEN"); }
;
Start simple, add slowly, and refactor when rules get too hairy or repetitive. And work through a tutorial before you jump into a large project. The GNU Bison manual has a good tutorial, as does Kernighan & Pike’s The Unix Programming Environment.
来源:https://stackoverflow.com/questions/9218999/yacc-how-to-do-a-if-condition