質問

私は(ネストされた括弧やものを扱う)文法を扱う表現を実装しようとしています。私はこれまでのところ、以下の持っている、しかし、彼らは(成功/失敗例は、以下のコードブロックの後に表示されます)いくつかのケースを扱うことができません。誰もが何が起こっているのか知っていますか?

注:の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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top