WIP parsec
This commit is contained in:
parent
632b2c4a6a
commit
7df5b0eeac
3 changed files with 69 additions and 6 deletions
|
|
@ -14,7 +14,7 @@ executable lamb
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
other-modules: Parser,
|
other-modules: Parser,
|
||||||
Evaluation
|
Evaluation
|
||||||
build-depends: base
|
build-depends: base, parsec
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
|
|
@ -26,6 +26,6 @@ test-suite lamb-tests
|
||||||
ParserSpec,
|
ParserSpec,
|
||||||
Evaluation,
|
Evaluation,
|
||||||
EvaluationSpec
|
EvaluationSpec
|
||||||
build-depends: base, hspec
|
build-depends: base, hspec, parsec
|
||||||
build-tool-depends: hspec-discover:hspec-discover
|
build-tool-depends: hspec-discover:hspec-discover
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,36 @@
|
||||||
module Parser where
|
module Parser where
|
||||||
|
|
||||||
|
import Control.Monad (void)
|
||||||
|
import Text.Parsec
|
||||||
|
import Text.Parsec.String (Parser)
|
||||||
|
|
||||||
data Expr = Variable String | Abstraction (String, Expr) | Application (Expr, Expr)
|
data Expr = Variable String | Abstraction (String, Expr) | Application (Expr, Expr)
|
||||||
deriving (Eq)
|
deriving (Eq)
|
||||||
|
|
||||||
instance Show Expr where
|
instance Show Expr where
|
||||||
show (Variable name) = name
|
show (Variable name) = name
|
||||||
show (Abstraction (arg, body)) = "λ" ++ arg ++ ". " ++ show body
|
show (Abstraction (arg, body)) = "λ" ++ arg ++ ". " ++ show body
|
||||||
show (Application (f, x)) = show f ++ " " ++ show x
|
show (Application (f, x)) = "(" ++ show f ++ " " ++ show x ++ ")"
|
||||||
|
|
||||||
|
ws :: Parser ()
|
||||||
|
ws = skipMany (void space)
|
||||||
|
|
||||||
|
variable :: Parser Expr
|
||||||
|
variable = do
|
||||||
|
name <- many letter
|
||||||
|
return $ Variable name
|
||||||
|
|
||||||
|
abstraction :: Parser Expr
|
||||||
|
abstraction = do
|
||||||
|
_ <- void (char 'λ')
|
||||||
|
variable <- many letter
|
||||||
|
body <- parseExpr
|
||||||
|
return $ Abstraction (variable, body)
|
||||||
|
|
||||||
|
parseExpr :: Parser Expr
|
||||||
|
parseExpr = variable <|> abstraction
|
||||||
|
|
||||||
parse :: String -> Either String Expr
|
parse :: String -> Either String Expr
|
||||||
parse _ = Left "unimplemented"
|
parse content = case Text.Parsec.parse parseExpr "<input>" content of
|
||||||
|
Left err -> Left (show err)
|
||||||
|
Right val -> Right val
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,49 @@
|
||||||
module ParserSpec (spec) where
|
module ParserSpec (spec) where
|
||||||
|
|
||||||
import Parser (Expr (Abstraction, Variable), parse)
|
import Parser (Expr (Abstraction, Application, Variable), parse)
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
|
|
||||||
spec :: Spec
|
spec :: Spec
|
||||||
spec = do
|
spec = do
|
||||||
describe "Parser" $ do
|
describe "Parser" $ do
|
||||||
it "can parse basic expressions" $
|
it "can parse variable" $
|
||||||
|
(parse "x") `shouldBe` Right (Variable "x")
|
||||||
|
it "can parse identity abstraction" $
|
||||||
(parse "λx.x") `shouldBe` Right (Abstraction ("x", Variable "x"))
|
(parse "λx.x") `shouldBe` Right (Abstraction ("x", Variable "x"))
|
||||||
|
it "can parse mockingbird of identity" $
|
||||||
|
(parse "(λx.x x) (λx.x)") -- (λx.x) (λx.x) -> (λx.x)
|
||||||
|
`shouldBe` Right
|
||||||
|
( Application
|
||||||
|
( Abstraction
|
||||||
|
( "x",
|
||||||
|
Application
|
||||||
|
( Variable "x",
|
||||||
|
Variable "x"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Abstraction ("x", Variable "x")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
it "it can parse successor" $
|
||||||
|
(parse "λn.λf.λx.f (n f x)")
|
||||||
|
`shouldBe` Right
|
||||||
|
( Abstraction
|
||||||
|
( "n",
|
||||||
|
Abstraction
|
||||||
|
( "f",
|
||||||
|
Abstraction
|
||||||
|
( "x",
|
||||||
|
Application
|
||||||
|
( Variable "f",
|
||||||
|
Application
|
||||||
|
( Application
|
||||||
|
( Variable "n",
|
||||||
|
Variable "f"
|
||||||
|
),
|
||||||
|
Variable "x"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue