11

我是 Haskell 的新手,我正在尝试解析表达式。我发现了 Parsec,也发现了一些文章,但我似乎不明白我必须做什么。我的问题是我想给出一个像 "x^2+2*x+3" 这样的表达式,结果是一个接受参数 x 并返回值的函数。如果这是一个简单的问题,我很抱歉,但我真的需要一些帮助。谢谢!我插入的代码来自您可以在此链接上找到的文章。

import Control.Monad(liftM)
import Text.ParserCombinators.Parsec 
import Text.ParserCombinators.Parsec.Expr  
import Text.ParserCombinators.Parsec.Token  
import Text.ParserCombinators.Parsec.Language  

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

expr :: Parser Expr
expr = buildExpressionParser table factor
    <?> "expression"

table = [[op "^" Pow AssocRight],
         [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"
4

1 回答 1

12

这只是带有变量的表达式的解析器。实际上解释表达式是完全不同的事情。

您应该创建一个函数,该函数采用已解析的表达式和变量值,并返回计算表达式的结果。伪代码:

evaluate :: Expr -> Map String Int -> Int
evaluate (Num n) _ = n
evaluate (Var x) vars = {- Look up the value of x in vars -}
evaluate (Plus e f) vars = {- Evaluate e and f, and return their sum -}
...

我故意省略了一些细节;希望通过探索缺失的部分,您可以了解更多有关 Haskell 的信息。

作为下一步,您可能应该查看Readermonad 以寻找一种方便的方法来传递变量映射vars,并使用MaybeorError来指示错误,例如引用未绑定到的变量vars,或除以零。

于 2011-01-17T11:36:12.673 回答