2010-05-03 1 views
1

У меня есть следующие правила лексера в моем файле грамматики:mismatchedtoken с Antlr синтаксическими предикатами

LINE : 'F' | 'G'; 
RULE : (('->' ('F' | 'G')) => 'F' | 'G') 
       | LINE LINE + | LINE * (ROTATE + LINE+)+ ; 
fragment ROTATE : ('/' | '\\'); 

Я в основном пытаюсь соответствовать постановки, которые выглядят как F -> F/F \ F \ F/F. Он успешно сопоставляет такие вещи, как выше, но я предполагаю, что есть проблема с моим синтаксическим предикатом, так как G -> G создает исключение MismatchedTokenException. Предикат служит для устранения неоднозначности между отдельными буквами на lhs из «->», который я хочу распознать как токен LINE, а также те из них, которые должны быть ПРАВИЛАМИ.

Любая идея, что я делаю неправильно?

+0

не должен быть ЛИНИЯ фрагмент слишком? –

+0

@ Аnders: Нет, другие части моей грамматики нуждаются в этом, чтобы быть токеном. – varzan

ответ

1

Обратите внимание, что правило:

RULE 
    : (('->' ('F' | 'G')) => 'F' | 'G') 
    | LINE LINE + 
    | LINE * (ROTATE + LINE+)+ 
    ; 

соответствует одиночному G без предиката. Правило выше, можно переписать так:

RULE 
    : (('->' ('F' | 'G')) => 'F' 
    | 'G' 
    ) 
    | LINE LINE + 
    | LINE * (ROTATE + LINE+)+ 
    ; 

, который в свою очередь равен:

RULE 
    : ('->' ('F' | 'G')) => 'F' 
    | 'G' 
    | LINE LINE + 
    | LINE * (ROTATE + LINE+)+ 
    ; 

Возможно, вы имели в виду сделать что-то вроде этого:

RULE 
    : ('->' ('F' | 'G')) => ('F' | 'G') 
    | LINE LINE + 
    | LINE * (ROTATE + LINE+)+ 
    ; 
+0

Вы правы со скобками, но это не помогло. Я переработал грамматику, сопоставляя «G» или «F» с маркером LINE и оставляя последние две альтернативы для RULE, а затем определяя правило для парсера для производств как LINE '->' RULE или LINE '->' LINE. – varzan

+0

Хорошо. Приятно слышать, как вы это решили! –