Как мой лексический анализатор ANTLR может соответствовать маркеру, сделанному из символов, которые являются подмножеством другого вида маркера?

Я имею то, что я думаю, простой вопрос 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

Как я могу сформировать свою грамматику, таким образом, что я правильно определяю свои два типа идентификаторов?

5
задан Chris Farmer 31 January 2010 в 21:39
поделиться

2 ответа

Расширение мысли Карла, я думаю, у вас есть четыре разных случая:

  1. A
  2. AA (A | N) *
  3. AN (A | N ) +

Только опция 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')+;
2
ответ дан 14 December 2019 в 19:12
поделиться

Похоже, у вас есть 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;
3
ответ дан 14 December 2019 в 19:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: