{-# LANGUAGE OverloadedStrings #-} module BNFC.Backend.Haskell.Utilities.Parser where import BNFC.Prelude import Data.String (fromString) import Prettyprinter import BNFC.CF tokenName :: Doc () tokenName = "Token" parserCatName :: Cat -> Doc () parserCatName c = "p" <> fromString (printCatNamePrec' c) generateP :: Bool -> Cat -> Doc () generateP functor c = "%name" <+> parserCatName c <> (if functor then "_internal" else emptyDoc) <+> fromString (printCatNamePrec' c) qualify :: String -> String -> String qualify q s | null q = s | otherwise = q ++ "." ++ s -- | Generate patterns and a set of metavariables (de Bruijn indices) indicating -- where in the pattern the non-terminals are locate. -- -- >>> generatePatterns False [ NTerminal (Cat' (BaseCat 'E':|"xp")), Terminal (Keyword ('+':|[])), NTerminal (Cat' (BaseCat 'E':|"xp")) ] -- ("Exp '+' Exp",["$1","$3"]) -- -- >>> generatePatterns True [ NTerminal (Cat' (BaseCat 'E':|"xp")), Terminal (Keyword ('+':|[])), NTerminal (Cat' (BaseCat 'E':|"xp")) ] -- ("Exp '+' Exp",["(snd $1)","(snd $3)"]) -- generatePatterns :: Bool -> RHS -> (String, [String]) generatePatterns _ [] = ("{- empty -}", []) generatePatterns functor rhs = ( unwords $ printRHS rhs , [ if functor then "(snd $" ++ show i ++ ")" else '$' : show i | (i, _) <- filter (isNTerminal . snd) (zip [1 :: Int ..] rhs) ] )