问题描述:

I'm having problems developing the grammar rule for a if/else....If someone could explain me what am I doing wrong it'd be great

/* Terminal symbols */

%token <string> TINTEGER

%token <token> TLBRACE TRBRACE TSEMI TLPAREN TRPAREN

%token <token> TMAIN TROTATE TFORWARD THUMAN TZOMBIE TATTACK TIF TELSE

/* Statements */

%type <block> main_loop block

%type <statement> statement rotate forward if else attack insideStatement

/* Expressions */

%type <numeric> numeric

%type <boolean> bool

%%

main_loop : TMAIN TLBRACE block TRBRACE { std::cout << "Main entry point found!" << std::endl; }

;

block : statement { std::cout << "Single statement" << std::endl; }

| block statement {std::cout<<"Multiple statements" <<std::endl;}

;

statement : rotate TSEMI

| forward TSEMI

| if

| attack TSEMI

;

if : TIF TLPAREN bool TRPAREN insideStatement

| TIF TLPAREN bool TRPAREN else

| statement

;

else :TELSE TLBRACE block TRBRACE{std::cout << "Else" << std::endl;}

;

insideStatement : TLBRACE block TRBRACE else

;

It compiles, but I don't really understand how the if/else works on Bison..

网友答案:

These rules:

statement : if ;
if : statement ;

are circular and make your grammar ambiguous, so you need to get rid of one of them (probably the if : statement ; rule.

Your other if rules are equivalent to:

if : TIF '(' bool ')' '{' block '}' TELSE '{' block '}'
   | TIF '(' bool ')' TELSE '{' block '}'
   ;

that is, you need to always have an else, but you might not have "true" block, which seems backwards. The else and insideStatement rules just server to obscure what is going one here.

In general, it's much clearer to use single character tokens for single character tokens rather than making up a name for the token...

相关阅读:
Top