ANTLR: проблема различения унарных и бинарных операторов (например, знак минус)

я использую ANTLR (3.2) для разбора довольно простой грамматики. К сожалению, столкнулся с небольшой проблемой. Возьмите следующее правило:

exp
 : NUM
 | '(' expression OPERATOR expression ')' -> expression+
 | '(' (MINUS | '!') expression ')' -> expression
 ;

ОПЕРАТОР содержит тот же знак минус ('-'), что и МИНУС. Теперь ANTLR, похоже, не может справиться с этими двумя правилами. Если я удаляю любой из них, все работает нормально.

Есть идеи?


person Christian    schedule 25.10.2010    source источник


Ответы (1)


Сделайте унарное выражение с наивысшим приоритетом. Я бы также использовал другой токен для унарного -, чтобы лучше различать минус. Демо:

grammar Exp;

options { 
  output=AST;
}

tokens {
  UNARY;
}

parse
  :  exp EOF
  ;

exp
  :  additionExp
  ;

additionExp
  :  multiplyExp ('+'^ multiplyExp | '-'^ multiplyExp)*
  ;

multiplyExp
  :  unaryExp ('*'^ unaryExp | '/'^ unaryExp)* 
  ;

unaryExp
  :  '-' atom -> ^(UNARY atom)
  |  '!' atom -> ^('!' atom)
  |  atom
  ;

atom
  :  '(' exp ')' -> exp
  |  Number      -> Number
  ;

Number : ('0'..'9')+ ('.' ('0'..'9')+)? ;

Spaces : (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;} ;

Быстрый тест с источником:

3 * -4 + 7 / 6 * -(3 + -7 * (4 + !2))

произвел следующий AST:

альтернативный текст

person Bart Kiers    schedule 26.10.2010
comment
И как токенизатор должен знать при чтении минуса, соответствует ли он УНАРНОМУ? - person Gastón Bengolea; 20.05.2014
comment
@GastónBengolea, токенизатор - нет. Парсер заменяет токен '-' на токен UNARY. - person Bart Kiers; 20.05.2014
comment
@Cope, вот пример с ANTLR4: stackoverflow.com/questions/15610183/ - person Bart Kiers; 23.08.2015
comment
Спасибо, это было полезно. Итак, это с 2010 года. Удивительно, что эти технологии парсеров не сильно меняются. - person yoshi; 15.06.2017