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 的非空 TerminalNode 的上下文都将表示评估成功。因此,在最简单的情况下,遍历解析树并在“enterEveryRule”中查看 ID。在“enterEveryRule”和“exitEveryRule”中观察成功之间的最高拐点(升序切换到降序,反之亦然),以区分有效和未使用的连词符号。

FWIW,您的前三个规则替代是模棱两可的,第四个不太可能达到您的预期,并且可以组合 5-7 以简化您的分析。

于 2013-04-06T18:42:36.903 回答