了解 ANTLR4 代币



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

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的类型?

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

因此,您要执行的第一步是以字符流的形式将输入预处理为 TOKENS。关于令牌,您只能说与它相关的价值以及它是哪种令牌。例如,在非常简单的计算器中,输入"2+3*9"2"表示值 2 的数字标记,"+"表示值"+"的运算符 toke,依此类推......词法分析器部分的结果是令牌流。可以想象,词法分析器和解析器规则非常相似。第一步处理字符,第二步处理令牌。

关于

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

为什么词法分析器规则不能相同?当词法分析器处理输入时,它会遍历流。它会尝试找到的第一个词法分析器规则,如果没问题,它将应用它。因此,如果有另一条规则也适用,嗯,真是可怜。它不会有机会。解析器在ANTLR中比词法分析器慷慨得多。

总结一下。令牌是词法分析器的产品,它们是一个或多个字符的组,应作为单个单元呈现到下一步。我们正在研究变量名称、运算符、函数名称等。

相关内容

  • 没有找到相关文章

最新更新