Reputation: 87
I need help creating a parser for ternary expressions. I'm given this grammar for ternary expressions.
tExp :: tOpd ( '<=>' tExp | '==>' tExp| e )
tOpd :: tTerm ( '|||' tOpd | e )
tTerm :: tFact ( '&&&' tTerm | e)
tFact :: '~' tPrim | tPrim
primary :: tVar | tLit | '('tExp')'
tVar :: lowercase (Alphanumeric)*
tLit :: T | F | M
I also have defined the data type Ternary and expression tree here.
data Ternary = T | F | M
deriving (Eq, Show, Ord)
data TExpTree = L Ternary -- Ternary literal (i.e. T, F or M)
| V String -- Variable
| N TExpTree -- Prefix not
| A TExpTree TExpTree -- And node
| O TExpTree TExpTree -- Or node
| E TExpTree TExpTree -- Equivalence node
| I TExpTree TExpTree -- Implication node
deriving (Show, Eq)
I know that first I need to create functions for each rule.
tExp:: Parser TExpTree
tExp = do o <- tOpd
(do symbol "<=>"
e <- tExp
return (e<=>o)
+++ do synbol "==>"
e <- tExp
return (e==>o)
+++ return o)
tOpd :: Parser TExpTree
tOpd = do t <- tTerm
(do symbol "|||"
e <- tOpd
return (t|||e)
+++ return t)
tTerm :: Parser TExpTree
tTerm = do f <- tFact
(do symbol "&&&"
e <- tTerm
return (f+e)
+++ return f)
tFact:: Parser TExpTree
tFact = do m <- tPrim
return m
+++
(do symbol "~"
m <- tExp
return (~m))
So far, I have these, but I don't know how to go about creating them for primary, tLit, and tVar.
Can someone help me figure out just tLit, so I can try doing the rest myself? I'm not sure how to go about this.
I have this test function for tLit to confirm that it works as well.
testtLit :: Bool
testtLit = lt == (L T) && lf == (L F) && lm == (L M)
where Just (lt, _) = parse tLit " T "
Just (lf, _) = parse tLit " F "
Just (lm, _) = parse tLit " M "
Upvotes: 0
Views: 130
Reputation: 789
You are implementing a parser and an evaluator in a single function. Because of that, you never use TExpTree
. If you want to build a parser, change the type of your parser functions to Parser TExpTree
. Then, let tExp
return (I e o)
instead of (e==>o)
, and so on.
The implementation of the tLit
function depends on the tools your parser offers. It could look like this (untested):
tLit :: Parser TExpTree
tLit = (symbol "T" >> return (L T))
<|> (symbol "F" >> return (L F))
<|> (symbol "M" >> return (L M))
Upvotes: 1