ANTLR:解析速度很慢

时间:2016-04-20 10:03:01

标签: antlr4 operator-precedence

我已成功将表达式拆分为算术和布尔表达式,如下所示:

/* entry point */
parse: formula EOF;


formula : (expr|boolExpr);

/* boolean expressions : take math expr and use boolean operators on them */

boolExpr
  : bool                                            
  | l=expr operator=(GT|LT|GEQ|LEQ) r=expr          
  | l=boolExpr operator=(OR|AND) r=boolExpr         
  | l=expr (not='!')? EQUALS r=expr                 
  | l=expr BETWEEN low=expr AND high=expr           
  | l=expr IS (NOT)? NULL                           
  | l=atom LIKE regexp=string                       
  | l=atom ('IN'|'in') '(' string (',' string)* ')' 
  | '(' boolExpr ')'                                
  ;

/* arithmetic expressions */
expr
    : atom                                                 
    | (PLUS|MINUS) expr                                    
    | l=expr operator=(MULT|DIV) r=expr                    
    | l=expr operator=(PLUS|MINUS) r=expr                  
    | function=IDENTIFIER '(' (expr ( ','  expr )* ) ? ')' 
    | '(' expr ')'                                         
    ;

atom
    : number
    | variable
    | string
    ;

但现在我遇到了巨大的性能问题。我试图解析的一些公式非常缓慢,以至于它变得无法忍受:超过一个小时(我在那时停止了)来解析它:

-4.77+[V1]*-0.0071+[V1]*[V1]*0+[V2]*-0.0194+[V2]*[V2]*0+[V3]*-0.00447932+[V3]*[V3]*-0.0017+[V4]*-0.00003298+[V4]*[V4]*0.0017+[V5]*-0.0035+[V5]*[V5]*0+[V6]*-4.19793004+[V6]*[V6]*1.5962+[V7]*12.51966636+[V7]*[V7]*-5.7058+[V8]*-19.06596752+[V8]*[V8]*28.6281+[V9]*9.47136506+[V9]*[V9]*-33.0993+[V10]*0.001+[V10]*[V10]*0+[V11]*-0.15397774+[V11]*[V11]*-0.0021+[V12]*-0.027+[V12]*[V12]*0+[V13]*-2.02963068+[V13]*[V13]*0.1683+[V14]*24.6268688+[V14]*[V14]*-5.1685+[V15]*-6.17590512+[V15]*[V15]*1.2936+[V16]*2.03846688+[V16]*[V16]*-0.1427+[V17]*9.02302288+[V17]*[V17]*-1.8223+[V18]*1.7471106+[V18]*[V18]*-0.1255+[V19]*-30.00770912+[V19]*[V19]*6.7738

你对这个问题有什么看法吗?

解析器输入formula语法规则时,解析停止。

编辑此处有原始问题:

我的语法允许这样:

// ( 1 LESS_EQUALS 2 )
1 <= 2  

但是我在G4文件中表达的方式使它也接受了这个:

// ( ( 1 LESS_EQUALS 2 ) LESS_EQUALS 3 )
1 <= 2 <= 3

我不想要的。

我的语法包含这个:

expr
    : atom                                                 # atomArithmeticExpr
    | (PLUS|MINUS) expr                                    # plusMinusExpr
    | l=expr operator=('*'|'/') r=expr                     # multdivArithmeticExpr
    | l=expr operator=('+'|'-') r=expr                     # addsubtArithmeticExpr
    | l=expr operator=('>'|'<'|'>='|'<=') r=expr           # comparisonExpr
[...]

我如何告诉Antlr这是不可接受的?

1 个答案:

答案 0 :(得分:0)

将root分成两部分。重命名root&#39; expr&#39;进入&#39; rootexpr&#39;,反之亦然。

rootExpr
    : atom                                                 # atomArithmeticExpr
    | (PLUS|MINUS) expr                                    # plusMinusExpr
    | l=expr operator=('*'|'/') r=expr                     # multdivArithmeticExpr
    | l=expr operator=('+'|'-') r=expr                     # addsubtArithmeticExpr
    | l=expr operator=('>'|'<'|'>='|'<=') r=expr           # comparisonExpr

编辑:你不能有循环引用=&gt; expr规则中的expr节点。