我有一个问题,我现在正在寻找一个小时左右。给定的ANTLR-lexer规则由2个(或更多)子规则组成。 Lexer现在生成单独的AST节点。
示例:
[...]
variable: '$' CamelCaseIdentifier;
CamelCaseIdentifier: ('a'..'z') Identifier*;
Identifier: ('a'..'z' | 'A' .. 'Z' | '0'..'9')+;
[...]
根据[...]$a[...]
的给定输入,结果为..., $, a, ...
我正在寻找一种告诉词法分析者的方法,这些规则不应该分开:..., $a, ...
有人可以帮帮我吗?
答案 0 :(得分:2)
解析器规则以小写字母开头,词法分析器规则以大写字母开头。当您作为AST输出时,解析器规则中的每个单独的标记将成为一个单独的节点,因此您需要使variable
规则成为词法分析器规则而不是解析器规则:
Variable : '$' CamelCaseIdentifier;
CamelCaseIdentifier : ('a'..'z') Identifier*;
Identifier : ('a'..'z' | 'A' .. 'Z' | '0'..'9')+;
但如果你这样做,输入123456
将被标记为Identifier
,这可能不是你想要的。此外,Identifier
规则更好地命名为AlphaNum
。如果你制定一个片段规则,你就要确保词法分析器永远不会产生任何AlphaNum
个标记,但只会将AlphaNum
用于其他词法规则(如CamelCaseIdentifier
} 规则)。如果您还想要一个与Identifier
匹配的规则,请执行以下操作:
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';
答案 1 :(得分:0)
也许会尝试大写所有规则名称?
编辑:使用示例
grammar Dummy;
prog : VARIABLE*;
VARIABLE: '$' CAMELCASEIDENTIFIER;
CAMELCASEIDENTIFIER: ('a'..'z') IDENTIFIER*;
IDENTIFIER: ('a'..'z' | 'A' .. 'Z' | '0'..'9')+;
WS: (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN; };
答案 2 :(得分:0)
我是编译器和Antlr的初学者,但是根据我的有限理解,大写(词法分析器)规则仅适用于正则表达式。小写(解析器)规则也可以作为词法分析器规则加倍(参见[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');
[...]
道歉,如果这完全偏离基础,我还在学习。