yacc - How to do a if condition

你离开我真会死。 提交于 2020-01-16 02:04:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!