Я имею то, что я думаю, простой вопрос ANTLR. У меня есть два типа маркера: ident
и special_ident
. Я хочу мой special_ident
соответствовать одной букве, сопровождаемой единственной цифрой. Я хочу дженерик ident
соответствовать одной букве, дополнительно сопровождаемой любым количеством букв или цифрами. Моя (неправильная) грамматика ниже:
expr
: special_ident
| ident
;
special_ident : LETTER DIGIT;
ident : LETTER (LETTER | DIGIT)*;
LETTER : 'A'..'Z';
DIGIT : '0'..'9';
Когда я пытаюсь проверить эту грамматику, я получаю это предупреждение:
Решение может соответствовать, вводит, такие как "ЦИФРА БУКВЫ", использующая несколько альтернатив: 1, 2. В результате альтернатива (альтернативы) 2 была отключена для того входа
Я понимаю, что моя грамматика неоднозначна и которые вводят такой как A1
мог соответствовать также ident
или special_ident
. Я действительно просто хочу special_ident
использоваться в самом узком из случаев.
Вот некоторый демонстрационный вход и чему я хотел бы, чтобы он соответствовал:
A : ident
A1 : special_ident
A1A : ident
A12 : ident
AA1 : ident
Как я могу сформировать свою грамматику, таким образом, что я правильно определяю свои два типа идентификаторов?
Расширение мысли Карла, я думаю, у вас есть четыре разных случая:
Только опция 2 должна быть токеном Special_ident, а остальные три должны быть идентичны. Все жетоны могут быть идентифицированы только синтаксисом. Вот быстрая грамматика, которую я смог проверить в AntlRworks, и оказалось правильно для меня работать. Я думаю, что Carl's может иметь одну ошибку при попытке проверить AA, но добивая вас 99%, есть огромное преимущество, поэтому это только незначительная модификация его быстрой мысли.
prog
: (expr WS)+ EOF;
expr
: special_ident {System.out.println("Found special_ident:" + $special_ident.text + "\n");}
| ident {System.out.println("Found ident:" + $ident.text + "\n");}
;
special_ident : LETTER DIGIT;
ident : LETTER
|LETTER DIGIT (LETTER|DIGIT)+
|LETTER LETTER (LETTER|DIGIT)*;
LETTER : 'A'..'Z';
DIGIT : '0'..'9';
WS
: (' '|'\t'|'\n'|'\r')+;
Похоже, у вас есть 3 случая:
A
AN
A (A | N) (A | N) +
вы можете классифицировать среднюю, как Special_ident
и два других, как ID
; кажется, что должен сделать трюк.
Я немного ржавый с ANTLR, я надеюсь, что этот намек достаточно. Я могу попытаться выписать выражения для вас, но они могут быть неправильными:
long_ident : LETTER (LETTER | DIGIT) (LETTER | DIGIT)+
special_ident : LETTER DIGIT;
ident : LETTER | long_ident;