我正在尝试使用ANTLR4来解析源文件。我需要做的一件事是字符串文字包含所有类型的字符和可能的空格,而普通标识符只包含英文字符和数字(白色空格被丢弃)。
我使用以下antlr语法规则(最小示例),但它不能按预期工作。
grammar parseString;
rules
: stringRule+
;
stringRule
: formatString
| idString
;
formatString
: STRING_DOUBLEQUOTE STRING STRING_DOUBLEQUOTE
;
idString
: (NONTERM | TERM)
;
// LEXER
STRING_DOUBLEQUOTE
: '"' ;
DIGITS
: DIGIT+
;
TERM
: UPPERCHAR CHAR+
;
NONTERM
: LOWERCHAR CHAR+
;
fragment
CHAR
: LOWERCHAR
| UPPERCHAR
| DIGIT
| '-'
| '_'
;
fragment
DIGIT
: [0-9]
;
fragment
LOWERCHAR
: [a-z]
;
fragment
UPPERCHAR
: [A-Z]
;
WS
: (' ' | '\t' | '\r' | '\n')+ -> skip
; // skip spaces, tabs, newlines
LINE_COMMENT
: '//' ~[\r\n]* -> skip
;
STRING
: ~('"')*
;
对于我使用的测试用例,
Test
HelloWorld
"$this is a string"
"*this is another string!"
我收到错误line 1:0 extraneous input 'Test\nHelloWorld\n' expecting {'"', TERM, NONTERM}
。并且'formatString'的最后两行被正确解析。但对于前两行,由于换行符('\ n')没有被丢弃,因此它们与'idString'不匹配。我想知道我做错了什么。
答案 0 :(得分:0)
您的STRING规则将匹配除引号之外的任何内容,因此几乎可以围绕任何内容。这太宽松了。你需要更加严格地定义STRING与我认为的其他区别。一旦它进入〜'' *它会围巾直到'''。
答案 1 :(得分:0)
是的,这个语法有问题。令牌STRING匹配'Test \ nHelloWorld \ n'。它会将所有内容放在此令牌中,但没有规则只需要TOKEN STRING。
考虑更改令牌STRING。