我在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
it(强制)将其解析为文字,并抛出错误(例如,如下grun
所示):
$ grun YARL literal -gui -tree
a
line 1:0 mismatched input 'a' expecting LITERAL
(literal a)
当我使用我过载的JavaScript Parser时出现同样的错误:
SomeGrammarLiteralPrinter.prototype.exitLiteral = function (ctx) {
debug ("Literal is " + ctx.getText ()); // Literal is a
};
我想抓住错误,以便我可以确定它是ID
,而不是LITERAL
。我该怎么做?
感谢任何帮助。
答案 0 :(得分:1)
更好的解决方案是调整语法,以便准确描述预期的语法:
startRule : ruleA ruleB EOF ;
ruleA : something operand anotherthing ;
ruleB : id assign literal ;
operand : ID | LITERAL ;
id : ID ;
literal : LITERAL ;
解析器从startRule
开始执行解析器规则的自上而下的图形评估。也就是说,解析器将按顺序评估列出的startRule
元素,按顺序降序通过命名的子规则(以及那些子规则)。因此,ruleA
不会遇到/考虑id
和literal
规则。
在这个有限的例子中,operand
,id
和literal
规则看似重叠的定义没有冲突。
<强>更新强>
OperandContext
类将包含返回ID()
的{{1}}和LITERAL()
方法。不返回null的那个表示在该特定上下文中实际匹配的符号。查看生成的代码。