【问题标题】:Understanding ANTLR4 Tokens了解 ANTLR4 令牌
【发布时间】:2016-02-23 14:31:15
【问题描述】:

我对 ANTLR 很陌生,我试图了解 Token 在 ATNLR4 中到底是什么。考虑以下非常荒谬的语法:

grammar Tst;

init: A token=('+'|'-') B;

A: .+?;
B: .+?;
ADD: '+';
SUB: '-';

ANTLR4 为其生成以下TstParser.InitContext

public static class InitContext extends ParserRuleContext {
        public Token token;       //<---------------------------- HERE
        public TerminalNode A() { return getToken(TstParser.A, 0); }
        public TerminalNode B() { return getToken(TstParser.B, 0); }
        public InitContext(ParserRuleContext parent, int invokingState) {
            super(parent, invokingState);
        }
        @Override public int getRuleIndex() { return RULE_init; }
        @Override
        public void enterRule(ParseTreeListener listener) {
            if ( listener instanceof TstListener ) ((TstListener)listener).enterInit(this);
        }
        @Override
        public void exitRule(ParseTreeListener listener) {
            if ( listener instanceof TstListener ) ((TstListener)listener).exitInit(this);
        }
    }

现在,所有词法分析器规则都可以作为解析器类中的静态常量使用:

public static final int A=1, B=2, ADD=3, SUB=4;

我们如何使用它们来识别词法分析器规则?所有ABADD 规则都可以匹配'+'。那么在测试时我应该使用什么类型。

我的意思是:

TstParser.InitContext ctx;
//...
ctx.token.getType() == //What type?
                       //TstParse.A
                       //TstParse.B
                       //or
                       //TstParse.ADD?

一般来说,我想了解ANTLR4 是如何知道Token 的类型的?

【问题讨论】:

    标签: java token antlr4 lexer


    【解决方案1】:

    我将尝试向您介绍解析的过程。该过程有两个阶段。词法分析器部分(创建标记的地方)和解析器部分。 (这就是解析表达式的来源——如果我们谈论的是一般的解析,这不是很精确)。您在此过程中要做的就是了解输入,同时可能创建输入模型。为了缓解这种情况,工作通常分为更小的步骤。主要表示为“单词”的标记(比字符更大的输入元素)更容易理解。 (准确地说是关键字、变量、文字)。

    因此,您要做的第一步是以字符流的形式将输入预处理为 TOKENS。关于代币,你所能说的只是与它相关的价值以及它是什么类型的代币。例如在非常简单的计算器中输入 "2+3*9" '2' 表示值为 2 的数字标记,'+' 表示值为 '+' 的运算符标记等等...... lexer 部分的结果是标记流.可以想象,词法分析器和解析器规则非常相似。第一步处理字符,第二步处理标记。

    关于 ANTLR(许多其他生成器的工作方式相同),有一个关于词法分析器的重要规则。对于不同的令牌,您不能有相同的规则。因此,您插入的语法将不起作用,因为 A 和 B 之间的词法分析器部分不能不同。您可以对双方使用相同的标记名称。你以后会照顾它的。

    为什么词法分析器规则不能相同?当词法分析器处理输入时,它会遍历流。它尝试找到的第一个词法分析器规则,如果没问题,它将应用它。因此,如果还有其他规则也适用,嗯,真可惜。它不会有机会。 ANTLR 中的 Parser 比 lexer 更慷慨。

    总结一下。标记是词法分析器的产物,它们是一个或多个字符的组,应该作为一个单元呈现给下一步。我们正在讨论变量名、运算符、函数名等。

    【讨论】:

      猜你喜欢
      • 2018-11-14
      • 2013-08-12
      • 2017-03-12
      • 1970-01-01
      • 2023-02-05
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 2020-09-14
      相关资源
      最近更新 更多