user3277930
user3277930

Reputation: 87

How do I define a parser function for variables?

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

Answers (1)

sapanoia
sapanoia

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

Related Questions