Есть ли способ улучшить эту грамматику ANTLR 3 для положительных и отрицательных целых и десятичных чисел? - PullRequest
0 голосов
/ 16 мая 2011

Есть ли способ выразить это менее повторяющимся образом с необязательными положительными и отрицательными знаками?

То, что я пытаюсь сделать, - это как выразить, при желании, положительные + (по умолчанию) и отрицательные - знаки на числовых литералах, которые могут иметь показатели степени или десятичные части.

NUMBER : ('+'|'-')? DIGIT+ '.' DIGIT* EXPONENT?
       | ('+'|'-')? '.'? DIGIT+ EXPONENT?
       ;

fragment 
EXPONENT : ('e' | 'E') ('+' | '-') ? DIGIT+ 
         ;

fragment
DIGIT  : '0'..'9' 
       ;

Я хочу иметь возможность распознавать NUMBER паттерны, и я не так обеспокоен арифметикой этих чисел в тот момент, я буду позже, но я пытаюсь понять, как распознать любой NUMBER литералы где числа выглядят так:

123
+123
-123
0.123
+.123
-.123
123.456
+123.456
-123.456
123.456e789
+123.456e789
-123.456e789 

и любые другие стандартные форматы, которые я не собирался включать сюда.

1 Ответ

3 голосов
/ 16 мая 2011

Чтобы ответить на ваш вопрос: нет, нет способа улучшить этот 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, будет проанализировано как:

enter image description here

и +123 + -456 как:

enter image description here

...