使用转义字符解析引用的字符串

Vis*_*hnu 4 antlr4

我在解析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输入不匹配'*这是一个字符串'期待'*'

Bar*_*ers 5

问题是你的词法分析员太贪心了.规则

WORD : (~'\n')+;
Run Code Online (Sandbox Code Playgroud)

匹配几乎一切.这会导致词法分析器为您的输入生成以下标记:

  • 令牌1: ()WORD* this is a string
  • 令牌2: NEWLINE
  • 令牌3 : WORD(`*"first"this is"quoted")
  • 令牌4: NEWLINE
  • 令牌5: ()WORD* this is "quoted with \" "

是的,这是正确的:只有WORDNEWLINE令牌.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)