问题 如何定义在ANTLR4中可以出现在多种词法模式中的标记?


我正在学习ANTLR4并尝试使用词法模式。如何在多个词法模式中出现相同的标记?作为一个非常简单的例子,假设我的语法有两种模式,我想在这两种模式中匹配空格和行尾,我怎么能这样做而不以WS_MODE1和WS_MODE2为例。有没有办法在两种情况下重用相同的定义?我希望在输出流中获得所有空白区域的WS令牌,而不管模式如何。这同样适用于EOL和其他可在两种模式下出现的关键字。


8280
2018-04-04 09:25


起源



答案:


规则必须有不同的名称,但您可以使用 -> type(...) lexer命令给它们相同的类型。

WS : [ \t]+;

mode Mode1;

    Mode1_WS : WS -> type(WS);

mode Mode2;

    Mode2_WS : WS -> type(WS);

即使 Mode1_WS 和 Mode2_WS 不是 fragment 规则,代码生成器将看到 type 命令并知道您重新分配了它们的类型,因此它不会为它们定义标记。


13
2018-04-04 13:06



关于这些Lexer规则的使用的简短问题:在解析器规则中,您是指WS还是Mode1_WS,Mode2_WS?我试过了两个,但似乎你只定义了Lexer规则而没有在解析器规则中直接引用它们。在那个senes中它更像是一个'import statement'而不是'别名'。 - andy droid
该 type 命令显式指定令牌类型,这是解析器将看到的类型。在这种情况下, WS 将用于引用由这3个规则中的任何一个创建的令牌。 - Sam Harwell
@SamHarwell什么终止了最终的模式规范?我注意到一些lexer文档在最终模式规范之后有片段defs,其中片段使用显示片段可用于所有模式,包括默认模式。 - bvj


答案:


规则必须有不同的名称,但您可以使用 -> type(...) lexer命令给它们相同的类型。

WS : [ \t]+;

mode Mode1;

    Mode1_WS : WS -> type(WS);

mode Mode2;

    Mode2_WS : WS -> type(WS);

即使 Mode1_WS 和 Mode2_WS 不是 fragment 规则,代码生成器将看到 type 命令并知道您重新分配了它们的类型,因此它不会为它们定义标记。


13
2018-04-04 13:06



关于这些Lexer规则的使用的简短问题:在解析器规则中,您是指WS还是Mode1_WS,Mode2_WS?我试过了两个,但似乎你只定义了Lexer规则而没有在解析器规则中直接引用它们。在那个senes中它更像是一个'import statement'而不是'别名'。 - andy droid
该 type 命令显式指定令牌类型,这是解析器将看到的类型。在这种情况下, WS 将用于引用由这3个规则中的任何一个创建的令牌。 - Sam Harwell
@SamHarwell什么终止了最终的模式规范?我注意到一些lexer文档在最终模式规范之后有片段defs,其中片段使用显示片段可用于所有模式,包括默认模式。 - bvj