{ -- | Parser for Bnf module Data.Cfg.Bnf.Parser(parse) where import qualified Data.Map as M import Data.Cfg.Bnf.Scanner(scan) import Data.Cfg.Bnf.Syntax import Data.Cfg.Bnf.Token import Data.Cfg.Cfg(Production, V(..), Vs) } %name parseTokens grammar %error { parseError } %tokentype { Token } %token FULL_STOP { Token FULL_STOP $$ } LOWER_IDENTIFIER { Token LOWER_IDENTIFIER $$ } OR { Token OR $$ } UPPER_IDENTIFIER { Token UPPER_IDENTIFIER $$ } YIELDS { Token YIELDS $$ } %% grammar :: { Grammar String String } : prods { Grammar $1 } prods :: { [Production String String] } : prods prod { $1 ++ $2 } | prod { $1 } prod :: { [Production String String] } : LOWER_IDENTIFIER YIELDS rhs FULL_STOP { [ ($1, alt) | alt <- $3 ] } rhs :: { [Vs String String] } : alts { $1 } alts :: { [Vs String String] } : alts OR alt { $1 ++ [ $3 ] } | alt { [ $1 ] } alt :: { Vs String String } : terms { $1 } terms :: { Vs String String } : terms term { $1 ++ [ $2 ] } | { [] } term :: { V String String } : UPPER_IDENTIFIER { T $1 } | LOWER_IDENTIFIER { NT $1 } { parseError :: [Token] -> a parseError ts = error $ "parseError at: " ++ show ts -- | Parses Bnf source into a 'Grammar'. parse :: String -> Grammar String String parse = parseTokens . scan -- | Parses a list of 'Token's into a 'Grammar'. parseTokens :: [Token] -> Grammar String String }