سؤال

أحاول تنفيذ قواعد تعبير التعبير (يتعامل مع الأقواس المتداخلة والأشياء). لدي ما يلي حتى الآن، لكن لا يمكن أن يتعامل مع بعض الحالات (تظهر حالات / حالات الفشل الناجحة بعد كتلة التعليمات البرمجية التالية). هل يعلم احدكم ماذا يحدث؟

لاحظ ال varname + = و varname = الاشياء هي مجرد بعض الاشياء مساعد جيل AST في extext. لا تقلق بشأنهم الآن.

...

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* )
;
...

وهنا قائمة PSESSE / فشل:

c = ((b)); //fails
c = ((a not b)); //fails
c = b; //parses
d = (b); //parses
هل كانت مفيدة؟

المحلول

ما يحدث هو أن تعبيرك / تعبيراتك تدعم قوسين واحدا ولكن ليس قوادا متعددة (كما انتهت صلما). ليس لدي تجربة محددة من Antlr لكنني عملت مع Javacc التي تشترك في العديد من المفاهيم المماثلة (كتبت قواعد اللغة للورقات ... لا تسأل).

للتعامل مع الأقواس المتداخلة، عادة ما يكون لديك شيء مشابه ل:

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

هذا يعني أن التعبير إما ملفوفا بين قوسين أو مجرد تعبير خام. بالنسبة لكيفية صفقات AST مع هذا، فإن Parenthesexpression "هو تعبير"، لذلك يمكن تمثيله كدفعة فرعية أو تنفيذ (إذا كان التعبير فئة واجهة / مجردة من الأنواع).

نصائح أخرى

الاستفادة من ^ وضع بعد اسم الرمز / القاعدة مفيد للغاية لتحديد التعبيرات.

    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/browse/~RAWR=5175/ANTLR-EXAMPLES/C/Polydiff/Poly.g.

لقد استخدمت أيضا القواعد تحتوي على هذا المشروع للتعبيرات الأكثر تعقيدا:http://www.codeProject.com/kb/recipes/sota_expression_evaluator.aspx.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top