Antlr4 使用相同符号的不同词法分析器规则
Antlr4 different lexer rules using same symbols
我有以下语法:
grammar Test2;
my_rule: 'start' L_PAREN dummy R_PAREN DOT;
dummy: upper_word|lower_word|single_quoted|distinct_object|dollar_word|dollar_dollar_word;
single_quoted : SINGLE_QUOTE single_quoted_entry SINGLE_QUOTE;
single_quoted_entry : SQ_CHAR+;
distinct_object : DOUBLE_QUOTE distinct_object_entry DOUBLE_QUOTE ;
distinct_object_entry : DO_CHAR+;
dollar_dollar_word : DOLLAR DOLLAR lower_word; // make lower word token for the word
dollar_word : DOLLAR lower_word; // make lower word token for the word
upper_word : UPPER_WORD; // necessary since it should be one token
UPPER_WORD : UPPER_ALPHA ALPHA_NUMERIC*;
lower_word : LOWER_WORD; // necessary since it should be one token
LOWER_WORD : LOWER_ALPHA ALPHA_NUMERIC*;
DOLLAR : '$';
L_PAREN : '(';
R_PAREN : ')';
L_SQUARE_BRACKET : '[';
R_SQUARE_BRACKET : ']';
COMMA : ',';
VLINE : '|';
STAR : '*';
PLUS : '+';
ARROW : '>';
LESS_SIGN : '<';
DOT : '.';
UNDERSCORE : '_';
NUMERIC : [0-9];
LOWER_ALPHA : [a-z];
UPPER_ALPHA : [A-Z];
ALPHA_NUMERIC : LOWER_ALPHA
| UPPER_ALPHA
| NUMERIC
| UNDERSCORE;
DOUBLE_QUOTE : '"';
DO_CHAR : [\u0028-\u0029\u002B-\u0085\u0087-\u00B0]; // for double_quoted
SINGLE_QUOTE : '\'' ;
SQ_CHAR : [\u0028-\u002E\u0032-\u0085\u0087-\u00B0]; // for single_quoted
NEWLINE : '\r'? '\n' -> skip;
WS : [ \t]+ -> skip;
从 my_rule 开始,虚拟规则可以输入 upper_word、lower_word、dollar_word、dollar_dollar_word。
但是 single_quoted 和 distinct_object 不会工作,因为他们期望 SQ_CHAR+ 或 DO_CHAR+ 也涵盖已经定义的标记,例如 UPPER_ALPHA 等等。
一个解决方案是将所有定义的标记用管道添加到使用 SQ_CHAR/DO_CHAR 的地方。这可能看起来与此类似,但管道更多:
single_quoted : SINGLE_QUOTE single_quoted_entry SINGLE_QUOTE;
single_quoted_entry : (SQ_CHAR|UPPER_ALPHA|...way more tokens here...)+;
double_quoted 也是如此。由于检查所有已定义为标记的 ascii 代码是一项繁琐的任务,并且在更改语法时容易出错,因此一些更简单的解决方案将是有利的。
有什么简单的解决办法吗?
我找到了另一个适用的解决方案,因为我在语法的其他地方没有使用单引号和双引号。
创建包含引号的词法分析器标记有效:
grammar Test2;
my_rule: 'start' L_PAREN dummy R_PAREN DOT;
dummy: upper_word|lower_word|single_quoted|distinct_object|dollar_word|dollar_dollar_word;
single_quoted : SINGLE_QUOTED;
SINGLE_QUOTED : SINGLE_QUOTE SQ_CHAR+ SINGLE_QUOTE;
distinct_object : DISTINCT_OBJECT;
DISTINCT_OBJECT : DOUBLE_QUOTE DO_CHAR+ DOUBLE_QUOTE;
dollar_dollar_word : DOLLAR DOLLAR lower_word; // make lower word token for the word
dollar_word : DOLLAR lower_word; // make lower word token for the word
upper_word : UPPER_WORD; // necessary since it should be one token
UPPER_WORD : UPPER_ALPHA ALPHA_NUMERIC*;
lower_word : LOWER_WORD; // necessary since it should be one token
LOWER_WORD : LOWER_ALPHA ALPHA_NUMERIC*;
DOLLAR : '$';
L_PAREN : '(';
R_PAREN : ')';
L_SQUARE_BRACKET : '[';
R_SQUARE_BRACKET : ']';
COMMA : ',';
VLINE : '|';
STAR : '*';
PLUS : '+';
ARROW : '>';
LESS_SIGN : '<';
DOT : '.';
UNDERSCORE : '_';
NUMERIC : [0-9];
LOWER_ALPHA : [a-z];
UPPER_ALPHA : [A-Z];
ALPHA_NUMERIC : LOWER_ALPHA
| UPPER_ALPHA
| NUMERIC
| UNDERSCORE;
DOUBLE_QUOTE : '"';
DO_CHAR : [\u0028-\u0029\u002B-\u0085\u0087-\u00B0]; // for double_quoted
SINGLE_QUOTE : '\'' ;
SQ_CHAR : [\u0028-\u002E\u0032-\u0085\u0087-\u00B0]; // for single_quoted
NEWLINE : '\r'? '\n' -> skip;
WS : [ \t]+ -> skip;
SINGLE_QUOTED、DISTINCT_OBJECT、UPPER_WORD、LOWER_WORD位置无差异(已测试)
请注意,此解决方案不会为引号创建额外的叶子。
我有以下语法:
grammar Test2;
my_rule: 'start' L_PAREN dummy R_PAREN DOT;
dummy: upper_word|lower_word|single_quoted|distinct_object|dollar_word|dollar_dollar_word;
single_quoted : SINGLE_QUOTE single_quoted_entry SINGLE_QUOTE;
single_quoted_entry : SQ_CHAR+;
distinct_object : DOUBLE_QUOTE distinct_object_entry DOUBLE_QUOTE ;
distinct_object_entry : DO_CHAR+;
dollar_dollar_word : DOLLAR DOLLAR lower_word; // make lower word token for the word
dollar_word : DOLLAR lower_word; // make lower word token for the word
upper_word : UPPER_WORD; // necessary since it should be one token
UPPER_WORD : UPPER_ALPHA ALPHA_NUMERIC*;
lower_word : LOWER_WORD; // necessary since it should be one token
LOWER_WORD : LOWER_ALPHA ALPHA_NUMERIC*;
DOLLAR : '$';
L_PAREN : '(';
R_PAREN : ')';
L_SQUARE_BRACKET : '[';
R_SQUARE_BRACKET : ']';
COMMA : ',';
VLINE : '|';
STAR : '*';
PLUS : '+';
ARROW : '>';
LESS_SIGN : '<';
DOT : '.';
UNDERSCORE : '_';
NUMERIC : [0-9];
LOWER_ALPHA : [a-z];
UPPER_ALPHA : [A-Z];
ALPHA_NUMERIC : LOWER_ALPHA
| UPPER_ALPHA
| NUMERIC
| UNDERSCORE;
DOUBLE_QUOTE : '"';
DO_CHAR : [\u0028-\u0029\u002B-\u0085\u0087-\u00B0]; // for double_quoted
SINGLE_QUOTE : '\'' ;
SQ_CHAR : [\u0028-\u002E\u0032-\u0085\u0087-\u00B0]; // for single_quoted
NEWLINE : '\r'? '\n' -> skip;
WS : [ \t]+ -> skip;
从 my_rule 开始,虚拟规则可以输入 upper_word、lower_word、dollar_word、dollar_dollar_word。 但是 single_quoted 和 distinct_object 不会工作,因为他们期望 SQ_CHAR+ 或 DO_CHAR+ 也涵盖已经定义的标记,例如 UPPER_ALPHA 等等。
一个解决方案是将所有定义的标记用管道添加到使用 SQ_CHAR/DO_CHAR 的地方。这可能看起来与此类似,但管道更多:
single_quoted : SINGLE_QUOTE single_quoted_entry SINGLE_QUOTE;
single_quoted_entry : (SQ_CHAR|UPPER_ALPHA|...way more tokens here...)+;
double_quoted 也是如此。由于检查所有已定义为标记的 ascii 代码是一项繁琐的任务,并且在更改语法时容易出错,因此一些更简单的解决方案将是有利的。
有什么简单的解决办法吗?
我找到了另一个适用的解决方案,因为我在语法的其他地方没有使用单引号和双引号。
创建包含引号的词法分析器标记有效:
grammar Test2;
my_rule: 'start' L_PAREN dummy R_PAREN DOT;
dummy: upper_word|lower_word|single_quoted|distinct_object|dollar_word|dollar_dollar_word;
single_quoted : SINGLE_QUOTED;
SINGLE_QUOTED : SINGLE_QUOTE SQ_CHAR+ SINGLE_QUOTE;
distinct_object : DISTINCT_OBJECT;
DISTINCT_OBJECT : DOUBLE_QUOTE DO_CHAR+ DOUBLE_QUOTE;
dollar_dollar_word : DOLLAR DOLLAR lower_word; // make lower word token for the word
dollar_word : DOLLAR lower_word; // make lower word token for the word
upper_word : UPPER_WORD; // necessary since it should be one token
UPPER_WORD : UPPER_ALPHA ALPHA_NUMERIC*;
lower_word : LOWER_WORD; // necessary since it should be one token
LOWER_WORD : LOWER_ALPHA ALPHA_NUMERIC*;
DOLLAR : '$';
L_PAREN : '(';
R_PAREN : ')';
L_SQUARE_BRACKET : '[';
R_SQUARE_BRACKET : ']';
COMMA : ',';
VLINE : '|';
STAR : '*';
PLUS : '+';
ARROW : '>';
LESS_SIGN : '<';
DOT : '.';
UNDERSCORE : '_';
NUMERIC : [0-9];
LOWER_ALPHA : [a-z];
UPPER_ALPHA : [A-Z];
ALPHA_NUMERIC : LOWER_ALPHA
| UPPER_ALPHA
| NUMERIC
| UNDERSCORE;
DOUBLE_QUOTE : '"';
DO_CHAR : [\u0028-\u0029\u002B-\u0085\u0087-\u00B0]; // for double_quoted
SINGLE_QUOTE : '\'' ;
SQ_CHAR : [\u0028-\u002E\u0032-\u0085\u0087-\u00B0]; // for single_quoted
NEWLINE : '\r'? '\n' -> skip;
WS : [ \t]+ -> skip;
SINGLE_QUOTED、DISTINCT_OBJECT、UPPER_WORD、LOWER_WORD位置无差异(已测试)
请注意,此解决方案不会为引号创建额外的叶子。