2016-07-02 3 views
0

У меня есть следующая простая ANTLR грамматика:Простая грамматика не сумеет Разбирает

grammar Grammar; 

grammarRules : grammarRule+ ; 

grammarRule: 
    lhs '->' WORD+ 
    ; 

lhs: ID ; 

WORD : LETTER+ ; 

ID : LETTER (LETTER|'0'..'9')* ; 

fragment 
LETTER : [a-zA-Z\u0080-\u00FF_] ; 

WS : [ \t] -> skip ; 

Когда я пытаюсь разобрать строку «веб-страница -> Поиск Google», я получаю ошибку:

line 1:0 mismatched input 'webpage' expecting ID 

ответ

0

Ваша грамматика сломана. Определение WORD соответствует webpage. Это то, что возвращает лексер, поэтому парсер жалуется, что не видит ID.

Если вы попытаетесь разобрать webpage1 -> google search, он должен работать, потому что webpage1 не является WORD.

Грамматика не LL (*). С учетом, например, вход a -> b c d -> e f, синтаксический анализатор должен будет смотреть вперёд на второй ->, чтобы вернуть информацию в лексер, что приведет к признанию d как ID, а не WORD. АНТЛЕР этого не делает. (Вы, вероятно, этого не хотели бы, так как это могло бы усложнить и, следовательно, значительно замедлить лексер.)

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

+0

Хорошо, поэтому большая точка, кажется, заключается в том, что лексер работает как свой собственный слой, полностью отличный от шага парсера, поэтому лексер обременен ответственностью за выяснение, что делать в случаях двусмысленности. В этом отношении мне любопытно, почему добавление терминатора утверждения устраняет проблему двусмысленности. –

+0

@ DanielBigham Вы правы. Этого, вероятно, будет недостаточно. Вам нужно будет сделать что-то вроде 'lhs -> ID | Слово'. При этом вам, вероятно, не понадобится ограничитель строки, потому что ANTLR-парсеры LL (*). (Если бы они были только LL (1).) – Gene

+0

Для других людей, которые могут найти это позже - я вытягивал свои волосы с помощью Antlr, получая всевозможные странные поступки, а затем я кое-что прочитал о рефакторинге моей грамматики, первичная грамматика содержится с одним правилом, а не разбивается на многие правила с разными символами. Это, по-видимому, позволяет лучше лечить рекурсию грамматики. Престо, сейчас он работает хорошо. –