2009-09-21 3 views
3

Я пытаюсь реализовать грамматику обработки выражений (которая касается вложенных скобок и т. Д.). У меня есть следующие до сих пор, но они не могут иметь дело с некоторыми случаями (успешные/неудачные случаи появляются после следующего блока кода). Кто-нибудь знает, что происходит?ANTLR Грамматика для выражений

Примечание: VarName + = и VarName = вещи являются лишь некоторые дополнительные поколения AST вспомогательный материал в XText. Не волнуйся о них пока.

... 

NilExpression returns Expression: 
    'nil'; 

FalseExpression returns Expression: 
    'false'; 

TrueExpression returns Expression: 
    'true'; 

NumberExpression returns Expression: 
    value=Number; 

StringExpression returns Expression: 
    value=STRING; //EllipsesExpression: '...'; 
//FunctionExpression: function=function; //don't allow random functions 


UnaryExpression: 
    op=unop ('(' expr=Expression ')')|expr=Expression; 

BinaryExpression: 
    'or'? AndOp; //or op 

AndOp: 
    'and'? ComparisonOp; 

ComparisonOp: 
    ('>'|'<'|'>='|'<='|'=='|'~=')? ConcatOp; 

ConcatOp: 
    '..'? AddSubOp; 

AddSubOp: 
    ('+' '-')? MultDivOp; 

MultDivOp: 
    ('*' '/')? ExpOp; 

ExpOp: 
    '^'? (('(' expr=Expression ')')|expr=Expression); 

ExprSideOne : Variable|NilExpression|FalseExpression|TrueExpression| 
    NumberExpression|StringExpression|UnaryExpression; 

Expression: 
    ( 
    '(' 
    expression1=ExprSideOne expression2+=BinaryExpression* 
    ')' 
) 
    | 
    (expression1=ExprSideOne expression2+=BinaryExpression*) 
; 
... 

А вот список разборов/не удается:

c = ((b)); //fails 
c = ((a not b)); //fails 
c = b; //parses 
d = (b); //parses 
+0

Нужна рекурсия. Просто из любопытства, почему ваши правила двоичного оператора написаны как унарные операторы? Является ли nil> = .. + * (1) что-то значимым? –

ответ

4

Что происходит в том, что ваше выражение/выражения поддерживают одиночные скобки, но не несколько круглых скобок (как вы пришли к выводу). У меня нет специфического опыта ANTLR, но я работал с Javacc, который разделяет много подобных концепций (я написал грамматику для Prolog ... не спрашиваю).

Для обработки вложенных скобок, то, как правило, есть что-то подобное:

ParenthesisExpression: '(' (ParenthesisExpression | Expression) ')'; 

Это означало бы, что выражение либо завернуто в скобках или это просто сырое выражение. Что касается того, как AST справляется с этим, ParenthesisExpression является выражением, поэтому его можно представить в виде подкласса или реализации (если выражение является классом интерфейса/абстрактного класса).

+0

В дополнение, вам, возможно, придется иметь дело и с этим делом: ((a) not (b или (c))), поэтому удовольствие заключается в том, чтобы ваше выражение также могло вернуться к ParenthesisExpression. – Malaxeur

+0

Разве это не заставит внешнюю()? Вокруг (ParenthesisExpression | Expression) у вас есть пара (...) s. – jameszhao00

+0

Извините, я имел в виду «('') 'вокруг вашей вещи, а не() :) – jameszhao00

1

Я использовал эту грамматику для простых выражений: http://fisheye2.atlassian.com/browse/~raw,r=5175/antlr-examples/C/polydiff/Poly.g

Я также использовал грамматику содержат в этом проекте для более сложных выражений: http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx

+0

Ссылка fisheye2 теперь мертва. – lycono

1

Сделать использование ^помещается после имя маркера/правила очень полезно для определения выражений.

expression : e1 (OR^ e1)* ; 
    e1 : e2 (AND^ e2)*; 
    e2 : e3 (PIPE^ e3)*; 
    e3 : e4 (ANDSYMB^ e4)*; 
    e4 : e5 ((EQUAL^|NOTEQUAL^) e5)*; 
    e5 : e6 ((LESS^|GREATER^) e6)*; 
    e6 : e7 ((PLUS^|MINUS^) e7)* ; 
    e7 : e8 ((STAR^|SLASH^) e8)* ; 
    e8 : e9 (NEW^ ID LPAREN RPAREN)*; 
    e9 : (NOT^)? e10; 
    e10 : e11 | call_def; 
    e11 : constant 
     | '(' expression ')' -> expression; 
+0

Что указывает каретка^после правила? Обновление: я вижу, что другой SOF, похоже, объясняет это http://stackoverflow.com/questions/11365781/caret-prefix-instead-of-postfix-in-antlr – javadba

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