2016-09-23 4 views
1

Мне необходимо написать логический синтаксический анализатор/оценщик. выражение будет иметь вид и будет заключено в круглых скобках:Antlr - синтаксический анализатор выражений и оценщик

exp1 : (A = B) 
exp2 : ((A = B) AND (C = D)) 
exp3 : ((A = B) AND ((C = D) OR (E = F))) 
exp4: (((A = B) AND (C = D)) OR (E = F)) 

и это продолжается. Правило может содержать «n» количество выражений с соответствующей группировкой 2 в каждой группе. Мой файл грамматики выглядит следующим образом:

/* 
Expression grammar 
*/ 

grammar Exparser; 

options 

{ 
    language = Java; 
} 
cond : 
tc EOF; 

tc: 
     exp 
    | binary_exp 
| leftparen* exp (binaryop leftparen* exp rightparen+)* 
| leftparen* exp (binaryop leftparen* exp rightparen*)* 

; 

binary_exp: 
'(' exp BINARYOP exp ')' 
; 

binaryop: 
      BINARYOP 
     ; 
leftparen: 
      LEFTPARN 
     ; 

rightparen: 
       RIGHTPARN 
      ; 

exp: 
LEFTPARN VARIABLE COMPOP VARIABLE RIGHTPARN 

; 

variable: 
      VARIABLE; 


BINARYOP: AND | OR; 
COMPOP: EQUAL | LT | GT | LTE | GTE | NE; 
VARIABLE: (CHAR)+; 
LEFTPARN: '('; 
RIGHTPARN: ')'; 
EQUAL: '=' | 'EQ'; 
LT: '<' | 'LT'; 

GT:'>' | 'GT'; 
LTE: '<='; 
GTE: '>='; 
NE : '!=' | 'NE'; 
AND: 'AND' | '&' | 'and'; 

OR: 'OR' | 'or'; 

CHAR : 'a'..'z'|'A'..'Z'|'_' |'0'..'9'|'-' | '.' 
    ; 

эта грамматика работает отлично, но я не в состоянии достичь глубины в AST. например, exp3 анализируется как три exp, а не один exp и один binary_exp. Также как я могу вычислять логическое выражение, используя мой парсер? Как моя грамматика обеспечивает балансировку круглых скобок? Хотя Nested Boolean Expression Parser using ANTLR дать некоторую идею для оценки выражения, я не могу применить в своем случае

ответ

1

парсер генерируется из следующей грамматики разбирает весь ваш пример ввода:

grammar Exparser; 

parse 
: expr EOF 
; 

expr 
: expr binop expr 
| VARIABLE 
| '(' expr ')' 
; 

binop 
: AND | OR | EQUAL | LT | GT | LTE | GTE | NE 
; 

EQUAL  : '=' | 'EQ'; 
LT  : '<' | 'LT'; 
GT  : '>' | 'GT'; 
LTE  : '<='; 
GTE  : '>='; 
NE  : '!=' | 'NE'; 
AND  : 'AND' | '&' | 'and'; 
OR  : 'OR' | 'or'; 
VARIABLE : [a-zA-Z0-9_.-]+; 
SPACE  : [ \t\r\n] -> skip; 

оценивающих эти выражения должны быть такими же, как the Q&A you linked to in your question.

+0

Спасибо, Барт. Я мог бы получить свою структуру дерева, когда я запускал это на antlrworks 2. Мне еще предстоит работать над частью оценки. – ssdimmanuel

+0

Грамматика работала как шарм. Я сделал простые изменения в соответствии с моими потребностями. Для меня выражения в моих приложениях довольно статичны после определения. Я думал написать дерево разбора на диск, но обнаружил, что это невозможно, поскольку классы не являются Serializable. Есть ли другой проверенный метод для этого? – ssdimmanuel

+0

Я еще не изучал сериализацию/сохранение классов ANTLR 4. –

0

Предостережение: Я не знаю antlr. Однако, я думаю, вам нужно сделать вашу грамматику более явной. Вы слишком много перегружаете exp. Попробуйте что-то вроде этого псевдокода:

tc <- binary_exp ; 
binary_exp <- comparison_exp 
      | LEFTPARN binary_exp RIGHTPARN 
      | LEFTPARN binary_exp BINARYOP binary_exp RIGHTPARN ; 
comparison_exp <- LEFTPARN VARIABLE COMPOP VARIABLE RIGHTPARN ; 
  • Каждый tc является двоичным выражением binary_exp.
  • Бинарное выражение является одним из:
    • выражения сравнения comparison_exp,
    • двоичного выражения в круглых скобках (LEFTPARN и RIGHTPARN),
    • или последовательность левого скобкой LEFTPARN, A binary_exp, двоичный оператор BINARYOP, a binary_exp и правая скобка RIGHTPARN.
  • выражение сравнения представляет собой последовательность левой скобкой LEFTPARN, переменная VARIABLE, оператор сравнения COMPOP, A VARIABLE, и правая скобка RIGHTPARN.

Эта грамматика позволяет вставлять двоичные выражения внутри дополнительных скобок или вставлять друг в друга, но выражения сравнения не могут содержать в себе другие выражения.

Смежные вопросы