了解 ANTLR4 令牌
Understanding ANTLR4 Tokens
我是 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);
}
}
现在,所有词法分析器规则都可以作为解析器中的静态常量使用class:
public static final int A=1, B=2, ADD=3, SUB=4;
我们如何使用它们来识别词法分析器规则?所有 A
、B
和 ADD
规则都可以匹配 '+'
。那么测试时应该使用什么类型。
我的意思是:
TstParser.InitContext ctx;
//...
ctx.token.getType() == //What type?
//TstParse.A
//TstParse.B
//or
//TstParse.ADD?
一般来说,我想了解 ANTLR4
如何知道 Token
的类型?
我将尝试向您介绍解析的过程。该过程有两个阶段。词法分析器部分(创建标记的地方)和解析器部分。 (这就是解析表达式的来源 - 如果我们谈论的是一般解析,则不是很精确)。您在此过程中要做的就是理解输入,同时可能创建输入模型。为了缓解这种情况,作业通常被分成更小的步骤。主要表示为 "words" 的标记(输入元素比字符大一些)更容易理解。 (准确地说是关键字、变量、文字)。
因此,您要做的第一步是将字符流形式的输入预处理为TOKENS。关于代币,你只能说它有什么价值,它是什么类型的代币。例如,在非常简单的计算器输入“2+3*9”中,“2”表示值为 2 的数字标记,“+”表示值为“+”的运算符标记等等……词法分析器部分的结果是标记流.可以想象,词法分析器和解析器规则非常相似。第一步使用字符,第二步使用标记。
关于 ANTLR(许多其他生成器的工作方式相同),有一条关于词法分析器的重要规则。您不能对不同的令牌使用相同的规则。因此,您插入的语法将不起作用,因为 A 和 B 之间的词法分析器部分不能不同。您可以对双方使用相同的标记名称。以后你会处理的。
为什么词法分析器规则不能相同?当词法分析器处理输入时,它遍历流。它会尝试它找到的第一个词法分析器规则,如果没问题,它将应用它。因此,如果还有另一条规则也适用,嗯,真可惜。它不会有机会。 ANTLR 中的解析器比词法分析器大方得多。
总结一下。标记是词法分析器的产物,它们是一个或多个字符的组,应该作为一个单元呈现给下一步。我们谈论的是变量名、运算符、函数名等
我是 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);
}
}
现在,所有词法分析器规则都可以作为解析器中的静态常量使用class:
public static final int A=1, B=2, ADD=3, SUB=4;
我们如何使用它们来识别词法分析器规则?所有 A
、B
和 ADD
规则都可以匹配 '+'
。那么测试时应该使用什么类型。
我的意思是:
TstParser.InitContext ctx;
//...
ctx.token.getType() == //What type?
//TstParse.A
//TstParse.B
//or
//TstParse.ADD?
一般来说,我想了解 ANTLR4
如何知道 Token
的类型?
我将尝试向您介绍解析的过程。该过程有两个阶段。词法分析器部分(创建标记的地方)和解析器部分。 (这就是解析表达式的来源 - 如果我们谈论的是一般解析,则不是很精确)。您在此过程中要做的就是理解输入,同时可能创建输入模型。为了缓解这种情况,作业通常被分成更小的步骤。主要表示为 "words" 的标记(输入元素比字符大一些)更容易理解。 (准确地说是关键字、变量、文字)。
因此,您要做的第一步是将字符流形式的输入预处理为TOKENS。关于代币,你只能说它有什么价值,它是什么类型的代币。例如,在非常简单的计算器输入“2+3*9”中,“2”表示值为 2 的数字标记,“+”表示值为“+”的运算符标记等等……词法分析器部分的结果是标记流.可以想象,词法分析器和解析器规则非常相似。第一步使用字符,第二步使用标记。
关于 ANTLR(许多其他生成器的工作方式相同),有一条关于词法分析器的重要规则。您不能对不同的令牌使用相同的规则。因此,您插入的语法将不起作用,因为 A 和 B 之间的词法分析器部分不能不同。您可以对双方使用相同的标记名称。以后你会处理的。
为什么词法分析器规则不能相同?当词法分析器处理输入时,它遍历流。它会尝试它找到的第一个词法分析器规则,如果没问题,它将应用它。因此,如果还有另一条规则也适用,嗯,真可惜。它不会有机会。 ANTLR 中的解析器比词法分析器大方得多。
总结一下。标记是词法分析器的产物,它们是一个或多个字符的组,应该作为一个单元呈现给下一步。我们谈论的是变量名、运算符、函数名等