首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Jison: if-else和for语句ara组合时的语法冲突

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

Stack Overflow用户
提问于 2014-09-25 05:31:18
回答 1查看 229关注 0票数 0

我想用jison为JavaScript语言的一个子集做一个解析器,但我有一些问题。

一开始,我对非终端stmt有这样的定义,它是有效的:

代码语言:javascript
复制
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中添加了以下规则

代码语言:javascript
复制
    : IF LPAREN expr RPAREN stmt
        {$$ = ['if ('].concat($3, [') '], $5)}
    | IF LPAREN expr RPAREN stmt ELSE stmt
        {$$ = ['if ('].concat($3, [') '], $5, [0, 'else '], $7)}

这种语法是模棱两可的,并且出现了冲突。因此,我遵循以下模式来解决悬而未决的else歧义:

代码语言:javascript
复制
stmt
    : IF LPAREN expr RPAREN stmt
    | IF LPAREN expr RPAREN stmt ELSE stmt
    | other_stmt
    ;

必须转换为: stmt : closed_stmt | non_closed_stmt;

代码语言:javascript
复制
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
    ;

这是我当前语法的一部分:

代码语言:javascript
复制
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

EN

回答 1

Stack Overflow用户

发布于 2014-09-25 13:25:29

您需要闭合和非闭合形式的for语句;它不能仅以stmt结尾。因此,在closed_stmt规则中放入以closed_stmt结尾的封闭形式,在non_closed_stmt规则中放入以non_closed_stmt结尾的非封闭形式。

那是因为

代码语言:javascript
复制
for (x=0;x<3;++x) if (x==2) do_something();

就像非闭合的

代码语言:javascript
复制
if (x==2) do_something();

在某种意义上,它将吸收下面的else令牌。在if语句前面加上一个(或多个) for头不会改变该语句的封闭性。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26026881

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档