我正在为Haskell中的lambda演算编写一个简单的解析器/解释器。
我正在使用语法" /(x.x)"对于lambda函数," x"为了一个名字和" f y"申请时," /(x.x)y"是对y的应用,应该返回y。
我的策略是为名称,lambda函数和应用程序提供解析器。名称和函数解析器可以工作,但不适用于应用程序解析器。
当我尝试解析" /(x.x)y"它失败。它应该尝试将源解析为名称,作为lambda函数,并且在不能同时使用它们之后(因为它不会解析所有源代码)尝试将其解析为应用程序然后成功。
我的代码是:
module Main where
import Text.ParserCombinators.Parsec
data Expression =
Var String
| Lambda Expression Expression
| Application Expression Expression
deriving Eq
instance Show Expression where
show (Var v) = v
show (Lambda v e) = "/(" ++ show v ++ "." ++ show e ++ ")"
show (Application e1 e2) = "" ++ show e1 ++ " " ++ show e2 ++ ""
-- Parser
parseSource :: String -> Expression
parseSource source =
case parse (parseExpression <* eof) "" source of
Right e -> e
_ -> error "Parsing error"
parseExpression :: Parser Expression
parseExpression =
parseVar <|> parseLambda <|> parseApplication
parseVar :: Parser Expression
parseVar = Var <$> many1 letter
parseLambda :: Parser Expression
parseLambda = do
_ <- char '/'
_ <- char '('
arg <- parseVar
_ <- char '.'
body <- parseExpression
_ <- char ')'
return $ Lambda arg body
parseApplication :: Parser Expression
parseApplication = do
e1 <- parseExpression
_ <- spaces
e2 <- parseExpression
return $ Application e1 e2