use makeExprParser for parsing
This commit is contained in:
parent
cc3ed6a35d
commit
e437fd82c4
@ -82,7 +82,7 @@ test-suite haskell-exps-test
|
||||
Test.SimpleParserSpec
|
||||
|
||||
library langfeatures
|
||||
build-depends: base, containers, megaparsec
|
||||
build-depends: base, containers, megaparsec, parser-combinators
|
||||
hs-source-dirs: src
|
||||
exposed-modules: Ologs, SimpleParser
|
||||
ghc-options: -Wall
|
||||
|
||||
@ -15,13 +15,16 @@
|
||||
{-# LANGUAGE NoMonomorphismRestriction #-}
|
||||
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
|
||||
|
||||
module SimpleParser
|
||||
( eval, Expr (..), BinaryOp (..), UnaryOp (..), parseExpr ) -- literalParser
|
||||
module SimpleParser (eval, Expr (..), BinaryOp (..), UnaryOp (..), parseExpr) -- literalParser
|
||||
where
|
||||
import Text.Megaparsec
|
||||
|
||||
import Control.Monad.Combinators.Expr
|
||||
import Data.Functor (($>))
|
||||
import Data.Void (Void)
|
||||
import Text.Megaparsec
|
||||
import Text.Megaparsec.Byte.Lexer (lexeme)
|
||||
import Text.Megaparsec.Char (char, space)
|
||||
import Text.Megaparsec.Char.Lexer (decimal)
|
||||
import Text.Megaparsec.Char (char)
|
||||
|
||||
type Parser = Parsec Void String
|
||||
|
||||
@ -29,10 +32,10 @@ data BinaryOp = Add | Subtract | Multiply | Divide deriving (Show, Eq)
|
||||
|
||||
data UnaryOp = Negate deriving (Show, Eq)
|
||||
|
||||
data Expr =
|
||||
BinaryExpr BinaryOp Expr Expr |
|
||||
UnaryExpr UnaryOp Expr |
|
||||
Literal Int
|
||||
data Expr
|
||||
= BinaryExpr BinaryOp Expr Expr
|
||||
| UnaryExpr UnaryOp Expr
|
||||
| Literal Int
|
||||
deriving (Show, Eq)
|
||||
|
||||
lookUpBinaryOp :: BinaryOp -> Int -> Int -> Int
|
||||
@ -50,28 +53,18 @@ 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,
|
||||
parseExpr =
|
||||
makeExprParser
|
||||
parseLiteral
|
||||
-- bracketedExpParser,
|
||||
-- negatedExp
|
||||
[ [InfixL (char '/' $> BinaryExpr Divide)]
|
||||
, [InfixL (char '*' $> BinaryExpr Multiply)]
|
||||
, [InfixL (char '+' $> BinaryExpr Add)]
|
||||
, [InfixL (char '-' $> BinaryExpr Subtract)]
|
||||
]
|
||||
|
||||
parseLiteral :: Parser Expr
|
||||
parseLiteral = Literal <$> decimal
|
||||
|
||||
parseBinaryExpr :: Parser Expr
|
||||
parseBinaryExpr = do
|
||||
lhs <- parseExpr
|
||||
binOp <- parseOp
|
||||
rhs <- parseExpr
|
||||
pure (BinaryExpr binOp lhs rhs)
|
||||
|
||||
parseOp :: Parser BinaryOp
|
||||
parseOp = choice [
|
||||
char '+' >> pure Add,
|
||||
char '-' >> pure Subtract,
|
||||
char '/' >> pure Divide,
|
||||
char '*' >> pure Multiply
|
||||
parseLiteral =
|
||||
choice
|
||||
[ Literal <$> decimal
|
||||
, between (char '(') (char ')') parseExpr
|
||||
]
|
||||
|
||||
|
||||
@ -36,5 +36,8 @@ spec = do
|
||||
checkParse "2" (Literal 2)
|
||||
checkParse "2+3" (BinaryExpr Add (Literal 2) (Literal 3))
|
||||
checkParse "2+3+5" (BinaryExpr Add (BinaryExpr Add (Literal 2) (Literal 3)) (Literal 5))
|
||||
checkParse "2+3*5" (BinaryExpr Add (Literal 2) (BinaryExpr Multiply (Literal 3) (Literal 5)))
|
||||
checkParse "(2+3)*5" (BinaryExpr Multiply (BinaryExpr Add (Literal 2) (Literal 3)) (Literal 5) )
|
||||
checkParse "((2+3))*5" (BinaryExpr Multiply (BinaryExpr Add (Literal 2) (Literal 3)) (Literal 5) )
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user