如何使用序列进行标记化,但不作为结果的标准返回

时间:2019-04-05 08:35:18

标签: antlr4

我想使用规则或序列作为分隔符来标记文件,但不返回分隔符

我尝试使用-> channel(hidden),但是搞砸了解析

我有这样的语法

grammar test;

file
 : l1 l2? l3
;

l1
 : 'L1:' STRING_LITERAL '\n'
;
l2
 : 'L2:'(NUMBER)+ '\n'
;
l3
 :'L3:' WORD|NUMBER '\n'
;


NUMBER          : [0-9]+ ;
STRING_LITERAL  : '"' (~["\\\r\n] | EscapeSequence)* '"';
WORD            : ('a'..'z' | 'A'..'Z')+;
fragment EscapeSequence
    : '\\' [btnfr"'\\]
    | '\\' ([0-3]? [0-7])? [0-7]
    ;

和输入文件(如

L1: "SO LONG"
L2: 42
L3: FISH

我不想返回L1: L2:L3:,但返回“ SO LONG” 42FISH

我得到了想要的令牌,但我也得到了\n L1: L2:L3:

See this for results tree

我还注意到,如果我将l1规则设置为l1:(〜[“ \\ r \ n])*;我可以匹配到行尾没有问题,但是我将每个单词作为一个单独的标记。对我来说很有意义,但是有没有办法将其作为单个令牌?

1 个答案:

答案 0 :(得分:0)

如果您希望能够在解析器中使用这些L1:标记,则无法删除它们。无论如何,我没有看到一个真正的用例。但是,我不明白为什么您不能在词法分析器期间仅跳过(或隐藏)这些标记。这似乎很好用:

parse
 : NL* line ( NL+ line )* NL* EOF
 ;

line
 : l1
 | l2
 | l3
 ;

l1 : STRING_LITERAL;
l2 : NUMBER+;
l3 : ( WORD | NUMBER );

NUMBER         : [0-9]+;
STRING_LITERAL : '"' ( ~["\\\r\n] | EscapeSequence )* '"';
WORD           : [a-zA-Z]+;

IGNORED
 : 'L' [0-9] ':' -> skip
 ;

SPACES
 : [ \t]+ -> skip
 ;

NL
 : '\r'? '\n'
 ;

fragment EscapeSequence
 : '\\' [btnfr"'\\]
 | '\\' ([0-3]? [0-7])? [0-7]
 ;

导致:

enter image description here

  

[...]因此,我应该能够执行以下操作:if(parser.l1()==“ SO LONG”“)然后执行一些操作

ANTLR不是这样工作的。解析器生成一个解析树(带有您定义的所有标记)。然后可以使用该解析树从中提取值。可以通过手动遍历解析树或使用ANTLR的侦听器(或访问者)类来提取值:https://github.com/antlr/antlr4/blob/master/doc/listeners.md

这是我对您的建议:请勿从词法分析器skip换行和L1:标记,而应使用侦听器或访问者从您的分析树中检索数据。