I am trying to learn how can I do a parser for expressions in Haskell and I found this code (below), but I don't even know how to use it.

I tried with: expr (Add (Num 5) (Num 2)) , but it needs a "Parser" data type.

import Text.Parsec
import Text.Parsec.String
import Text.Parsec.Expr
import Text.Parsec.Token
import Text.Parsec.Language

data Expr = Num Int | Var String | Add Expr Expr | Sub Expr Expr | Mul Expr Expr | Div Expr Expr deriving Show

expr :: Parser Expr
expr = buildExpressionParser table factor
  <?> "expression"
table = [[op "*" Mul AssocLeft, op "/" Div AssocLeft],
      [op "+" Add AssocLeft, op "-" Sub AssocLeft]]
      where
        op s f assoc = Infix (do{ string s; return f}) assoc
factor = do{ char '('
        ; x <- expr
        ; char ')'
        ; return x}
    <|> number
    <|> variable
    <?> "simple expression"
number :: Parser Expr
number = do{ ds<- many1 digit
      ; return (Num (read ds))}
  <?> "number"
variable :: Parser Expr
variable = do{ ds<- many1 letter
        ; return (Var ds)}
  <?> "variable"

Solution: readExpr input = parse expr "name for error messages" input and use readExpr.

有帮助吗?

解决方案

You can use the function parse which will run a Parser on an input string and return an Either ParseError Expr. I put a simple usage below where I turn that ParseError into a string and pass it along

readExpr :: String -> Either String Expr
readExpr input = case parse expr "name for error messages" input of
   Left err -> Left $ "Oh noes parsers are failing: " ++ show err -- Handle error
   Right a  -> Right a -- Handle success

There are a few other functions, such as parseFromFile, which let you shorthand a few common patterns, to find them, check out the parsec haddock

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top