我需要解析以ABNF格式编写的SRGS文件。我需要抓住缺少双引号字符,例如:
public $sdsid300035= $<sdsid300101>s number "hee; // missing enclosing "
public $sdsid300036= $<sdsid300101>'s number "that's";
我有一条lexer规则:
DOUBLE_QUOTED_CHARACTERS: '"' ~(['"'])*? '"'
它匹配有效的输入,例如:"sometext"。但是如何编写检测和抛出错误的规则是否像示例中那样缺少双引号?
以下是在ANTLR v3:ANTLR4-lexer规则中使用@init block
一种方法是使用模式来隔离构成有效字符串的语法:
StrStart: '"' -> pushMode(strMode) ;
mode strMode;
ValidStringChar: [a-zA-Z ... ]+ ;
StrEnd: '"' -> popMode;
InvalidStrChar1: '>' -> popMode, type(RAngle);
InvalidStrChar2: ';' -> popMode, type(Semi);
...
当解析器在未终止字符串的情况下无法找到替代方案时,可以使用解析器的ANTLRErrorStrategy来定义如何处理错误。这个答案提供了关于使用错误策略的更多细节。您可以选择从解析器错误中"警告并恢复",而不仅仅是抛出错误。
我已经使用altrenatives实现了这一点,请参阅:
doubleQuotedCharacters
: DOUBLE_QUOTED_CHARACTERS
| WHITE_SPACES_IN_DOUBLE_QUOTE {notifyErrorListeners("Illegal empty quotes""!");}
| MISSING_CLOSING_DOUBLE_QT {notifyErrorListeners("Missing closing double quote!");}
;
WHITE_SPACES_IN_DOUBLE_QUOTE
: '"' WS* '"' -> channel(HIDDEN)
;
MISSING_CLOSING_DOUBLE_QT
: '"' ~('"')*?
;
DOUBLE_QUOTED_CHARACTERS
: '"' ~('"' | 'n'|'r' )*? '"'
{ setText(getText().substring(1, getText().length()-1));}
;
我可以很好地处理双引号中的字符串,这些字符串不分为多行。