首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >解决yacc/ocamlyacc中的reduce/reduce冲突

解决yacc/ocamlyacc中的reduce/reduce冲突
EN

Stack Overflow用户
提问于 2008-08-23 19:18:48
回答 2查看 8.3K关注 0票数 10

我正在尝试解析ocamlyacc中的语法(与常规yacc几乎相同),它支持无运算符的函数应用程序(如Ocaml或Haskell),以及二元运算符和一元运算符的普通分类。我得到了一个与'-‘运算符的reduce/reduce冲突,它既可以用于减法,也可以用于否定。下面是我使用的语法示例:

代码语言:javascript
复制
%token <int> INT
%token <string> ID
%token MINUS

%start expr
%type <expr> expr

%nonassoc INT ID
%left MINUS
%left APPLY

%%

expr: INT
    { ExprInt $1 }
| ID
    { ExprId $1 }
| expr MINUS expr
    { ExprSub($1, $3) }
| MINUS expr
    { ExprNeg $2 }
| expr expr %prec APPLY
    { ExprApply($1, $2) };

问题是,当你得到一个像"a - b“这样的表达式时,解析器不知道这应该被简化为"a (-b)”( b的否定,后面跟着应用)还是"a - b“(减法)。减法归约是正确的。我如何解决冲突,使之有利于该规则?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2008-08-23 20:49:00

不幸的是,我能想到的唯一答案就是增加了语法的复杂性。

在APPLY expr_with_prefix

  • allow 中,
  1. expr拆分为simple_exprsimple_expr(expr_with_prefix)

第一步是将reduce/reduce冲突转换为shift/reduce冲突,但括号可以解决这一问题。

你用'a,b,c‘也会遇到同样的问题:是a(b(c))还是(a(b))(c)?你还需要在语法中去掉applied_expression和必需的(applied_expression)

我想这样就行了,但我不确定:

代码语言:javascript
复制
expr := INT
      | parenthesized_expr
      | expr MINUS expr

parenthesized_expr := ( expr )
                    | ( applied_expr )
                    | ( expr_with_prefix )

applied_expr := expr expr

expr_with_prefix := MINUS expr
票数 8
EN

Stack Overflow用户

发布于 2011-10-07 02:06:54

这个最简单的答案就是忽略它,让默认的reduce/reduce解析来处理它-- reduce是在语法中最先出现的规则。在这种情况下,这意味着优先减少expr MINUS expr而不是MINUS expr,这正是您想要的。在看到a-b之后,您希望将其解析为二进制减号,而不是一元减号,然后再解析为apply。

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

https://stackoverflow.com/questions/24516

复制
相关文章

相似问题

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