module GLL.Combinators.Visit.Grammar where

import GLL.Types.Grammar

import qualified Data.Map as M

type Grammar_Expr t = M.Map Nt [Prod t] -> M.Map Nt [Prod t]

grammar_nterm :: Nt -> [Prod t] -> [Grammar_Expr t] -> Grammar_Expr t
grammar_nterm :: forall t. Nt -> [Prod t] -> [Grammar_Expr t] -> Grammar_Expr t
grammar_nterm Nt
x [Prod t]
alts [Grammar_Expr t]
ps Map Nt [Prod t]
rules 
    | Nt
x Nt -> Map Nt [Prod t] -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`M.member` Map Nt [Prod t]
rules = Map Nt [Prod t]
rules
    | Bool
otherwise = (Grammar_Expr t -> Grammar_Expr t)
-> Map Nt [Prod t] -> [Grammar_Expr t] -> Map Nt [Prod t]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Grammar_Expr t -> Grammar_Expr t
forall a b. (a -> b) -> a -> b
($) (Nt -> [Prod t] -> Grammar_Expr t
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Nt
x [Prod t]
alts Map Nt [Prod t]
rules) ([Grammar_Expr t] -> Map Nt [Prod t])
-> [Grammar_Expr t] -> Map Nt [Prod t]
forall a b. (a -> b) -> a -> b
$ [Grammar_Expr t]
ps 

grammar_apply :: Grammar_Expr t -> Grammar_Expr t
grammar_apply :: forall t. Grammar_Expr t -> Grammar_Expr t
grammar_apply = Grammar_Expr t -> Grammar_Expr t
forall a. a -> a
id

grammar_seq :: Grammar_Expr t -> Grammar_Expr t -> Grammar_Expr t
grammar_seq :: forall t. Grammar_Expr t -> Grammar_Expr t -> Grammar_Expr t
grammar_seq Grammar_Expr t
p Grammar_Expr t
q Map Nt [Prod t]
rules =
    let rules1 :: Map Nt [Prod t]
rules1  = Grammar_Expr t
q Map Nt [Prod t]
rules
        rules2 :: Map Nt [Prod t]
rules2  = Grammar_Expr t
p Map Nt [Prod t]
rules1 in Map Nt [Prod t]
rules2