Вот что я пытаюсь сделать AST этого:ANTLR для необязательного ключевого значения
{{ 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;} ;
Это, очевидно, неправильно, потому что имя и SimpleOption неоднозначны. Даже инлайн правило бесполезно:
box : '{{' Name ('|' (ID | KeyValue | box))* '}}';
Потому что он никогда не выбирает KeyValue и дает несовпадение исключение на встрече с «=».
Как вы напишете эту грамматику?
'name' не должно быть неоднозначным потому что идентификатор всегда будет сведен к этому, если это первый токен после '{{', и никогда иначе. Полученный ответ выглядит как двусмысленность для меня. – Lucero