我很难与ANTLR规则参数斗争。 ANTLR版本是4.4。
grammar A;
DIGIT: [0-9];
s: val EOF;
val: dval[1] | val '*' val;
dval[int x]: '.';
ANTLR失败
error(50): :2:32: syntax error: '1' came as a complete surprise to me while looking for rule element
/Users/parrt/antlr/code/antlr4/tool/src/org/antlr/v4/parse/GrammarTreeVisitor.g: node from after line 2:10 no viable alternative at input 'dval<tokenIndex=22>'
/Users/parrt/antlr/code/antlr4/tool/src/org/antlr/v4/parse/GrammarTreeVisitor.g: node from after line 2:10 no viable alternative at input 'dval<tokenIndex=22>'
/Users/parrt/antlr/code/antlr4/tool/src/org/antlr/v4/parse/GrammarTreeVisitor.g: node from after line 2:10 no viable alternative at input 'dval<tokenIndex=22>'
但没有规则参数的类似语法处理得很好。
grammar A;
DIGIT: [0-9];
s: val EOF;
val: dval | val '*' val;
dval: '.';
答案 0 :(得分:0)
ANTLR 确实允许使用规则参数,但我怀疑它们并没有像您期望的那样工作。这是您的语法的修订版(我猜测您的意图)。另外,请注意:这只是使用规则的 returns
注释。
(关于传递参数的更完整答案,可以参考https://stackoverflow.com/a/21747790/73764)
grammar A;
s: val EOF;
val returns [int value]: INT | INT '*' INT;
fragment DIGIT: [0-9];
INT: DIGIT+;
WS: [ \t\n] -> skip;
通过这个运行输入 89*10
,得到树 (val 89 * 10)
returns [int value]
部分只是将 value
添加到您的 ValContext
。这为您提供了一个变量,用于在您调用侦听器时放置计算值(覆盖 void exitVal(AParser.ValContext ctx);
方法。
public static class ValContext extends ParserRuleContext {
public int value;
public List<TerminalNode> INT() { return getTokens(AParser.INT); }
public TerminalNode INT(int i) {
return getToken(AParser.INT, i);
}
public ValContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_val; }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof AListener ) ((AListener)listener).enterVal(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof AListener ) ((AListener)listener).exitVal(this);
}
}
这在第 7 章的“注释解析树”部分的 The Definitive ANTLR Reference 中有详细说明。另请参阅第 15 章的“规则属性定义”(如果您打算使用ANTLR,这本书非常平易近人,非常宝贵的参考)