0

私は次の文法を持っています

grammar Expr;   

prog: expr;

expr: LP expr RP
| expr LP expr RP
| LP expr RP expr
| expr '*' '{' ',' expr 
| expr op=NOT expr
| expr op=AND expr
| expr op=OR expr
| ID
;

NEWLINE:'\r'? '\n' ; 

NOT: '~';    
AND: '&';
OR: '|';

LP : '(';
RP : ')';

// lexer/terminal rules start with an upper case letter
ID
  :
    (
    'a'..'z'
    | 'A'..'Z'
    | '0'..'9' | ' '
    | ('+'|'-'|'*'|'/'|'_')
  | '='
  | '~'
  | '{'
  | '}'
  | ','
  )+ 
  ;

WS : [ \t\n]+ -> skip ;

評価される式のノードを抽出し、評価される順序で必要とします。したがって、1*{A42,A53,A16,A3}&(A26|A41)&(A51=P&A2=F|A7=C) のような式の場合、次の順序で評価されます。

A26 | A41 
A51 & A2=F
A51 & A2F | AF=C
1*{A42,A53,A16,A3}&(A26|A41)
1*{A42,A53,A16,A3}&(A26|A41)&(A51=P&A2=F|A7=C)

主な関心事は、式が評価される順序を理解することです。

これについてどう思いますか。訪問者の実装を書いてみましたが、注文を抽出する方法がわかりません。

4

1 に答える 1

0

「expr」ルールを再帰するたびに、Antlr は新しいコンテキスト オブジェクトを生成します。コンテキストの順序によって、必要な情報が提供されます。ID に null 以外の TerminalNode を含む各コンテキストは、評価の成功を表します。したがって、最も単純なケースでは、解析ツリーをたどり、「enterEveryRule」で ID を監視します。'enterEveryRule' と 'exitEveryRule' では、有効な接続記号と未使用の接続記号を区別するために、成功間の最高の変曲点 (昇順から降順への切り替え、またはその逆) を監視します。

FWIW、最初の 3 つのルール alt はあいまいです。4 番目の alt は期待どおりに動作しない可能性が高く、5-7 を組み合わせて分析を簡素化できます。

于 2013-04-06T18:42:36.903 に答える