最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】antlr中支持EDDL的多国语言字符串其中用的是rule而非token

Android crifan 3519浏览 0评论

【背景】

如下antlr语法:

1
2
3
4
5
6
7
8
9
10
11
12
fragment
LETTER  :   'a'..'z' | 'A'..'Z';
 
 
STR_LAN :   '"|' LETTER LETTER '|"';
 
//fragment
STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;
 
multi_lan_str   :   STRING WS* STR_LAN STRING;

可以匹配:

1
"Deviation alarm"   "|sv|""Avviks larm"

但是用的是lexer的token。

现在去想要尝试用parser的rule去表示。

【折腾过程】

1.改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fragment
LETTER  :   'a'..'z' | 'A'..'Z';
 
 
STR_LAN :   '"|' LETTER LETTER '|"';
 
//fragment
STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;
 
string_value    :   (IMPORTED_VALUE | ID | multi_lan_str | STRING); // support multi language string
 
//multiple language string
//eg: "Current loop"       "|sv|""St?mslinga"
//multi_lan_str :   STRING '"|' LETTER LETTER '|"' STRING;
//multi_lan_str :   STRING WS+ STRING STRING;
//multi_lan_str :   STRING WS* STR_LAN STRING;
multi_lan_str   :   STRING single_lan_str+;
single_lan_str  :   WS* '"|' lan_id '|"' lan_str; // single language string
lan_id  :   LETTER LETTER;
lan_str :   STRING;

结果无法匹配:

multi lan str can not match

2.再去改为:

1
2
3
4
5
6
7
8
9
10
11
12
fragment
LETTER  :   'a'..'z' | 'A'..'Z';
 
STR_LAN :   '"|' LETTER LETTER '|"';
 
string_value    :   (IMPORTED_VALUE | ID | multi_lan_str | STRING); // support multi language string
 
multi_lan_str   :   STRING single_lan_str+;
//single_lan_str    :   WS* '"|' lan_id '|"' lan_str; // single language string
single_lan_str  :   WS* lan_id lan_str; // single language string
lan_id  :   STR_LAN;
lan_str :   STRING;

就可以了。

3.目前暂时缺点是:

对于lan_id,得到的是:

"|sv|"

而不是:

"sv"

但是凑合用了。

 

【总结】

antlr中的语法,尤其是lexer,还是需要额外小心,否则内容被之前的token匹配掉了,后面就无法匹配了。需要额外小心。

转载请注明:在路上 » 【已解决】antlr中支持EDDL的多国语言字符串其中用的是rule而非token

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
83 queries in 0.327 seconds, using 22.12MB memory