Как правильно разрешить двусмысленность правил лексера ANTLR?

См. Исходный код по адресу: https://gist.github.com/1684022 .

У меня есть два токена определено:

ID  :   ('a'..'z' | 'A'..'Z') ('0'..'9' | 'a'..'z' | 'A'..'Z' | ' ')*;

PITCH   
    :   (('A'|'a') '#'?)
    |   (('B'|'b') '#'?) 
    |   (('C'|'c') '#'?);

Очевидно, что буква «A» будет двусмысленностью.

Далее я определяю:

note    :   PITCH;
name    :   ID;
main    :   name ':' note '\n'?

Теперь, если я ввожу «A: A» в качестве входных данных для синтаксического анализатора, я всегда получаю сообщение об ошибке. синтаксический анализатор ожидает PITCH или ID в зависимости от того, какой ID или PITCH определен первым:

mismatched input 'A' expecting ID

Каков правильный способ решить эту проблему, чтобы она работала так, как задумано?


Как описано, хотя интуитивно понятно, как синтаксический анализ должен работают, ANTLR не делает «правильных вещей».То есть, даже несмотря на то, что правило main говорит, что имя / ID должно идти первым, лексер, кажется, не знает об этом и идентифицирует «A» как PITCH , потому что он следует правилу «самое длинное совпадение» / «которое идет первым», а не более разумному правилу «то, что правило говорит».

Является ли единственное решение подделать / взломать его, сопоставив ID и PITCH, а затем повторно объединив их позже, как говорит dasblinkenlight?

6
задан Ana 27 January 2012 в 01:27
поделиться