ANTLR:令牌的组合

时间:2012-06-20 11:28:56

标签: antlr

我有一个问题,我现在正在寻找一个小时左右。给定的ANTLR-lexer规则由2个(或更多)子规则组成。 Lexer现在生成单独的AST节点。

示例:

[...]
variable: '$' CamelCaseIdentifier;
CamelCaseIdentifier: ('a'..'z') Identifier*;
Identifier: ('a'..'z' | 'A' .. 'Z' | '0'..'9')+;
[...]

根据[...]$a[...]的给定输入,结果为..., $, a, ...

我正在寻找一种告诉词法分析者的方法,这些规则不应该分开:..., $a, ...

有人可以帮帮我吗?

3 个答案:

答案 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');
[...]

道歉,如果这完全偏离基础,我还在学习。

[1] https://theantlrguy.atlassian.net/wiki/spaces/ANTLR3/pages/2687210/Quick+Starter+on+Parser+Grammars+-+No+Past+Experience+Required