使用GNU bison时,是否可以在匹配生产后不执行任何操作,然后检查是否可以使用其他一些规则来减少相同的令牌序列?基本上,我正在寻找的是类似的:
iexpr: VARIABLE { if (condition) {
/*some action */
}
else {
/*pushback read symbol, and check if other pattern can
be matched */
}
}
fexpr: VARIABLE { }
由于
答案 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 */
}