Javascript Jison:if-else和for语句组合时的语法冲突

Javascript Jison:if-else和for语句组合时的语法冲突,javascript,parsing,if-statement,for-loop,jison,Javascript,Parsing,If Statement,For Loop,Jison,我想用jison为JavaScript语言的一个子集创建一个解析器,但我遇到了一些问题 起初,我对非终结符stmt有这样的定义,它可以工作: stmt : FOR LPAREN varlist_decl SEMICOLON expr SEMICOLON expr RPAREN stmt {$$ = ['for ('].concat($3, ['; '], $5, ['; '], $7, [') '], $9)} | varlist_decl {$

我想用jison为JavaScript语言的一个子集创建一个解析器,但我遇到了一些问题

起初,我对非终结符
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, '}'])}
    ;
之后,我在
stmt
中添加了以下规则:

    : IF LPAREN expr RPAREN stmt
        {$$ = ['if ('].concat($3, [') '], $5)}
    | IF LPAREN expr RPAREN stmt ELSE stmt
        {$$ = ['if ('].concat($3, [') '], $5, [0, 'else '], $7)}
此语法不明确,出现冲突。所以我遵循这些模式来解决悬而未决的歧义:

stmt
    : IF LPAREN expr RPAREN stmt
    | IF LPAREN expr RPAREN stmt ELSE stmt
    | other_stmt
    ;
它必须转化为: 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)}
    ;
这一部分仅在我对语句规则进行注释时有效

你怎么修理它


这是我的完整代码存储库:

对于语句,您需要封闭和非封闭形式的
;它不能仅以
stmt
结束。因此,您在
closed\u stmt
规则中放置了一个以
closed\u stmt
结尾的封闭表单,在
non\u closed\u stmt
规则中放置了一个以
non\u closed\u stmt
结尾的非封闭表单

那是因为

for (x=0;x<3;++x) if (x==2) do_something();
在某种意义上,它将吸收以下
else
标记。如果在
语句前面加上一个(或多个)
for
标题,则不会改变
if
语句的关闭度

if (x==2) do_something();