2013-08-15 3 views
1

я беру первый удар при создании грамматики для выражений, как:ANTLR для булева/условного выражения

(foo = bar or (bar = "bar" and baz = 45.43)) and test = true 

Моей грамматика до сих пор выглядит следующим образом:

grammar filter; 

tokens { 
    TRUE = 'true'; 
    FALSE = 'false'; 
    AND = 'and'; 
    OR = 'or'; 
    LT = '<'; 
    GT = '>'; 
    EQ = '='; 
    NEQ = '!='; 
    PATHSEP = '/'; 
    LBRACK = '['; 
    RBRACK = ']'; 
    LPAREN = '('; 
    RPAREN = ')'; 
} 

expression : or_expression EOF; 

or_expression : and_expression (OR or_expression)*; 

and_expression : term (AND term)*; 

term : atom (operator atom)? | LPAREN expression RPAREN; 

atom : ID | INT | FLOAT | STRING | TRUE | FALSE; 

operator : LT | GT | EQ | NEQ; 

INT : '0'..'9'+; 
FLOAT : ('0'..'9')+ '.' ('0'..'9')*; 
STRING : '"' ('a'..'z'|'A'..'Z'|'_'|' ')* '"'; 
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*; 

Но в ANTLRWorks 1.4.3, я получаю дерево разбора:

The resulting parse tree with the above input

Но для литий Я не могу понять, что не так с моей грамматикой. Какой токен здесь отсутствует?

Большое спасибо заранее.

Редактировать: Чтобы уточнить альтернативу atom, я должен, возможно, упомянуть, что атомы должны быть свободно стоящими без сравнения с другим атомом. Например. a or b является допустимым выражением.

+0

Space-символы, возможно? –

ответ

4

Я отвечаю на свой вопрос здесь. Я нашел две проблемы с моей грамматикой. Первое было легко заметить; Я поставил EOF в конце моего правления верхнего уровня:

expression : or_expression EOF; 

EOF был, таким образом, отсутствует маркер. Мое решение было удалить EOF из expression правила, и вместо того, чтобы ввести правило, над ним:

filter: expression EOF; 

Вторая проблема заключалась в том, что мое or_expression правило должно быть:

or_expression : and_expression (OR and_expression)*; 

и не

or_expression : and_expression (OR or_expression)*; 

Полная исправленная грамматика:

grammar filter; 

tokens { 
    TRUE = 'true'; 
    FALSE = 'false'; 
    AND = 'and'; 
    OR = 'or'; 
    LT = '<'; 
    GT = '>'; 
    EQ = '='; 
    NEQ = '!='; 
    PATHSEP = '/'; 
    LBRACK = '['; 
    RBRACK = ']'; 
    LPAREN = '('; 
    RPAREN = ')'; 
} 

filter: expression EOF; 

expression : or_expression; 

or_expression : and_expression (OR and_expression)*; 

and_expression : term (AND term)*; 

term : atom (operator atom)? | LPAREN expression RPAREN; 

atom : ID | INT | FLOAT | STRING | TRUE | FALSE; 

operator : LT | GT | EQ | NEQ; 

INT : '0'..'9'+; 
FLOAT : ('0'..'9')+ '.' ('0'..'9')*; 
STRING : '"' ('a'..'z'|'A'..'Z'|'_'|' ')* '"'; 
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*; 

И в результате синтаксического дерева:

The correct parse tree

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