2017-10-10 1 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 또는 다른 유형의 문법 정의의 특정 치료 때문입니까?

아래 문법에 대해 정의 된 사업자 및 IDS이 있습니다

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에 해당됩니다.

후드에서이 규칙은 왼쪽 재귀 제거 단계의 일부로 수동으로 수행 한 것과 동일한 규칙으로 다시 작성됩니다. AN 문법은 LL 문법이 왼쪽 재귀 규칙을 포함 할 수 없기 때문에 편의상 사용합니다. 이러한 규칙을 파서 코드로 직접 변환하면 코드에서 무한 재귀가 생성되므로 (무조건 자체를 호출하는 함수) ANTLR이 편리합니다.

더 많은 정보와 변환 예가 the docs page about left-recursion에 있습니다.