解析:.NET 的 ANTLR

Parsing: ANTLR for .NET

我正在尝试解析以下文本:

<<! notes, Test!>>

语法:

grammar Hello;

prog:   stat+;
stat:   DELIMETER_OPEN expr DELIMETER_CLOSE ;
expr:   NOTES value=VAR_VALUE   # delim_body ;
VAR_VALUE   : [ a-Z A-Z 0-9 ! ];
NOTES   : 'notes,'
        |   ' notes,';
DELIMETER_OPEN  :   '<<!';
DELIMETER_CLOSE :   '!>>';

错误:

line 1:12 token recognition error at: '>' 
line 1:13 token recognition error at: '>' 
line 1:10 mismatched input ' !' expecting VAR_VALUE

(注意:添加了 DELIMITER defs,因为我之前忘记了它们)

试试这个:

grammar Hello;

prog :      stat+ EOF ;
stat :      DELIMETER_OPEN expr DELIMETER_CLOSE ;
expr :      NOTES COMMA value=VAR_VALUE   # delim_body ;

VAR_VALUE : ANBang* AlphaNum ;
NOTES :    'notes' ;
COMMA :    ','     ;
WS    : [ \t\r\n]+ -> skip ;

DELIMETER_OPEN  :  '<<!';
DELIMETER_CLOSE :  '!>>';

fragment ANBang : AlphaNum | Bang ;
fragment AlphaNum : [a-zA-Z0-9] ;
fragment Bang : '!' ;

理想情况下,规则必须相互明确。所以,VAR_VALUE规则被定义为从末尾限制!的存在。这将防止 ! 优先于 DELIMITER_CLOSEVAR_VALUE 消耗。当然,前提是重新定义是可以接受的。如果不是,则需要更复杂的解决方案。

此外,作为一般原则,skip 任何在语法上对解析不重要的内容。