0

我在为 if/else 开发语法规则时遇到问题......如果有人能解释我做错了什么,那就太好了

/* 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

 ;

它可以编译,但我真的不明白 if/else 如何在 Bison 上工作。

4

1 回答 1

3

这些规则:

statement : if ;
if : statement ;

是循环的并使您的语法模棱两可,因此您需要摆脱其中一个(可能是if : statement ;规则。

您的其他 if 规则等效于:

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

也就是说,您需要始终拥有一个 else,但您可能没有“true”块,这似乎是倒退的。elseandinsideStatement规则只是为了掩盖这里发生的事情。

通常,将单个字符标记用于单个字符标记而不是为标记编一个名称要清楚得多......

于 2013-05-10T22:13:36.470 回答