generateParser ∷ String → String → Either String String
generateParser pname input = do
  (header, stateData, custom, pgr, lgr) ← mapLeft show $ runLexer input >>= parseGrammarFile
  (pgr', first, follow) ← processGrammar pgr
  let config = GC { parserName   = pname
                  , parserHeader = header
                  , parserState  = stateData
                  , parserCustom = custom
                  , pGrammar     = pgr'
                  , lGrammar     = lgr
                  , gFIRST       = first
                  , gFOLLOW      = follow
                  }
  generateParserSource config


main ::
generateParser ∷ String → String → Either String String
generateParser pname input = do
  (header, stateData, custom, pgr, lgr) ← mapLeft show $ runLexer input >>= parseGrammarFile
  (pgr', first, follow) ← processGrammar pgr
  let config = GC { parserName   = pname
                  , parserHeader = header
                  , parserState  = stateData
                  , parserCustom = custom
                  , pGrammar     = pgr'
                  , lGrammar     = lgr
                  , gFIRST       = first
                  , gFOLLOW      = follow
                  }
  generateParserSource config
generateParser pname input = do
  (header, stateData, custom, pgr, lgr) ← mapLeft show $ runLexer input >>= parseGrammarFile
  (pgr', first, follow) ← processGrammar pgr
  let config = GC { parserName   = pname
                  , parserHeader = header
                  , parserState  = stateData
                  , parserCustom = custom
                  , pGrammar     = pgr'
                  , lGrammar     = lgr
                  , gFIRST       = first
                  , gFOLLOW      = follow
                  }
  generateParserSource config