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

标签 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 
        {$$ = $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)}

该语法有二义性并且出现冲突。所以我遵循这些模式来解决悬空的 else 歧义:

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

它必须转换为: 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)}
    ;

这部分仅在我注释 for-statement 规则时才起作用。

如何解决这个问题?

这是我的完整代码存储库:https://github.com/xgbuils/if-for-grammar-issue

最佳答案

您需要 for 语句的封闭式和非封闭式;它不能只是以 stmt 结尾。因此,您可以在 lined_stmt 规则中放置一个以 lined_stmt 结尾的封闭形式,并在 non_angled_stmt 规则中放置一个以 non_angled_stmt 结尾的非封闭形式。 规则。

那是因为

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

与非闭合一样

if (x==2) do_something();

从某种意义上说,它将吸收后面的else标记。 if 语句的封闭性不会因在其前面添加一个(或多个)for header 而改变。

关于javascript - Jison:if-else 和 for 语句 ara 组合时的语法冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26026881/

相关文章:

php - 在 Laravel 5.4 中使用 if 条件获取图像

javascript - 如何在 jquery 中制作背景幻灯片?

javascript - 使用 Javascript 编写解析器的教程

javascript - React-Native:我们可以直接使用 JavaScript 的 'debounce' 函数还是 _lodash 的 debounce 是唯一的选择?

javascript - 插件在 WordPress 4.5 更新后抛出 TypeError

javascript - 需要 Date.parse 以外的方法来解析日期字符串

string - 以Scala方式从同一行读取多个输入

java - Stax vs Sax vs DOM 解析器?

c++ - if 命名空间内的语句给出错误

javascript - If语句在javascript中只检查一次变量值