From ff7fe0a1d35616722cf4dba7ccf4d242582c726c Mon Sep 17 00:00:00 2001 From: sudoer777 Date: Thu, 7 Sep 2023 22:57:12 -0500 Subject: [PATCH] Create very basic equation parser --- README.md | 15 +++++--- app/Main.hs | 51 ++++++++++++++++++++++++++-- really-bad-compiler-in-haskell.cabal | 5 ++- 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f80b32f..55dc53d 100644 --- a/README.md +++ b/README.md @@ -6,17 +6,24 @@ Main repo: https://git.sudoer.ch/me/really-bad-compiler-in-haskell ## Build Instructions -Clone the repo. Then, use `ghcup tui` to install all of the Haskell tools. +- Clone the repo. +- Use `ghcup` to install all of the Haskell tools. +- Use `stack build` and `stack run ` to run the program. ## Credits -### Learning Resources +### Learning Resources Used - Introduction to Compiler Design class at The University of Texas at Dallas, taught by Charles Averill +- learnyouahaskell.com (for learning Haskell basics) +- https://akashagrawal.me/2017/01/19/beginners-guide-to-megaparsec.html +- https://markkarpov.com/tutorial/megaparsec.html (for help writing a Haskell equation parser) ### Tools - Language: Haskell -- Language-specific tools: GHCup, Stack, Cabal +- Haskell tools: GHCup, Stack, Cabal +- Libraries: megaparsec, parser-combinators, text - IDE: VSCodium -- Git tool: Forgejo +- Git platform: Forgejo +- AI: Phind diff --git a/app/Main.hs b/app/Main.hs index 65ae4a0..e6f83b1 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -1,4 +1,51 @@ -module Main where +module Main (main) where + +import Control.Monad.Combinators.Expr +import Data.Void (Void) +import Text.Megaparsec +import Text.Megaparsec.Char as C +import Text.Megaparsec.Char.Lexer as L + +type Parser = Parsec Void String + +data Expr + = Int Int + | Add Expr Expr + | Sub Expr Expr + | Mul Expr Expr + | Div Expr Expr + deriving (Show) + +lexemeParser :: Parser a -> Parser a +lexemeParser = L.lexeme C.space + +symbolParser :: String -> Parser String +symbolParser = L.symbol C.space + +intParser :: Parser Int +intParser = lexemeParser L.decimal + +term :: Parser Expr +term = Int <$> intParser + +table :: [[Operator Parser Expr]] +table = + [ [ binaryOp "*" Mul, + binaryOp "/" Div + ], + [ binaryOp "+" Add, + binaryOp "-" Sub + ] + ] + +binaryOp name f = InfixL (f <$ symbolParser name) + +expr :: Parser Expr +expr = makeExprParser term table + +parseExpr :: String -> Either (ParseErrorBundle String Void) Expr +parseExpr = parse (C.space *> expr <* eof) "" main :: IO () -main = putStrLn "Hello, Haskell!" +main = do + print $ parseExpr "2+3* 4" \ No newline at end of file diff --git a/really-bad-compiler-in-haskell.cabal b/really-bad-compiler-in-haskell.cabal index 76a6597..5433bd0 100644 --- a/really-bad-compiler-in-haskell.cabal +++ b/really-bad-compiler-in-haskell.cabal @@ -31,6 +31,9 @@ executable really-bad-compiler-in-haskell -- LANGUAGE extensions used by modules in this package. -- other-extensions: - build-depends: base ^>=4.16.4.0,megaparsec + build-depends: base ^>=4.16.4.0 + , megaparsec >= 9.2.2 + , parser-combinators + , text hs-source-dirs: app default-language: Haskell2010