ANTLR4 JavaScript 解析器:如何捕获解析中的错误

ANTLR4 JavaScript parser: how to catch an error in parsing

我在 ANTLR4 中有一个语法,我正在围绕它编写一个应用程序。相关语法片段如下所示:

grammar SomeGrammar;
// ... a bunch of other parse rules
operand
   : id | literal ;
id
   : ID ;
literal
   : LITERAL ;
// A bunch of other lexer rules
LITERAL       : NUMBER | BOOLEAN | STRING;
NUMBER        : INTEGER | FLOAT ;
INTEGER       : [0-9]+ ;
FLOAT         : INTEGER '.' INTEGER | '.' INTEGER ;
BOOLEAN       : 'TRUE' | 'FALSE' ;
ID            : [A-Za-z]+[A-Za-z0-9_]* ;
STRING        : '"' .*? '"' ;

我像这样生成 antlr4 JavaScript Lexer 和 Parser:

$ antlr4 -o . -Dlanguage=JavaScript -listener -visitor

然后我重载 exitLiteral () 原型来检查操作数是否是文字。问题是如果我通过

a

它(强制)将其解析为文字,并抛出错误(例如下面显示的 grun):

$ grun YARL literal -gui -tree
a
line 1:0 mismatched input 'a' expecting LITERAL
(literal a)

当我使用我重载的 JavaScript 解析器时出现同样的错误:

SomeGrammarLiteralPrinter.prototype.exitLiteral = function (ctx) {
    debug ("Literal is " + ctx.getText ()); // Literal is a
    };

我想捕获错误,以便确定它是 ID,而不是 LITERAL。我该怎么做?

感谢任何帮助。

更好的解决方案是调整语法,使其准确描述预期的语法开头:

startRule : ruleA ruleB EOF ;
ruleA     : something operand anotherthing ;
ruleB     : id assign literal  ;

operand   : ID | LITERAL ;
id        : ID ;
literal   : LITERAL ;

解析器对解析器规则执行自上而下的图形评估,从 startRule 开始。也就是说,解析器将按顺序评估列出的 startRule 元素,按顺序降序通过命名的子规则(并且只是那些子规则)。因此,ruleA 不会 encounter/consider idliteral 规则。

在这个有限的示例中,operandidliteral 规则看似重叠的定义没有冲突。

更新

OperandContext class 将包含 ID()LITERAL() 方法 returning TerminalNode。不 return null 的表示在该特定上下文中实际匹配的符号。查看生成的代码。