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

 ;

コンパイルはできますが、Bison で if/else がどのように機能するのかよくわかりません。

4

1 に答える 1

3

これらのルール:

statement : if ;
if : statement ;

は循環的であり、文法があいまいになるため、そのうちの 1 つを取り除く必要があります (おそらくif : statement ;規則.

あなたの他のifルールは以下と同等です:

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

つまり、常に else が必要ですが、「真」のブロックがない可能性があり、逆に見えます。elseとルールはinsideStatement、ここで何が起こっているのかを曖昧にするためのサーバーです。

一般に、トークンの名前を作成するよりも、1 文字のトークンに 1 文字のトークンを使用する方がはるかに明確です...

于 2013-05-10T22:13:36.470 に答える