-- -*- Mode: Haskell -*- -- Copyright 1994 by Peter Thiemann -- EbnfGrammar.hs --- a simple combinator parser for a grammar in EBNF -- Author : Peter Thiemann -- Created On : Tue Aug 3 10:30:03 1993 -- Last Modified By: Peter Thiemann -- Last Modified On: Mon Dec 27 17:41:17 1993 -- Update Count : 13 -- Status : Unknown, Use with caution! -- -------------------------------------------------- -- $Log: EbnfGrammar.hs,v $ -- Revision 1.1 2004/08/05 11:11:57 malcolm -- Add a regression testsuite for the nhc98 compiler. It isn't very good, -- but it is better than nothing. I've been using it for about four years -- on nightly builds, so it's about time it entered the repository! It -- includes a slightly altered version of the nofib suite. -- Instructions are in the README. -- -- Revision 1.1 1996/01/08 20:02:34 partain -- Initial revision -- -- Revision 1.3 1994/03/15 15:34:53 thiemann -- added full color support, XColorDB based -- --Revision 1.2 1993/08/31 12:31:32 thiemann --reflect changes in type FONT -- --Revision 1.1 1993/08/17 12:34:29 thiemann --Initial revision -- -- $Locker: $ -------------------------------------------------- module EbnfGrammar (parseAll) where import Parsers import Lexer import AbstractSyntax parseAll s = [ prod | (prod, []) <- parseFile (lexer (uncomment s)) ] -- This is the grammar for EBNF -- File = {Production}. -- Production = Nonterminal [ String ] "=" Term "." . -- Term = Factor / "|" . # alternative -- Factor = ExtAtom + . # sequence -- ExtAtom = Atom -- | Atom "/" Atom # repetion through Atom -- | Atom "+". # at least one repetion -- Atom = Nonterminal -- | String # terminal string -- | "(" Term ")" -- | "[" Term "]" # an optional Term -- | "{" Term "}" # zero or more repetions -- . -- String = "\"" { character } "\"" . -- Nonterminal = letter { letter | digit | "_" } . -- character = "\\" charesc. parseFile = rpt parseProduction -- no longer `using` ProdFile parseProduction = (satisfy isIdent `thn` opt (satisfy isString) `thn` expectSymbol "=" `xthn` parseTerm `thnx` expectSymbol ".") `using` \(nt, (ntNames, term)) -> ProdProduction (getIdent nt) (map getString ntNames) term parseTerm = (parseFactor `thn` rpt (expectSymbol "|" `xthn` parseFactor)) `using2` (:) `using` ProdTerm parseFactor = (parseExtendedAtom `thn` rpt parseExtendedAtom) `using2` (:) `using` ProdFactor parseExtendedAtom = parseAtom `thn` opt ((expectSymbol "+" `using` \ _ -> ProdPlus) `alt` (expectSymbol "/" `xthn` parseAtom `using` ProdSlash)) `using2` helper where helper term [] = term helper term [ProdPlus] = ProdRepeat1 term helper term [ProdSlash atom] = ProdRepeatWithAtom term atom parseAtom = (expectSymbol "(" `xthn` parseTerm `thnx` expectSymbol ")") `alt` ((expectSymbol "[" `xthn` parseTerm `thnx` expectSymbol "]") `using` ProdOption) `alt` ((expectSymbol "{" `xthn` parseTerm `thnx` expectSymbol "}") `using` ProdRepeat) `alt` (satisfy isIdent `using` (ProdNonterminal . getIdent)) `alt` (satisfy isString `using` (ProdTerminal . getString)) expectSymbol c = satisfy test where test (Symbol x) = c == x test _ = False