2016-01-23 35 views
0

需要定義一個switch statement,其中分支的定義由大括號包圍,但對於單語句分支可以省略大括號,如單語句if塊。如何在Bison中明確定義單語句開關分支?

(白色間隔爲清楚起見)所需的語法的一個例子:

switch 
    condition1 
     blah 
    | condition2 { 
     blah 
     blah 
    } 
    | condition3 
    | condition4 
     switch 
     nested_condition 
      blah 

我有以下語法,但它具有一個移位/減少衝突:

%token <union_string> T_ID "identifier" 

%% // begin rules 

program: 
    statement_list 
    ; 

statement_list: 
    statement_list statement 
    | empty 
    ; 

statement: 
    T_ID //added for completeness 
    | "switch" switch_branch_list //the subject of the switch is elided for brevity 
    ; 

switch_branch_list: 
    switch_branch_list "|" switch_branch 
    | switch_branch 
    ; 

switch_branch: 
    T_ID statement 
    | T_ID "{" statement_list "}" 
    ; 

empty: 
    ; 

衝突:

... 
State 9 

    5 statement: "switch" switch_branch_list . 
    6 switch_branch_list: switch_branch_list . "|" switch_branch 

    "|" shift, and go to state 13 

    "|"  [reduce using rule 5 (statement)] 
    $default reduce using rule 5 (statement) 
... 

如何解決給定語法中的shift/reduce衝突?

回答

0

沒有終止您的switch語句,所以如果switch分支的目標是另一個switch語句,程序就變得模糊不清。

我建議不允許開關(或其他複合語句)成爲分支的直接目標。堅持要用大括號包圍它。

所以,你最終會得到這樣的:

statement:   simple_statement | compound_statement 
simple_statement: expr 
        | '{' statement_list '}' 
        | ... 
compound_statement: switch_statement 
        | ... 
statement_list  /* empty */ | statement_list statement 

switch_statement: "switch" expr branch_list 
branch_list:  branch | branch_list '|' branch 
branch:    T_ID simple_statement 

注意,我把塊語句的語法('{' statement_list '}')作爲生產用於simple_statement之一。通常情況下,就是這樣,正如括號表達式是標準表達式語法中term的生產一樣。但這只是一個建議。