antlr 部分字符串中含有空格的解决方法

在antlr解析AST时我们通常都会把字符串之间的空格,回车,换行等隐藏

如下:

WS     
    : ( '\t' | ' ' | '\r' | '\n' )+   { $channel = HIDDEN; }
    ;

但是,如果我们希望保留解析出来的字符串怎么办呢。就如我们想解析出来一个程序段

foo(){

  a+b = c;

}

昨天在杨老师的指导下,我成功解析了含有空格的字符串。

具体方法如下:

 1 grammar lexParse;
 2 
 3 options {
 4         output = AST;
 5         ASTLabelType=CommonTree;
 6         language = Java;
 7 }
 8 
 9 tokens
10 {MARK;}
11 
12 starting
13     : block+
14     ;
15 
16 block
17     : BLOCK blockname BODY
18     -> ^(BLOCK blockname ^(MARK BODY));
19 
20 blockname
21     : ID
22     ;
23 
24 ID
25     : ('A..Z'|'a'..'z'|'0'..'9'|'_')+
26     ;
27 
28 BLOCK
29     : 'BLOCK'
30     ;
31 
32 BODY 
33     : BEGIN .* END
34     ; 
35 
36 //此外,token定义里的token或fragment之间如果没有WS,对应的输入文件中也
37 //不能匹配空格。
38 
39 WS      
40     : ( '\t' | ' ' | '\r' | '\n' )+   { $channel = HIDDEN; }
41     ;
42 
43 fragment
44 BEGIN
45     : 'BEGIN'
46     ;
47 
48 fragment
49 END
50     : 'END'
51     ;

".*"代码这段字符串可以包含任意字符。

输入文件:

BLOCK 0000blockname1
BEGIN body END

BLOCK blockname2
BEGIN body aa bb cc dd END

BLOCK blockname3
BEGIN {...
 } END

BLOCK blockname4
BEGIN body END

解析的树如下:

parser tree: (BLOCK 0000blockname1 (MARK BEGIN body END)) (BLOCK
blockname2 (MARK BEGIN body aa bb cc dd END)) (BLOCK blockname3 (MARK
BEGIN {...
} END)) (BLOCK blockname4 (MARK BEGIN body END))
---------------

注:BLOCK后的block_name中字符之间不能包含空格及回车。整个程序段的字符串必须以BEGIN开始,以END结束。

原文地址:https://www.cnblogs.com/zhengrui0452/p/3042900.html