2017-10-10 3 views
1

私は比較的新しいコンパイラ理論です。後でそれらを評価するために、いくつかの比較を解析するための文法を作成したかっただけです。文法を指定する強力なツールであるantlrが見つかりました。私が理論で学んだことから、優先順位の高い演算子は優先順位の低い演算子よりも深いレベルで宣言する必要があることが分かりました。さらに、いくつかのルールを関連性のままにしたい場合は、ルールの左側に再帰性を設定する必要があることがわかります。使用する基本的な文法を作成したことを知って、& & ||、!=、==、<、>、< =、> =、(、)!antlr文法の定義

しかし、私は演算子の優先順位と左結合性について言及した上記の規則に従っていない文法上指定するための別の方法を発見したインターネットでの検索
start 
: orExpr 
; 

orExpr 
: orExpr OR andExpr 
| andExpr 
; 

andExpr 
: andExpr AND eqNotEqExpr 
| eqNotEqExpr 
; 

eqNotEqExpr 
: eqNotEqExpr NEQ compExpr 
| eqNotEqExpr EQ compExpr 
| compExpr 
; 

compExpr 
: compExpr LT compExpr 
| compExpr GT compExpr 
| compExpr LTEQ compExpr 
| compExpr GTEQ compExpr 
| notExpr 
; 

notExpr 
: NOT notExpr 
| parExpr 
; 

parExpr 
: OPAR orExpr CPAR 
| id 
; 

id 
: INT 
| FLOAT 
| TRUE 
| FALSE 
| ID 
| STRING 
| NULL 
; 

start 
: expr 
; 

expr 
: NOT expr        //notExpr 
| expr op=(LTEQ | GTEQ | LT | GT) expr //relationalExpr 
| expr op=(EQ | NEQ) expr    //equalityExpr 
| expr AND expr      //andExpr 
| expr OR expr       //orExpr 
| atom         //atomExpr 
; 

atom 
: OPAR expr CPAR //parExpr 
| (INT | FLOAT) //numberAtom 
| (TRUE | FALSE) //booleanAtom 
| ID    //idAtom 
| STRING   //stringAtom 
| NULL   //nullAtom 
; 

誰かが、なぜこのように説明することができます文法もうまくいきますか? antlrや別の文法定義の特定の扱いがあるからでしょうか?

以下の文法について定義された事業者とIDがあります。

OR : '||'; 
AND : '&&'; 
EQ : '=='; 
NEQ : '!='; 
GT : '>'; 
LT : '<'; 
GTEQ : '>='; 
LTEQ : '<='; 
NOT : '!'; 

OPAR : '('; 
CPAR : ')'; 

TRUE : 'true'; 
FALSE : 'false'; 
NULL : 'null'; 

ID 
: [a-zA-Z_] [a-zA-Z_0-9]* 
; 

INT 
: [0-9]+ 
; 

FLOAT 
: [0-9]+ '.' [0-9]* 
| '.' [0-9]+ 
; 

STRING 
: '"' (~["\r\n] | '""')* '"' 
; 

COMMENT 
: '//' ~[\r\n]* -> skip 
; 

SPACE 
: [ \t\r\n] -> skip 
; 

OTHER 
: . 
; 

答えて

0

これはANTLR V4に固有のものです。

フードの下で、このようなルールは、左回帰除去ステップの一部として手動で行ったものと同等のものに書き換えられます。 LL文法は左回帰規則を含むことができないので、ANTLRは便宜的にこれを行います。そのような規則をパーサーコードに直接変換すると、コード内で無限回帰(無条件に自分自身を呼び出す関数)が生成されるためです。

さらに詳しい情報と変換例がthe docs page about left-recursionにあります。