忽略yacc中匹配的生产

时间:2012-12-24 22:07:30

标签: compiler-construction bison yacc

使用GNU bison时,是否可以在匹配生产后不执行任何操作,然后检查是否可以使用其他一些规则来减少相同的令牌序列?基本上,我正在寻找的是类似的:

iexpr: VARIABLE { if (condition) {
                    /*some action */
                  }
                  else {
                    /*pushback read symbol, and check if other pattern can
                         be matched */
                  }
                }
 fexpr: VARIABLE {   }

由于

2 个答案:

答案 0 :(得分:1)

您应该可以使用YYBACKUP功能。

答案 1 :(得分:1)

嗯,你可以用btyacc - 一个回溯的yacc变体来做到这一点:

iexpr: VARIABLE [ if (!condition)
                     /* this parse was wrong, backtrack and try something else */
                    YYERROR; ]
                { /* some action */ }
fexpr: VARIABLE { /* some other action */  }

但是正如评论者所指出的那样,尝试在解析器中进行类型检查是一个坏主意,只会导致一个不必要的复杂语法和错误的,混乱的类型错误错误消息。

相反,只需对所有类型的表达式使用单个(一组)expr规则,并在生成的解析树的单独传递中进行类型检查。你甚至不需要构建整个解析树并为此保留它;您可以构建解析树的一小部分并立即进行类型检查,然后在进一步解析之前丢弃不需要的信息。类似的东西:

expr: expr '+' expr {
    Typecheck('+', $1, $3); /* make sure operand types are appropriate for an add */
    $$ = BuildBinopCode('+', $1, $2); /* build some code to add two things */
}