Parsec:在2014年获得buildexpressionParser示例到typecheck

Mic*_*Fox 2 haskell parsec

以下是http://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-Expr.html的示例:

expr    = buildExpressionParser table term
        <?> "expression"

term    =  parens expr 
        <|> natural
        <?> "simple expression"

table   = [ [prefix "-" negate, prefix "+" id ]
        , [postfix "++" (+1)]
        , [binary "*" (*) AssocLeft, binary "/" (div) AssocLeft ]
        , [binary "+" (+) AssocLeft, binary "-" (-)   AssocLeft ]
        ]

binary  name fun assoc = Infix (do{ reservedOp name; return fun }) assoc
prefix  name fun       = Prefix (do{ reservedOp name; return fun })
postfix name fun       = Postfix (do{ reservedOp name; return fun })
Run Code Online (Sandbox Code Playgroud)

似乎你需要一些导入才能开始:

import Text.Parsec
import Text.Parsec.Expr
import Text.Parsec.Token
Run Code Online (Sandbox Code Playgroud)

现在它几乎没有在每一行都进行过类似的检查.

有谁知道如何修理它?

更新

错误看起来像这样:

Couldn't match expected type ‘ParsecT s u m a0’
            with actual type ‘String -> ParsecT s9 u9 m9 ()’
Relevant bindings include
  name :: GenTokenParser s9 u9 m9 (bound at Eval2.hs:28:9)
  postfix :: GenTokenParser s9 u9 m9 -> (a -> a) -> Operator s u m a
    (bound at Eval2.hs:28:1)
Probable cause: ‘reservedOp’ is applied to too few arguments
In a stmt of a 'do' block: reservedOp name
In the first argument of ‘Postfix’, namely
  ‘(do { reservedOp name;
         return fun })’
Run Code Online (Sandbox Code Playgroud)

让我对这种类型感到好奇 reservedOp

? :t reservedOp
reservedOp
  :: GenTokenParser s u m
     -> String -> Text.Parsec.Prim.ParsecT s u m ()
Run Code Online (Sandbox Code Playgroud)

所以在这里查看文档http://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-Token.html:

reservedOp :: String -> ParsecT s u m ()
Run Code Online (Sandbox Code Playgroud)

奥利?那是什么GenTokenParser s u m,我怎么得到一个?

纯娱乐

看看这种类型.它可能意味着什么?

? :t TokenParser
TokenParser
:: Text.Parsec.Prim.ParsecT s u m String
 -> (String -> Text.Parsec.Prim.ParsecT s u m ())
 -> Text.Parsec.Prim.ParsecT s u m String
 -> (String -> Text.Parsec.Prim.ParsecT s u m ())
 -> Text.Parsec.Prim.ParsecT s u m Char
 -> Text.Parsec.Prim.ParsecT s u m String
 -> Text.Parsec.Prim.ParsecT s u m Integer
 -> Text.Parsec.Prim.ParsecT s u m Integer
 -> Text.Parsec.Prim.ParsecT s u m Double
 -> Text.Parsec.Prim.ParsecT s u m (Either Integer Double)
 -> Text.Parsec.Prim.ParsecT s u m Integer
 -> Text.Parsec.Prim.ParsecT s u m Integer
 -> Text.Parsec.Prim.ParsecT s u m Integer
 -> (String -> Text.Parsec.Prim.ParsecT s u m String)
 -> (forall a.
     Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m a)
 -> Text.Parsec.Prim.ParsecT s u m ()
 -> (forall a.
     Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m a)
 -> (forall a.
     Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m a)
 -> (forall a.
     Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m a)
 -> (forall a.
     Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m a)
 -> (forall a.
     Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m a)
 -> Text.Parsec.Prim.ParsecT s u m String
 -> Text.Parsec.Prim.ParsecT s u m String
 -> Text.Parsec.Prim.ParsecT s u m String
 -> Text.Parsec.Prim.ParsecT s u m String
 -> (forall a.
     Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m [a])
 -> (forall a.
     Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m [a])
 -> (forall a.
     Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m [a])
 -> (forall a.
     Text.Parsec.Prim.ParsecT s u m a
     -> Text.Parsec.Prim.ParsecT s u m [a])
 -> GenTokenParser s u m
Run Code Online (Sandbox Code Playgroud)

Mic*_*Fox 6

谢谢@Christian Conkle和@bheklilr这里http://hackage.haskell.org/package/parsec-3.1.7/docs/Text-Parsec-Token.html#v:makeTokenParser

这是2014年版本的buildExpressionParser示例,应该在Parsec文档而不是那里.

import Text.Parsec
import Text.Parsec.Expr
import Text.Parsec.Token
import Text.Parsec.Language (javaStyle)

lexer = makeTokenParser javaStyle

expr    = buildExpressionParser table term
        <?> "expression"

term    =  parens lexer expr 
        <|> natural lexer
        <?> "simple expression"

table   = [ [prefix "-" negate, prefix "+" id ]
        , [postfix "++" (+1)]
        , [binary "*" (*) AssocLeft, binary "/" (div) AssocLeft ]
        , [binary "+" (+) AssocLeft, binary "-" (-)   AssocLeft ]
        ]

binary  name fun assoc = Infix (do{ reservedOp lexer name; return fun }) assoc
prefix  name fun       = Prefix (do{ reservedOp lexer name; return fun })
postfix name fun       = Postfix (do{ reservedOp lexer name; return fun })
Run Code Online (Sandbox Code Playgroud)


Chr*_*kle 3

数据构造函数GenTokenParser具有所有这些参数,因为它是具有大量字段的类型的构造函数。

制作 a 的方法TokenParser确实是 with makeTokenParser。它的类型表明它返回一个GenTokenParser; TokenParser只是一个受限类型的同义词。TokenParser st与 完全相同GenTokenParser String st Identity

正如文档所建议的,您可以向其传递预制语言定义,例如haskellDef. 您也可以手动构造一个LanguageDef,这并不太复杂;询问您是否需要详细说明。中间立场是使用记录修改语法来修改预定义之一:makeTokenParser (haskellDef { commentStart = "<<", commentEnd = ">>" })