ANTLR:解析非常慢



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

/* 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
[...]

我怎么能告诉安特尔这是不可接受的?

只需将根分成两部分。将根"expr"重命名为"rootexpr",反之亦然。

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

编辑:您不能在 expr 规则中使用循环引用 => expr 节点。

相关内容

  • 没有找到相关文章

最新更新