Проблема с пробелами и литералами int / бинарными операторами - PullRequest
0 голосов
/ 06 февраля 2020

Я пытаюсь написать грамматику, которая допускает

  • целые числа со знаком (т.е. целые числа со знаком или без него; 3, -2, +5)
  • Унарный минус (-)
  • Двоичное сложение и вычитание (+, -)

Вот соответствующая грамматика:

expr: INTLITER
    | unaryOp expr
    | expr binaryOp expr
    | OPEN_PAREN expr CLOSE_PAREN
    ;

unaryOp: MINUS ;  // Other operators ommitted for clarity

binaryOp: PLUS | MINUS ;  

INTLITER: INTSIGN? DIGIT+ ;

fragment INTSIGN : PLUS | MINUS

WS: [ \r\n\t] -> skip ;  // Ignore whitespace

Я нахожу странную проблему с пробелами.

Рассмотрим выражение (2+ 1); это дает правильное дерево разбора, как и ожидалось, примерно так: The correct parse tree

Однако (2+1) дает это дерево разбора: The unexpected parse tree

Поскольку правило WS означает, что пробел игнорируется, как пробелы влияют на дерево разбора?

Как я могу решить эту проблему?

1 Ответ

2 голосов
/ 06 февраля 2020

Проблема с грамматикой заключается в том, что вы пытаетесь представить числа со знаком в виде токена в лексере. Определите INTLITER без «INTSIGN?». Грамматика теперь работает.

grammar arithmetic;

expr: INTLITER
    | unaryOp expr
    | expr binaryOp expr
    | OPEN_PAREN expr CLOSE_PAREN
    ;

unaryOp: MINUS ;  // Other operators ommitted for clarity

binaryOp: PLUS | MINUS ;  

INTLITER: DIGIT+ ;

WS: [ \r\n\t] -> skip ;  // Ignore whitespace

fragment DIGIT
   : ('0' .. '9')+
   ;

OPEN_PAREN
   : '('
   ;

CLOSE_PAREN
   : ')'
   ;

PLUS
   : '+'
   ;

MINUS
   : '-'
   ;
...