快乐优先级函数定义和变量

时间:2016-04-23 21:21:40

标签: parsing haskell happy

我一直在努力从今天的解析器中删除所有s / r冲突。我设法删除所有这些但只有一个。

我的语言的语法应该像haskell一样。而不是main,我有一个顶级表达式,即条目。

解析器如下所示。我还添加了Happy生成的Parser.info文件的摘录,其中描述了转换/减少冲突。

据我所知,问题是一旦解析器遇到函数定义的varname,就可以使用两个分支。它可以假设有更多varname s因为它当前正在解析函数定义(具有一个或多个参数),或者它可以停止将其解析为变量表达式。之后可能的varname就是另一个表达式。

我玩过%prec规则并没有什么帮助。

我的第一个推理是,鉴于解析器想要转换为函数定义,我可以优先使用该规则。我还尝试向=运算符添加优先级(用于函数定义),这样我就可以将它放在函数定义的优先级之下,但这也不起作用。我的猜测是我不完全理解解析器的工作原理。任何指针都非常感谢。

一个小小的注意事项,默认行为 - 我认为这是一种转变 - 也是所希望的行为。

state 25 contains 1 shift/reduce conflicts.

...

State 25

    Definition -> varname . ':' ':' Type                (rule 7)
    Definition -> varname . FunctionParameters '=' Exp bl    (rule 8)
    Atom -> varname .                                   (rule 20)

    '('            reduce using rule 20
    '<'            reduce using rule 20
    '>'            reduce using rule 20
    '/'            reduce using rule 20
    '*'            reduce using rule 20
    '-'            reduce using rule 20
    '+'            reduce using rule 20
    "eq?"          reduce using rule 20
    number         reduce using rule 20
    ':'            shift, and enter state 27
    varname        shift, and enter state 28
            (reduce using rule 20)

    %eof           reduce using rule 20

    FunctionParametersgoto state 26

分析器

%nonassoc PARS
%nonassoc VAR
%%
Program
 : Definitions Exp { Program $1 $2 }
 | Exp             { Program [] $1 }


Definitions
 : Definitions Definition { ($1 ++ [$2]) }
 | Definition             { [$1]         }


Definition
 : type upsym '=' Type                   { TypeDef $2 $4  }
 | varname ':' ':' Type                  { FTypeDef $1 $4 }
 | varname FunctionParameters '=' Exp bl { FDef $1 $2 $4  }


FunctionParameters
 : FunctionParameters varname %prec PARS { $1 ++ [$2] }
 | varname                    { [$1]    }



Exp
 : let varname '=' Exp "in" Exp { Let $2 $4 $6  }
 | if Exp then Exp else Exp     { If $2 $4 $6   }
 | "Lam" varname "->" Exp       { Abs $2 $4     }
 | Form                         { $1            }


Form
 : Juxt { $1 }


Juxt
 : Juxt Atom { App $1 $2 }
 | Atom      { $1        }


Atom
 : '(' Exp ')'         { $2                }
 | number              { Value $ Number $1 }
 | varname %prec VAR   { Var $1            }
 | Binfs               { Value $ Binf $1   }


Binfs
 : "eq?"    { BinfEqual }
 | '/'      { BinfDiv   }
 | '*'      { BinfTimes }
 | '+'      { BinfPlus  }
 | '-'      { BinfMinus }
 | '>'      { BinfGT    }
 | '<'      { BinfLT    }

0 个答案:

没有答案