这是我试图制作的 AST:
{{ name }}
{{ name | option }}
{{ name | option1 | option2 }}
{{ name | key=value }}
{{ name | option1 | key=value }}
{{ name | option1 | {{ another }} | option3 }}
所以在实践中总是有一个名称(a..zA..Z0..9),选项有时采用键值格式,有时采用简单且没有值的格式。
我正在尝试通过 ANTLR 为它编写一个词法分析器/解析器语法,但它一直在唠叨不同的东西。这是我最好的镜头:
start : box+;
box : '{{' Name ('|' Options )* '}}';
Options : (SimpleOption | KeyValue | box);
Name : ID;
SimpleOption: ID;
KeyValue: ID '=' ID;
fragment
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* ;
WS : ( ' ' | '\t' | '\r' | '\n' {$channel=HIDDEN;} ;
这显然是错误的,因为 Name 和 SimpleOption 是模棱两可的。即使是内联规则也没有用:
box : '{{' Name ('|' (ID | KeyValue | box) )* '}}';
因为它从不拾取 KeyValue 并在遇到 '=' 时给出不匹配异常。
你会怎么写这个语法?