我正在尝试通过 Jison 为语言ChucK在 JavaScript 中生成一个解析器,并且已经有了一个良好的开端,除了生成的解析器无法处理的语言中存在歧义。最初的 ChuckK 编译器是由 Bison 生成的,它必须能够以某种方式解决这些歧义。
出于这个问题的目的,我已将问题简化为仅存在一种歧义的解释语法。作为参考,我列出了所有相关文件的要点(包括生成的parser)。项目结构如下:
- language/lexer.js:词法分析器。
- language/grammar.js:语法定义以及
generate
通过 Jison 生成解析器的函数 ( )。 - language/helpers.js : 辅助函数
- src/parser.js:生成的解析器。
- testparse.js:使用以下源代码测试解析器的程序:
Type var => out;
.
语法本身如下所示:
grammar = {
Program: [
['ProgramSection', '$$ = new yy.Program($1);']
],
ProgramSection: [
['Expression SEMICOLON', '$$ = new yy.ExpressionStatement($1);']
],
Expression: [
['DeclExpression', '$$ = $1;'],
['Expression OP DeclExpression', '$$ = new yy.ExpFromBinary($1, $2, $3);']
],
DeclExpression: [
['TypeDecl VarDeclList', '$$ = new yy.DeclExp($1, $2, 0);'],
['PrimaryExpression', '$$ = $1;']
],
VarDeclList: [
['VarDecl', '$$ = new yy.VarDeclList($1);']
],
VarDecl: [
['ID', '$$ = new yy.VarDecl($1);']
],
TypeDecl: [
['ID', '$$ = new yy.TypeDecl(new yy.IdList($1), 0);']
],
PrimaryExpression: [
['ID', '$$ = new yy.ExpFromId($1);']
]
};
歧义在于非终结符 DeclExpression 可以匹配TypeDecl VarDeclList
或PrimaryExpression
。这使得 Jison 发出以下警告:
States with conflicts:
State 7
TypeDecl -> ID . #lookaheads= ID SEMICOLON OP
PrimaryExpression -> ID . #lookaheads= ID SEMICOLON OP
并且生成的解析器无法解析测试代码(Type var => out;
),如下所示:
Error: Parse error on line 1: Unexpected 'SEMICOLON'
据我了解,它是=>
解析器尝试与 rule 匹配的运算符之后的部分TypeDecl VarDeclList
。
那么,如何生成能够处理这种歧义的解析器呢?