parsing simple expressions

This commit is contained in:
Felix Dilke 2026-01-14 16:50:59 +00:00
parent 81feb1aee3
commit 763cae02b7
4 changed files with 34 additions and 53 deletions

View File

@ -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

View File

@ -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 [
try parseBinaryExpr,
parseLiteral
-- bracketedExpParser,
-- negatedExp
]
-- parseExpr :: Parser Expr
-- parseExpr = choice [
-- literalParser,
-- expressionParser
-- -- bracketedExpParser,
-- -- negatedExp
-- ]
parseLiteral :: Parser Expr
parseLiteral = Literal <$> decimal
-- literalParser :: Parser Expr
-- literalParser = Literal <$> decimal
parseBinaryExpr :: Parser Expr
parseBinaryExpr = do
lhs <- parseLiteral <|> parseExpr
binOp <- parseOp
rhs <- parseLiteral <|> parseExpr
pure (BinaryExpr binOp lhs rhs)
-- expressionParser :: Parser Expr
-- expressionParser = do
-- parseExpr
-- parseOp
-- parseExpr
parseOp :: Parser BinaryOp
parseOp = choice [
char '+' >> pure Add,
char '-' >> pure Subtract,
char '/' >> pure Divide,
char '*' >> pure Multiply
]
-- parseOp :: Parser Expr

View File

@ -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))

29
untitled/.gitignore vendored
View File

@ -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