Eouti писал:
Я добавил разделение. Но я хотел бы уведомить пользователя, если он попытается разделить на 0.
Внутри вашего правила multExpr
вы не должны делать if (e != 0) ...
, но вместо этого вы должны получить доступ к атрибуту e
value
. Кроме того, левая сторона вашего выражения называется e
, а правая часть также называется e
. Вам лучше дать им уникальные имена:
multExpr returns [int value]
: e1=atom {$value = $e1.value;}
( '*' e2=atom {$value *= $e2.value;}
| '/' e2=atom {if ($e2.value != 0) $value /= $e2.value;
else System.err.println("Division par 0 !");}
)*
;
Но вы действительно хотите предупредить пользователя? После этого предупреждения расчет просто продолжится в данный момент. ИМО, тебе нужно просто выбросить исключение.
Eouti писал:
Я хотел бы добавить пау в моем анализаторе (с более высоким приоритетом, чем умножение и деление.
Затем добавьте правило powExpr
между multExpr
и atom
и позвольте multExpr
использовать это правило powExpr
вместо правила atom
:
multExpr returns [int value]
: e1=powExpr {...}
( '*' e2=powExpr {...}
| '/' e2=powExpr {...}
)*
;
powExpr returns [int value]
: atom {...}
('^' atom {...}
)*
;
atom returns [int value]
: INT {...}
| ID {...}
| '(' expr ')' {...}
;
(powExpr
буквально не обязательно находиться между этими правилами ...)
Кроме того, вы можете изменить returns [int value]
на returns [double value]
, особенно если вы используете деление.