module EBNF where

{-
A -> B B
   | B C
B -> 'b'
C -> 'c'

or:

A -> B (B | C)
B -> 'b'
C -> 'c'
-}

-- look-ahead of one token
la :: [Char] -> [Char] -> Bool
la xs l = length xs > 0 && (head xs) `elem` l

data NT = A | B | C
        deriving Show

data Tree = Leaf Char
          | Node NT [ Tree ]
          deriving Show

parseA :: [Char] -> (Tree, [Char])
parseA xs | la ys "b" = (Node A [t1, t2 ], zs)
          | la ys "c" = (Node A [t1, t2'], zs')
  where (t1,  ys)  = parseB xs -- B 
        (t2,  zs)  = parseB ys -- B B
        (t2', zs') = parseC ys -- B C

parseB :: [Char] -> (Tree, [Char])
parseB ('b':xs) = (Node B [Leaf 'b'], xs)

parseC :: [Char] -> (Tree, [Char])
parseC ('c':xs) = (Node C [Leaf 'c'], xs)

