2016-04-20 4 views
0

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

どのように私はこれが受け入れられないことをANTLRを伝えることができますか?

答えて

0

ルートを2つに分割します。 root '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 

EDIT:exprルールで循環参照=> exprノードを使用することはできません。

+0

え?しかし、 'expr'を定義するのは何ですか? – Gui13

+0

あなたが持っていた質問は、Antlrに伝える方法でした、それは受け入れられません。だから、私はあなたに、唯一の演算子式を許可したいのであれば、循環参照を使わないように言っています。もちろん、文法全体ではなく、その点だけです。 exprルールは別個のルールとして定義することもできますし、適用される場合は 'atom'ルールを使用することもできます。 – Divisadero

関連する問題