ANTLR:令牌的组合
我有一个问题,我正在搜索大约一个小时。给定的ANTLR lexer规则由2个(或更多)子规则组成。Lexer现在生成单独的AST节点 例如:ANTLR:令牌的组合,antlr,Antlr,我有一个问题,我正在搜索大约一个小时。给定的ANTLR lexer规则由2个(或更多)子规则组成。Lexer现在生成单独的AST节点 例如: [...] variable: '$' CamelCaseIdentifier; CamelCaseIdentifier: ('a'..'z') Identifier*; Identifier: ('a'..'z' | 'A' .. 'Z' | '0'..'9')+; [...] 给定的[…]$a[…]输入结果是..,$,a,… 我正在寻找一种方法来告诉
[...]
variable: '$' CamelCaseIdentifier;
CamelCaseIdentifier: ('a'..'z') Identifier*;
Identifier: ('a'..'z' | 'A' .. 'Z' | '0'..'9')+;
[...]
给定的[…]$a[…]
输入结果是..,$,a,…
我正在寻找一种方法来告诉lexer,这些规则不应该分开:…$a,…
有人能帮我吗?也许可以尝试将所有规则名称都大写 编辑:以示例为例
grammar Dummy;
prog : VARIABLE*;
VARIABLE: '$' CAMELCASEIDENTIFIER;
CAMELCASEIDENTIFIER: ('a'..'z') IDENTIFIER*;
IDENTIFIER: ('a'..'z' | 'A' .. 'Z' | '0'..'9')+;
WS: (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN; };
解析器规则以小写字母开头,lexer规则以大写字母开头。当您作为AST输出时,解析器规则中的每个单独标记都将成为一个单独的节点,因此您需要将
变量
规则设置为lexer规则,而不是解析器规则:
Variable : '$' CamelCaseIdentifier;
CamelCaseIdentifier : ('a'..'z') Identifier*;
Identifier : ('a'..'z' | 'A' .. 'Z' | '0'..'9')+;
但是如果您这样做,输入123456
将被标记为标识符,这可能不是您想要的。此外,Identifier
规则最好命名为AlphaNum
。如果你对它做了一个片段规则,你就要确保lexer不会在自己身上产生任何AlphaNum
标记,而只会对其他lexer规则使用AlphaNum
(比如你的CamelCaseIdentifier
规则)。如果还需要与标识符匹配的规则,请执行以下操作:
Variable : '$' (CamelCaseIdentifier | Identifier);
CamelCaseIdentifier : 'a'..'z' AlphaNum*;
Identifier : 'A'..'Z' AlphaNum*;
// a fragment rule can't be used inside parser rules, only in lexer rules
fragment AlphaNum : 'a'..'z' | 'A' .. 'Z' | '0'..'9';
我是编译器和Antlr的初学者,但从我有限的理解来看,大写(lexer)规则只适用于正则表达式。小写(解析器)规则也可以兼作lexer规则(参见[1])。所以变量是大写还是小写并不重要,对吧
不管怎样,我可能错了,但这样做不是更简单吗:
[...]
variable: '$' ('a'..'z' | 'A' .. 'Z') ALPHANUM*;
ALPHANUM: ('a'..'z' | 'A' .. 'Z' | '0'..'9');
[...]
?
如果您计划重用('a'..'z'|'a'..'z'),那么您应该:
[...]
variable: '$' ALPHA ALPHANUM*;
fragment ALPHA: ('a'..'z' | 'A' .. 'Z')
ALPHANUM: (ALPHA | '0'..'9');
[...]
抱歉,如果这是完全不正确的,我仍在学习
[1]