-
12-09-2019 - |
質問
私は(ネストされた括弧やものを扱う)文法を扱う表現を実装しようとしています。私はこれまでのところ、以下の持っている、しかし、彼らは(成功/失敗例は、以下のコードブロックの後に表示されます)いくつかのケースを扱うことができません。誰もが何が起こっているのか知っていますか?
注:のVARNAME + = と VARNAME = のものXTEXTでちょうどいくつかの追加のAST生成ヘルパーのものです。今はそれらについて心配しないでください。
...
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
解決
何が起こっているのは、あなたの表現/式は、単一の括弧ではなく、(あなたが締結される)複数の括弧をサポートしていることです。私はANTLR特定の経験を持っていないが、私は多くの類似概念を共有したJavaCCで働いてきた(私は聞いていない...プロローグのための文法を書いた)。
ネストされた括弧を処理するために、あなたは典型的には類似した何かを持っています:
ParenthesisExpression: '(' (ParenthesisExpression | Expression) ')';
この式は括弧に包まれているいずれか、またはそれだけで生の発現だことを意味します。これでどのようにASTのお得な情報については、ParenthesisExpressionは式「です」ので、(式は、種類のインタフェース/抽象クラスである場合)には、サブクラスまたはの実装として表すことができます。
他のヒント
に置か^
を利用しての の後にトークン/ルール名は、式を定義するために非常に便利です。
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;
私は単純な式のために、この文法を使用しました: のhttp://fisheye2.atlassian .COM /閲覧/〜生、R = 5175 / ANTLR-例/ C / polydiff / Poly.g の
私は、より複雑な式のために、このプロジェクトに含まれている文法をも使用しました: http://www.codeproject.com/KB/recipes/sota_expression_evaluator.aspx