【问题标题】:Ambiguous grammar and possible fixes模棱两可的语法和可能的修复
【发布时间】:2016-03-24 21:52:14
【问题描述】:

所以我有这种语言的语法,语法肯定包含一些歧义,但是我发现修复它有点异常困难。下面是该语言的 BNF 语法,下面是我快乐的解析器文件的那部分。

建议语言的 BNF:

<program> ::=                                   Skel program
      "program" <id> ":" <pars> "."

--> <pars> ::=
      <par> [";" <pars>]                        parallel statements

<par> ::=
    "func" <id> <structs>                       structured expression
--> |   <pars> "||" <pars>                          parallel pipeline
|   "farm" <int> <pars>                         task farm

--> <structs> ::=
    <struct> [";" <structs>]                    statements

<struct> ::=
      <exprs>                                   expression
--> |     <structs> "•" <structs>                   composition
|     "iter" <int> <structs>                    iteration

--> <exprs> ::=
      <expr> ["," <exprs>]                      expressions

<expr> ::=
    <int>                                       integer value
    |  <string>                                 string value
    |  <bool>                                   boolean value
    |  <id> [ "=" <exprs> ]                     identifier/assignment
    |  "raise" <id> "=" <exprs>                 raise exception
    |  <exprs> "catch" <id> <id> ":" <exprs>    catch exception
    |  <exprs> <op> <exprs>                     binary operator
    |  "(" <exprs> ")"                          grouping

<op> ::=                        operators
    "+" | "*" | "-" | "div"| "<"| "<=" | "==" | "!="

Parser.y

TProgram: program ID ':' TPars '.'    { Program $2 $4 }

TPars   : TPar ';'                    {   [$1]  }
        | TPars TPar                  { $2 : $1 }

TPar    : func ID TStructs            { Function $2 $3   }
      --| "||" TPars                  { Parall $2        }
        | farm DIGIT TPars            { Farm $2 $3       }

TStructs: TStruct ';'                 {  [$1]  }
        | TStructs TStruct            { $2 : $1 }

TStruct : TExprs                      { ExprList $1   }
      --| '•' TStructs                { CompOp $2     }
        | iter DIGIT TStructs         { Iter $2 $3    }

TExprs  : TExpr                       {   [$1]    }
        | TExprs ',' TExpr            {  $3 : $1  }

BinExpr : Term                        {  $1  }
        | BinExpr Op BinExpr          { BinOp $2 $1 $3  }

Op      : '/'                         { Divide }
        | '*'                         { Times  }
        | '-'                         { Minus  }
        | '+'                         { Plus   }

Term    : ID                          { Var $1 }
        | DIGIT                       { Digit $1 }
        | FLOAT                       { Float $1 }

TExpr   : '(' TExprs ')'              { ParenExpr $2 }
        | true                        { Bool $1  }
        | false                       { Bool $1  }
        | ID '=' TExprs               { Assign $1 $3  }
        | raise ID '=' TExprs         { Raise $2 $4   }
        | BinExpr                     {  $1  }

编辑:我在 BNF 格式中添加了箭头,显示我认为导致语法歧义的原因。

【问题讨论】:

  • 这是一个谜题吗?你为什么不向我们展示模棱两可的地方?但是我相信a = b, c 可以解析为(a=b), ca = (b,c)
  • @Ingo 这不是一个谜题,我会标记我现在所指的内容。

标签: parsing haskell bison yacc happy


【解决方案1】:

那么,你想要什么

a = true, false

得到解析?可能是

(a=true), false

a = (true, false)

如果这是 yacc,我建议通过使用 %right %left%nonassoc 编译指示赋予 '=' 和 ',' 关联性和优先级来解决冲突,也许 Happy 支持这样的东西。

【讨论】:

  • 我明白你的意思,从未想过你提到的这一点(专注于其他序列,如ParsStructs 的序列),是的,Happy 确实支持像你这样的编译指示我提到过。感谢您的帮助。
  • @ymg 据我所知,parsstructs 也有类似的问题,基本上你有一个事物列表,但是一个事物可以以另一个事物列表结尾,所以它外部列表是否应该结束以及应该结束的位置从来都不是很清楚。
  • 谢谢,你帮了大忙!在您的发言之后,我注意到了一些事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多