2017-10-10 121 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 
; 

有人可以解釋爲什麼這樣definig的語法也適用?是否因爲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。

在這種情況下,像這樣的規則將被重寫爲與左手遞歸消除步驟的一部分手動完成的操作相同的操作。 ANTLR這樣做是爲了方便,因爲LL語法不能包含左遞歸規則,因爲直接將這樣的規則轉換爲解析器代碼會在代碼中產生無限遞歸(一種非規則地調用自身的函數)。

the docs page about left-recursion有更多信息和轉換示例。