带参数的Antlr规则

时间:2014-12-10 14:06:09

标签: antlr

我很难与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: '.';

1 个答案:

答案 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)

enter image description here

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,这本书非常平易近人,非常宝贵的参考)

相关问题