2015-12-09 17:49:24 +03:00
|
|
|
|
module Parser where
|
|
|
|
|
|
|
|
|
|
import Diff
|
2015-12-09 18:32:22 +03:00
|
|
|
|
import Range
|
|
|
|
|
import Syntax
|
2015-12-09 17:49:24 +03:00
|
|
|
|
import Term
|
2015-12-09 18:32:22 +03:00
|
|
|
|
import Control.Comonad.Cofree
|
2015-12-17 00:27:03 +03:00
|
|
|
|
import qualified OrderedMap as Map
|
2015-12-09 18:32:22 +03:00
|
|
|
|
import qualified Data.Set as Set
|
2015-12-15 21:29:58 +03:00
|
|
|
|
import qualified Data.Text as T
|
2015-12-09 17:49:24 +03:00
|
|
|
|
|
2015-12-15 21:29:58 +03:00
|
|
|
|
type Parser = T.Text -> IO (Term T.Text Info)
|
2015-12-09 18:32:22 +03:00
|
|
|
|
|
2015-12-17 00:24:58 +03:00
|
|
|
|
-- | Given a source string and a term’s annotation & production/child pairs, construct the term.
|
|
|
|
|
type Constructor = String -> Info -> [(String, Term String Info)] -> Term String Info
|
2015-12-17 00:27:03 +03:00
|
|
|
|
|
|
|
|
|
-- | Given two sets of production names, produce a Constructor.
|
|
|
|
|
constructorForProductions :: Set.Set String -> Set.Set String -> Constructor
|
|
|
|
|
constructorForProductions keyed fixed source info@(Info range categories) = (info :<) . construct
|
|
|
|
|
where construct [] = Leaf (substring range source)
|
|
|
|
|
construct children | not . Set.null $ Set.intersection fixed categories = Fixed $ fmap snd children
|
|
|
|
|
construct children | not . Set.null $ Set.intersection keyed categories = Keyed . Map.fromList $ assignKey <$> children
|
|
|
|
|
construct children = Indexed $ fmap snd children
|
|
|
|
|
assignKey ("pair", node@(_ :< Fixed (key : _))) = (getSubstring key, node)
|
|
|
|
|
assignKey (_, node) = (getSubstring node, node)
|
|
|
|
|
getSubstring (Info range _ :< _) = substring range source
|