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