Implemented the program
This commit is contained in:
parent
ff37176966
commit
7075c52c9f
5 changed files with 144 additions and 4 deletions
79
src/Lib.hs
79
src/Lib.hs
|
@ -1,6 +1,79 @@
|
|||
module Lib
|
||||
( someFunc
|
||||
( parseFullString, evaluate, collectVariableNames, Expression, ParseError
|
||||
) where
|
||||
|
||||
someFunc :: IO ()
|
||||
someFunc = putStrLn "someFunc"
|
||||
import Text.Parsec
|
||||
import Text.Parsec.Expr
|
||||
import Text.Parsec.Token
|
||||
import Text.Parsec.Language
|
||||
|
||||
import Data.Set (Set)
|
||||
import qualified Data.Set as Set
|
||||
|
||||
import Data.Map (Map)
|
||||
import qualified Data.Map as Map
|
||||
|
||||
import Data.Functor.Identity
|
||||
|
||||
data Expression = Constant Bool | Binary BinaryOperator Expression Expression | Unary UnaryOperator Expression | Variable String
|
||||
deriving Show
|
||||
data BinaryOperator = LogicalAnd | LogicalOr
|
||||
deriving Show
|
||||
data UnaryOperator = LogicalNot
|
||||
deriving Show
|
||||
|
||||
def :: GenLanguageDef String u Identity
|
||||
def = emptyDef{ commentStart = ""
|
||||
, commentEnd = ""
|
||||
, identStart = letter <|> char '_'
|
||||
, identLetter = alphaNum <|> char '_'
|
||||
, opStart = oneOf "&|~"
|
||||
, opLetter = oneOf "&|~"
|
||||
, reservedOpNames = ["&", "|", "~"]
|
||||
, reservedNames = ["true", "false"]
|
||||
}
|
||||
|
||||
TokenParser{ parens = m_parens
|
||||
, identifier = m_identifier
|
||||
, reservedOp = m_reservedOp
|
||||
, reserved = m_reserved
|
||||
, whiteSpace = m_whiteSpace } = makeTokenParser def
|
||||
|
||||
exprparser :: ParsecT String () Identity Expression
|
||||
exprparser = buildExpressionParser table term <?> "expression"
|
||||
|
||||
table :: [[Operator String u Identity Expression]]
|
||||
table = [
|
||||
[
|
||||
Prefix (m_reservedOp "~" >> return (Unary LogicalNot))
|
||||
],
|
||||
[
|
||||
Infix (m_reservedOp "&" >> return (Binary LogicalAnd)) AssocLeft
|
||||
],
|
||||
[
|
||||
Infix (m_reservedOp "|" >> return (Binary LogicalOr)) AssocLeft
|
||||
]
|
||||
]
|
||||
|
||||
term :: ParsecT String () Data.Functor.Identity.Identity Expression
|
||||
term = m_parens exprparser
|
||||
<|> fmap Variable (m_identifier)
|
||||
<|> (m_reserved "true" >> return (Constant True))
|
||||
<|> (m_reserved "false" >> return (Constant False))
|
||||
<?> "logical expression"
|
||||
|
||||
parseFullString :: SourceName -> String -> Either ParseError Expression
|
||||
parseFullString = parse (m_whiteSpace *> exprparser <* eof)
|
||||
|
||||
collectVariableNames :: Expression -> Set String
|
||||
collectVariableNames (Constant _) = Set.empty
|
||||
collectVariableNames (Binary _ left right) = Set.union (collectVariableNames left) (collectVariableNames right)
|
||||
collectVariableNames (Unary _ right) = collectVariableNames right
|
||||
collectVariableNames (Variable name) = Set.singleton name
|
||||
|
||||
evaluate :: Map String Bool -> Expression -> Bool
|
||||
evaluate _ (Constant b) = b
|
||||
evaluate vs (Unary LogicalNot e) = not (evaluate vs e)
|
||||
evaluate vs (Binary LogicalAnd l r) = evaluate vs l && evaluate vs r
|
||||
evaluate vs (Binary LogicalOr l r) = evaluate vs l || evaluate vs r
|
||||
evaluate vs (Variable name) = maybe False id (Map.lookup name vs)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue