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

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

Android crifan 3373浏览 0评论

【背景】

如下antlr语法:

fragment
LETTER	:	'a'..'z' | 'A'..'Z';


STR_LAN	:	'"|' LETTER LETTER '|"';

//fragment
STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;

multi_lan_str	:	STRING WS* STR_LAN STRING;

可以匹配:

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

但是用的是lexer的token。

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

【折腾过程】

1.改为:

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.再去改为:

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.189 seconds, using 22.04MB memory