Haskell parsec で命題論理(propositional logic)の構文解析器

Haskell parsec で命題論理(propositional logic)の構文解析器を作ってみた。

作ってみた、とは一言っても、つくりかけ。

BNF の右辺が2つの時はできるのだけど、それが3つ以上になった時にどうして良いかわからない。

以下を参考に作った。以下と違って、終端記号に文字列が使えるようになってる。

http://utotch.blogspot.jp/2011/12/haskell-parser.html

import Data.Char (ord)
import Text.Parsec 
import Text.Parsec.String 
import Text.Parsec.Token

data Exp = And Exp Exp | Or Exp Exp | Bool String deriving Show
{- BNF for simple boolean expression
expr ::= term ('&' expr | ε)
term ::= factor ('|' term | ε)
factor ::= '(' expr ')' | bool
bool ::= String
-}

-- expr ::= term ('&' expr | ε)
expr::Parser Exp
expr =
  do
    t <- term
    do
      char '&'
      e <- expr
      return (And t e)
     <|> return t

-- term ::= factor ('|' term | ε)
term::Parser Exp
term =
  do
    f <- factor
    do
      char '|'
      t <- term
      return (Or f t)
     <|> return f
    
-- factor ::= '(' expr ')' | var
factor::Parser Exp
factor =
  do
    char '('
    e <- expr
    char ')'
    return e
   <|> var
  
-- var ::= String
var::Parser Exp
var =
  do
    s <- many (noneOf "()~|&\n")
--    s <- many1 p_char
--    s <- string "hoge"
--    s <- Text.Parsec.Token.identifier
    return (Bool s)

{- How to test this
parseTest expr "A & B"
parseTest expr "(A&B)|C"

parseTest expr "1+2*3"
Add (Nat 1) (Mul (Nat 2) (Nat 3))

parseTest expr "(1+2)*3"
-}