2014-09-24 8 views
0

jison을 사용하여 JavaScript 언어의 하위 집합에 대한 파서를 만들고 싶습니다. 몇 가지 문제가 있습니다.Jison : if-else 및 for 문을 결합했을 때 문법에 충돌이 있습니다.

은 첫째 나는 비단 stmt이 정의를했고, 그것을 작동 : 나는 stmt에 다음과 같은 규칙을 추가,

stmt 
    : FOR LPAREN varlist_decl SEMICOLON expr SEMICOLON expr RPAREN stmt 
     {$$ = ['for ('].concat($3, ['; '], $5, ['; '], $7, [') '], $9)} 
    | varlist_decl 
     {$$ = $1} 
    | expr 
     {$$ = $1} 
    | LBRACE stmts RBRACE 
     {$$ = ['{', 0, 1].concat($2, [0, -1, '}'])} 
    ; 

후 :

: IF LPAREN expr RPAREN stmt 
     {$$ = ['if ('].concat($3, [') '], $5)} 
    | IF LPAREN expr RPAREN stmt ELSE stmt 
     {$$ = ['if ('].concat($3, [') '], $5, [0, 'else '], $7)} 

이 문법이 모호하며 충돌이 나타납니다. | 을 closed_stmt : STMT : 그것은으로 변환해야

stmt 
    : IF LPAREN expr RPAREN stmt 
    | IF LPAREN expr RPAREN stmt ELSE stmt 
    | other_stmt 
    ; 

: 그래서 매달려 다른 모호성을 해결하기 위해 이러한 패턴을 따라 non_closed_stmt ;

closed_stmt 
    : IF LPAREN expr RPAREN closed_stmt ELSE closed_stmt 
    | other_stmt 
    ; 

non_closed_stmt 
    : IF LPAREN expr RPAREN stmt 
    | IF LPAREN expr RPAREN closed_stmt ELSE non_closed_stmt 
    ; 

이 내 문법의 현재의 일부입니다

stmt 
    : closed_stmt 
     {$$ = $1} 
    | non_closed_stmt 
     {$$ = $1} 
    ; 

closed_stmt 
    : IF LPAREN expr RPAREN closed_stmt ELSE closed_stmt 
     {$$ = ['if ('].concat($3, [') '], $5, [0, 'else '], $7)} 
    | FOR LPAREN varlist_decl SEMICOLON expr SEMICOLON expr RPAREN stmt 
     {$$ = ['for ('].concat($3, ['; '], $5, ['; '], $7, [') '], $9)} 
    | varlist_decl 
     {$$ = $1} 
    | expr 
     {$$ = $1} 
    | LBRACE stmts RBRACE 
     {$$ = ['{', 0, 1].concat($2, [0, -1, '}'])} 
    ; 

non_closed_stmt 
    : IF LPAREN expr RPAREN stmt 
     {$$ = ['if ('].concat($3, [') '], $5)} 
    | IF LPAREN expr RPAREN closed_stmt ELSE non_closed_stmt 
     {$$ = ['if ('].concat($3, [') '], $5, [0, 'else '], $7)} 
    ; 

와 나는 for-statement 규칙을 언급 할 때이 부분에서만 작동합니다.

어떻게 수정합니까? 여기

내 전체 코드 저장소입니다 : 당신은 for 문을 폐쇄 및 비 폐쇄 형태를 필요 https://github.com/xgbuils/if-for-grammar-issue

답변

1

; 그것은 단지 stmt으로 끝날 수 없습니다. 따라서 closed_stmt으로 끝나는 닫힌 양식은 closed_stmt 규칙에 넣고 non_closed_stmt으로 끝나는 닫히지 않은 양식은 non_closed_stmt 규칙에 넣습니다.

for (x=0;x<3;++x) if (x==2) do_something(); 

그것이 다음 else 토큰을 흡수한다는 의미에서

if (x==2) do_something(); 

으로 비는 폐쇄 것처럼 때문에입니다

. if 문은 하나의 (또는 그 이상) for 헤더를 사용하여 문을 닫음으로써 문이 닫히지 않습니다.