Grammar.hs revision c21e35439f23de1c900b22b997b7869565322174
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd-- parse the ISO BNF grammar for DOL
0a146bb31945dd13e6f7ad35818f6842ec91ff53ndimport qualified Data.Set as Set
0a146bb31945dd13e6f7ad35818f6842ec91ff53nddata Term =
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd Terminal String
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd | NT String
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd | Alt [Term]
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd | Seq [Term]
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd | Option Term
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd | Many Term Bool
0a146bb31945dd13e6f7ad35818f6842ec91ff53nddata Rule = Rule { lhs :: String, rhs :: Term }
0a146bb31945dd13e6f7ad35818f6842ec91ff53ndlhss :: [Rule] -> [String]
0a146bb31945dd13e6f7ad35818f6842ec91ff53ndlhss = sort . map lhs
3a5c8a7c39f03520463a70cf3f90091dc3a1eb32ndnts :: Bool -> Term -> Set.Set String
0a146bb31945dd13e6f7ad35818f6842ec91ff53ndnts b trm = let unite = Set.unions . map (nts b) in case trm of
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd Terminal s -> if b || isPrefixOf "($<$" s then Set.empty
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd else Set.singleton . init $ tail s
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd Alt l -> unite l
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd Seq l -> unite l
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd Option t -> nts b t
0a146bb31945dd13e6f7ad35818f6842ec91ff53nd Many t _ -> nts b t
0a146bb31945dd13e6f7ad35818f6842ec91ff53ndterms :: Bool -> [Rule] -> Set.Set String
0a146bb31945dd13e6f7ad35818f6842ec91ff53ndterms b = Set.unions . map (nts b . rhs)
0a146bb31945dd13e6f7ad35818f6842ec91ff53ndterminals = terms False