我在解析antlr4中的格式行列表时遇到问题
* this is a string
* "first" this is "quoted"
* this is "quoted with \" "
Run Code Online (Sandbox Code Playgroud)
我想构建一个像这样的解析树
(list
(line * (value (string this is a string)))
(line * (value (parameter first) (string this is) (parameter quoted)))
(line * (value (string this is) (parameter quoted with " )))
)
Run Code Online (Sandbox Code Playgroud)
我有这种格式的antlr4语法
grammar List;
list : line+;
line : '*' (WS)+ value* NEWLINE;
value : string
| parameter
;
string : ((WORD) (WS)*)+;
parameter : '"'((WORD) (WS)*)+ '"';
WORD : (~'\n')+;
WS : '\t' | ' ';
NEWLINE : '\n';
Run Code Online (Sandbox Code Playgroud)
但是在第一个字符识别'*'本身就失败了,这让我感到困惑.
第1行:0输入不匹配'*这是一个字符串'期待'*'
问题是你的词法分析员太贪心了.规则
WORD : (~'\n')+;
Run Code Online (Sandbox Code Playgroud)
匹配几乎一切.这会导致词法分析器为您的输入生成以下标记:
WORD
* this is a string
NEWLINE
WORD
(`*"first"this is"quoted")NEWLINE
WORD
* this is "quoted with \" "
是的,这是正确的:只有WORD
和NEWLINE
令牌.ANTLR的词法分析器尝试使用尽可能多的字符构造标记,它不会"监听"解析器尝试匹配的内容.
错误消息:
第1行:0输入不匹配'*这是一个字符串'期待'*'
告诉你:在第1行,索引0 遇到带有text '* this is a string'
(type WORD
)的标记,但是解析器正在尝试匹配标记:'*'
尝试这样的事情:
grammar List;
parse
: NEWLINE* list* NEWLINE* EOF
;
list
: item (NEWLINE item)*
;
item
: '*' (STRING | WORD)*
;
BULLET : '*';
STRING : '"' (~[\\"] | '\\' [\\"])* '"';
WORD : ~[ \t\r\n"*]+;
NEWLINE : '\r'? '\n' | '\r';
SPACE : [ \t]+ -> skip;
Run Code Online (Sandbox Code Playgroud)
它解析您的示例输入,如下所示:
(parse
(list
(item
* this is a string) \n
(item
* "first" this is "quoted") \n
(item
* this is "quoted with \" "))
\n
<EOF>)
Run Code Online (Sandbox Code Playgroud)