Haskell - 快乐的解析器错误

Joh*_*ith 4 parsing haskell happy

我正在开发一个使用Happy parser生成器的项目.这是我到目前为止所做的事情:

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 }
Run Code Online (Sandbox Code Playgroud)

问题是我收到以下错误:

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
Run Code Online (Sandbox Code Playgroud)

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

更新:我解决了它,但现在它只有在我写"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 }
Run Code Online (Sandbox Code Playgroud)

sep*_*p2k 5

sqrt $2 p
Run Code Online (Sandbox Code Playgroud)

这将调用sqrt函数$2作为其参数,然后将结果函数应用于参数p.只有当sqrt可以接受一个函数并产生一个函数时,这才有意义,当且仅当有一个Floating函数实例时才会这样.因此错误消息.

你无疑打算做的是将函数$2应用于参数p然后应用于sqrt你要编写的结果:

sqrt ($2 p)
Run Code Online (Sandbox Code Playgroud)

  • 只是因为我们想要很多`$`,当然. (2认同)