diff --git a/haskell-experiments/haskell-experiments.cabal b/haskell-experiments/haskell-experiments.cabal index 52e827b..48a3e43 100644 --- a/haskell-experiments/haskell-experiments.cabal +++ b/haskell-experiments/haskell-experiments.cabal @@ -77,7 +77,7 @@ test-suite haskell-exps-test main-is: Main.hs -- Test dependencies. - build-depends: base, hspec, langfeatures + build-depends: base, hspec, langfeatures, megaparsec other-modules: Test.OlogsSpec, Test.SimpleParserSpec diff --git a/haskell-experiments/src/SimpleParser.hs b/haskell-experiments/src/SimpleParser.hs index 037e7c3..7e5f920 100644 --- a/haskell-experiments/src/SimpleParser.hs +++ b/haskell-experiments/src/SimpleParser.hs @@ -16,23 +16,24 @@ {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} module SimpleParser - ( eval, Expr (..), BinaryOp (..), UnaryOp (..) ) -- literalParser + ( eval, Expr (..), BinaryOp (..), UnaryOp (..), parseExpr ) -- literalParser where import Text.Megaparsec import Data.Void (Void) -import Text.Megaparsec.Byte.Lexer (decimal) -import Control.Concurrent (yield) +import Text.Megaparsec.Char.Lexer (decimal) +import Text.Megaparsec.Char (char) type Parser = Parsec Void String -data BinaryOp = Add | Subtract | Multiply | Divide +data BinaryOp = Add | Subtract | Multiply | Divide deriving (Show, Eq) -data UnaryOp = Negate +data UnaryOp = Negate deriving (Show, Eq) data Expr = BinaryExpr BinaryOp Expr Expr | UnaryExpr UnaryOp Expr | Literal Int + deriving (Show, Eq) lookUpBinaryOp :: BinaryOp -> Int -> Int -> Int lookUpBinaryOp Add = (+) @@ -48,22 +49,29 @@ eval (Literal n) = n eval (BinaryExpr binOp a b) = lookUpBinaryOp binOp (eval a) (eval b) eval (UnaryExpr unaryOp a) = lookUpUnaryOp unaryOp (eval a) - --- parseExpr :: Parser Expr --- parseExpr = choice [ --- literalParser, --- expressionParser --- -- bracketedExpParser, --- -- negatedExp --- ] +parseExpr :: Parser Expr +parseExpr = choice [ + try parseBinaryExpr, + parseLiteral + -- bracketedExpParser, + -- negatedExp + ] --- literalParser :: Parser Expr --- literalParser = Literal <$> decimal +parseLiteral :: Parser Expr +parseLiteral = Literal <$> decimal --- expressionParser :: Parser Expr --- expressionParser = do --- parseExpr --- parseOp --- parseExpr +parseBinaryExpr :: Parser Expr +parseBinaryExpr = do + lhs <- parseLiteral <|> parseExpr + binOp <- parseOp + rhs <- parseLiteral <|> parseExpr + pure (BinaryExpr binOp lhs rhs) + +parseOp :: Parser BinaryOp +parseOp = choice [ + char '+' >> pure Add, + char '-' >> pure Subtract, + char '/' >> pure Divide, + char '*' >> pure Multiply + ] --- parseOp :: Parser Expr \ No newline at end of file diff --git a/haskell-experiments/test/Test/SimpleParserSpec.hs b/haskell-experiments/test/Test/SimpleParserSpec.hs index fdac99f..c3e4fe1 100644 --- a/haskell-experiments/test/Test/SimpleParserSpec.hs +++ b/haskell-experiments/test/Test/SimpleParserSpec.hs @@ -11,7 +11,7 @@ module Test.SimpleParserSpec where import Test.Hspec - +import Text.Megaparsec import SimpleParser spec :: Spec @@ -28,6 +28,8 @@ spec = do (UnaryExpr Negate (Literal 1)) (BinaryExpr Divide (Literal 7) (Literal 3)) ) `shouldBe` 1 - + it "can parse basic expressions" $ do + parse parseExpr "" "2" `shouldBe` Right (Literal 2) + parse parseExpr "" "2+3" `shouldBe` Right (BinaryExpr Add (Literal 2) (Literal 3)) diff --git a/untitled/.gitignore b/untitled/.gitignore deleted file mode 100644 index f68d109..0000000 --- a/untitled/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -### IntelliJ IDEA ### -out/ -!**/src/main/**/out/ -!**/src/test/**/out/ - -### Eclipse ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ - -### VS Code ### -.vscode/ - -### Mac OS ### -.DS_Store \ No newline at end of file