我正在使用 Bison 实现一个 Javascript 解析器。 ECMAScript specification指出
ExpressionStatement:
[lookahead ∉ { '{' , 'function'}] Expression ;
这打破了“{}”作为 BlockStatement(空语句块)和作为 ExpressionStatement(空对象文字)之间的歧义,因为 ExpressionStatement 不能以 '{' 标记开头,尽管 Expression 可以。
空语句块示例:
if (a > 5) {}
空对象字面量示例:
var a = {};
如何在 bison/yacc 语法中指定某些生产不应以某些特定标记开始?我的意思是,类似于:
expressionStatement
: %must-not-start-with('{', TOKEN_FUNCTION) expression ';'
;
我知道我可以复制我所有的表达式规则来定义一个“ExpressionNotStartingWithOpenCurlyBraceOrFunction”,但这会大大增加我的语法大小,所以我试图避免它。
最佳答案
Bison 中没有这样的指令。我看到您可以探索的另外两个选项。一种是研究由此产生的冲突,看看是否可以使用优先指令解决它(查看 http://www.gnu.org/software/bison/manual/html_node/Shift_002fReduce.html )。另一种方法是改用 GLR 解析器,并在运行时解决歧义。
如果适用,第一个选项可能更容易。但这在很大程度上取决于您的语法。
关于parsing - yacc 中的生产开始约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17195671/