1 -- -*- Mode: Haskell -*- 2 -- Copyright 1994 by Peter Thiemann 3 -- EbnfGrammar.hs --- a simple combinator parser for a grammar in EBNF 4 -- Author : Peter Thiemann 5 -- Created On : Tue Aug 3 10:30:03 1993 6 -- Last Modified By: Peter Thiemann 7 -- Last Modified On: Mon Dec 27 17:41:17 1993 8 -- Update Count : 13 9 -- Status : Unknown, Use with caution! 10 -- 11 -------------------------------------------------- 12 -- $Log: EbnfGrammar.hs,v $ 13 -- Revision 1.1 1996/01/08 20:02:34 partain 14 -- Initial revision 15 -- 16 -- Revision 1.3 1994/03/15 15:34:53 thiemann 17 -- added full color support, XColorDB based 18 -- 19 --Revision 1.2 1993/08/31 12:31:32 thiemann 20 --reflect changes in type FONT 21 -- 22 --Revision 1.1 1993/08/17 12:34:29 thiemann 23 --Initial revision 24 -- 25 -- $Locker: $ 26 -------------------------------------------------- 27 28 module EbnfGrammar (parseAll) where 29 30 import Parsers 31 import Lexer 32 import AbstractSyntax 33 34 parseAll s = [ prod | (prod, []) <- parseFile (lexer (uncomment s)) ] 35 36 -- This is the grammar for EBNF 37 -- File = {Production}. 38 -- Production = Nonterminal [ String ] "=" Term "." . 39 -- Term = Factor / "|" . # alternative 40 -- Factor = ExtAtom + . # sequence 41 -- ExtAtom = Atom 42 -- | Atom "/" Atom # repetion through Atom 43 -- | Atom "+". # at least one repetion 44 -- Atom = Nonterminal 45 -- | String # terminal string 46 -- | "(" Term ")" 47 -- | "[" Term "]" # an optional Term 48 -- | "{" Term "}" # zero or more repetions 49 -- . 50 -- String = "\"" { character } "\"" . 51 -- Nonterminal = letter { letter | digit | "_" } . 52 -- character = "\\" charesc. 53 54 parseFile = rpt parseProduction -- no longer `using` ProdFile 55 56 parseProduction = (satisfy isIdent `thn` 57 opt (satisfy isString) `thn` 58 expectSymbol "=" `xthn` 59 parseTerm `thnx` 60 expectSymbol ".") `using` 61 \(nt, (ntNames, term)) -> ProdProduction (getIdent nt) (map getString ntNames) term 62 63 parseTerm = (parseFactor `thn` 64 rpt (expectSymbol "|" `xthn` parseFactor)) 65 `using2` (:) `using` ProdTerm 66 67 parseFactor = (parseExtendedAtom `thn` rpt parseExtendedAtom) 68 `using2` (:) `using` ProdFactor 69 70 parseExtendedAtom = parseAtom `thn` 71 opt ((expectSymbol "+" `using` \ _ -> ProdPlus) 72 `alt` 73 (expectSymbol "/" `xthn` parseAtom `using` ProdSlash)) 74 `using2` helper 75 where 76 helper term [] = term 77 helper term [ProdPlus] = ProdRepeat1 term 78 helper term [ProdSlash atom] = ProdRepeatWithAtom term atom 79 80 parseAtom = (expectSymbol "(" `xthn` 81 parseTerm `thnx` 82 expectSymbol ")") 83 `alt` 84 ((expectSymbol "[" `xthn` parseTerm `thnx` expectSymbol "]") 85 `using` ProdOption) 86 `alt` 87 ((expectSymbol "{" `xthn` parseTerm `thnx` expectSymbol "}") 88 `using` ProdRepeat) 89 `alt` 90 (satisfy isIdent `using` (ProdNonterminal . getIdent)) 91 `alt` 92 (satisfy isString `using` (ProdTerminal . getString)) 93 94 expectSymbol c = satisfy test 95 where test (Symbol x) = c == x 96 test _ = False