【问题标题】:Shift reduce conflicts in happy grammarShift减少快乐语法中的冲突
【发布时间】:2012-05-28 21:35:34
【问题描述】:

你好优秀的程序员,

我已经在快乐(haskell)中建立了以下语法:

P  :  program  C             {Prog $2}


E  :  int            {Num $1}
   |  ident           {Id $1}
   |  true           {BoolConst True}
   |  false          {BoolConst False}
   |  read           {ReadInput}
   |  '(' E ')'              {Parens $2}
   |  E '+' E                { Add $1 $3 }
   |  E '-' E                { Sub $1 $3 }
   |  E '*' E                { Mult $1 $3 }
   |  E '/' E                { Div $1 $3 }
   |  E '=' E                { Eq $1 $3 }
   |  E '>' E                { Gt $1 $3 }
   |  E '<' E                { Lt $1 $3 }


C  :   '(' C ')'             {$2}
   |  ident assign E         {Assign $1 $3}
   |  if E then C else C     {Cond $2 $4 $6}  
   |  output E               {OutputComm $2}
   |  while E do C           {While $2 $4 }
   |  begin D ';' C end      {Declare $2 $4}
   |  C ';' C                {Seq $1 $3 }


D  :  D ';' D                {DSeq $1 $3 } 
   |  '(' D ')'              {$2}
   |  var ident assign E     {Var $2 $4} 

现在,While 循环包含了“do”之后的所有命令。如何改变这种行为?我已经尝试过 %left, %right... :(

【问题讨论】:

    标签: haskell grammar yacc happy


    【解决方案1】:

    发明两种C,一种允许排序,另一种不允许。可能是这样的:

    Cnoseq : '(' Cseq ')'
           | ident assign E
           | while E do Cnoseq
    
    Cseq : Cnoseq ';' Cseq
         | Cnoseq
    

    【讨论】:

    • 这是唯一的解决方案吗?需要对代码进行重大更改:(
    • @user1422467 它应该只需要在解析器中进行更改——使用解析树的代码应该能够保持不变。
    【解决方案2】:

    考虑这个代码片段:

    while True do output 1 ; output 2
    

    这可以被解析为任一

    (while True do output 1) ; (output 2)
    

    while True do (output 1 ; output 2)
    

    这种歧义是冲突的根源。

    如果您不想按照@DanielWagner 的建议更改语法,可以使用precedence rules 来解决歧义。具体如何取决于优先级应该是什么,但可能是这样的:

    %right do
    %right then else
    %right ';'
    

    优先级从低到高列出,因此在这种情况下,上面的示例将以后一种方式解析。只需在标记下方、%% 行之前添加优先规则即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多