Чтобы ответить на ваш вопрос: нет, нет способа улучшить этот AFAIK.Вы можете поместить ('+' | '-')
в правило фрагмента и использовать этот фрагмент, точно так же, как фрагмент экспоненты, но я бы не назвал это реальным улучшением.
Обратите внимание, что унарные знаки +
и -
как правило, не являются частью числа-токена.Рассмотрим источник ввода "1-2"
.Вы не хотите, чтобы это было токенизировано как 2 числа: NUMBER[1]
и NUMBER[-2]
, но как NUMBER[1]
, MINUS[-]
и NUMBER[2]
, так что ваш анализатор содержит следующее:
parse
: statement+ EOF
;
statement
: assignment
;
assignment
: IDENTIFIER '=' expression
;
expression
: addition
;
addition
: multiplication (('+' | '-') multiplication)*
;
multiplication
: unary (('*' | '/') unary)*
;
unary
: '-' atom
| '+' atom
| atom
;
atom
: NUMBER
| IDENTIFIER
| '(' expression ')'
;
IDENTIFIER
: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | DIGIT)*
;
NUMBER
: DIGIT+ '.' DIGIT* EXPONENT?
| '.'? DIGIT+ EXPONENT?
;
fragment
EXPONENT
: ('e' | 'E') ('+' | '-') ? DIGIT+
;
fragment
DIGIT
: '0'..'9'
;
и addition
будут соответствовать входу "1-2"
.
РЕДАКТИРОВАТЬ
Выражение, подобное 111.222 + -456
, будет проанализировано как:
и +123 + -456
как: