Haskell - Happy解析器错误

4

我正在开发一个使用Happy解析器生成器的项目。目前为止,我的工作如下:

Exp   : Exp1                    { $1 }

Exp1  : Exp1 '+' Term           { \p -> $1 p + $3 p }
      | Exp1 '-' Term           { \p -> $1 p - $3 p }
      | Term                    { $1 }

Term  : Term '*' Factor         { \p -> $1 p * $3 p }
      | Term '/' Factor         { \p -> $1 p / $3 p }
      | sqrt Factor             { \p -> sqrt $2 p }
      | Factor                  { $1 }

Factor                    
      : double                  { \p -> $1 }
      | '(' Exp ')'             { $2 }

问题是我遇到了以下错误:

Parser.hs:158:38:
No instance for (Floating ([a0] -> Double))
  arising from a use of `happyReduction_7'
Possible fix:
  add an instance declaration for (Floating ([a0] -> Double))
In the second argument of `happySpecReduce_2', namely
  `happyReduction_7'
In the expression: happySpecReduce_2 6 happyReduction_7
In an equation for `happyReduce_7':
    happyReduce_7 = happySpecReduce_2 6 happyReduction_7

你知道我该怎么解决这个问题吗?

更新:我已经解决了,但是现在只有当我写成“sqrt2”(sqrt和2之间没有空格)时它才起作用;如果我写成“sqrt 2”,我会得到“解析错误”。

以下是我在Alex(lex)文件中的内容:

       tokens :-

       $white+         ;
       "--".*          ;
       "sqrt"                   { \s -> TokenSqrt}
       "sin"                    { \s -> TokenSin}
       "log"                    { \s -> TokenLog}
       @doubleNumber            { \s -> TokenDouble (read s) }
       @var                     { \s -> TokenVar s }
       "+"                      { \s -> TokenPlus }
       "-"                      { \s -> TokenMinus }
       "*"                      { \s -> TokenMul }
       "/"                      { \s -> TokenDiv }
       "("                      { \s -> TokenOB }
       ")"                      { \s -> TokenCB }
       "="                      { \s -> TokenEq }
1个回答

5
sqrt $2 p

这段代码调用了sqrt方法并以$2作为其参数,然后将生成的函数应用于参数p。如果sqrt可以接受函数并产生函数作为结果,则会有一个Floating实例来处理函数,但事实上并没有这样的实例,因此会出现错误消息。
你想要做的是先将函数$2应用于参数p,然后再将sqrt应用于结果,代码如下:
sqrt ($2 p)

1
我们可以写sqrt $ $2 p,不是吗? - muhmuhten
1
其实,我对 happy 没有头绪,但是出于好奇,写成 { sqrt . $2 } 而不是 { \p -> sqrt ($2 p) } 是否有效呢? - muhmuhten
谢谢!还有一个问题:这只在我写“sqrt2”时有效,例如(sqrt和2之间没有空格);如果我写“sqrt 2”,我会得到“解析错误”。你知道为什么吗? - John Smith
@JohnSmith:这听起来像是你的分词器/词法分析器出了问题。 - hammar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接