如何在Bison中明确定义单语句切换分支?

时间:2016-01-23 22:16:00

标签: bison

希望定义一个switch statement,其中分支的定义用花括号括起来,但是对于单语句分支可以省略大括号,比如单个语句if

所需语法的示例(为了清晰起见,白色间隔):

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)
...

如何解决给定语法中的转换/减少冲突?

1 个答案:

答案 0 :(得分: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的产生一样。但这只是一个建议。