{-# LANGUAGE AllowAmbiguousTypes #-} -- For grammar
{-# LANGUAGE ConstraintKinds #-} -- For Grammar
module Symantic.Parser.Grammar
  ( module Symantic.Parser.Grammar
  , module Symantic.Parser.Grammar.Combinators
  , module Symantic.Parser.Grammar.Fixity
  , module Symantic.Parser.Grammar.Optimize
  , module Symantic.Parser.Grammar.ObserveSharing
  , module Symantic.Parser.Grammar.Write
  , module Symantic.Parser.Grammar.View
  , Letable(..)
  ) where
import Symantic.Parser.Grammar.Combinators
import Symantic.Parser.Grammar.View
import Symantic.Parser.Grammar.Fixity
import Symantic.Parser.Grammar.ObserveSharing
import Symantic.Parser.Grammar.Optimize
import Symantic.Parser.Grammar.Write

import Data.Function ((.))
import Data.String (String)
import Text.Show (Show(..))
import qualified Language.Haskell.TH.Syntax as TH

-- * Class 'Grammar'
type Grammar tok repr =
  ( Applicable repr
  , Alternable repr
  , Satisfiable tok repr
  , Letable TH.Name repr
  , Selectable repr
  , Matchable repr
  , Foldable repr
  , Lookable repr
  )

-- | A usual pipeline to interpret 'Comb'inators:
-- 'observeSharing' then 'optimizeGrammar' then a polymorphic @(repr)@.
grammar ::
  Grammar tok repr =>
  ObserveSharing TH.Name
    (OptimizeGrammar repr) a ->
  repr a
grammar :: forall tok (repr :: * -> *) a.
Grammar tok repr =>
ObserveSharing Name (OptimizeGrammar repr) a -> repr a
grammar = SomeComb repr a -> repr a
forall (repr :: * -> *) a.
Trans (SomeComb repr) repr =>
SomeComb repr a -> repr a
optimizeGrammar (SomeComb repr a -> repr a)
-> (ObserveSharing Name (SomeComb repr) a -> SomeComb repr a)
-> ObserveSharing Name (SomeComb repr) a
-> repr a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ObserveSharing Name (SomeComb repr) a -> SomeComb repr a
forall (repr :: * -> *) a. ObserveSharing Name repr a -> repr a
observeSharing

-- | An usual pipeline to show 'Comb'inators:
-- 'observeSharing' then 'optimizeGrammar' then 'viewGrammar' then 'show'.
showGrammar ::
  ObserveSharing TH.Name
    (OptimizeGrammar (ViewGrammar showName)) a ->
  String
showGrammar :: forall (showName :: Bool) a.
ObserveSharing Name (OptimizeGrammar (ViewGrammar showName)) a
-> String
showGrammar = ViewGrammar showName a -> String
forall a. Show a => a -> String
show (ViewGrammar showName a -> String)
-> (ObserveSharing Name (SomeComb (ViewGrammar showName)) a
    -> ViewGrammar showName a)
-> ObserveSharing Name (SomeComb (ViewGrammar showName)) a
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ViewGrammar showName a -> ViewGrammar showName a
forall (sN :: Bool) a. ViewGrammar sN a -> ViewGrammar sN a
viewGrammar (ViewGrammar showName a -> ViewGrammar showName a)
-> (ObserveSharing Name (SomeComb (ViewGrammar showName)) a
    -> ViewGrammar showName a)
-> ObserveSharing Name (SomeComb (ViewGrammar showName)) a
-> ViewGrammar showName a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeComb (ViewGrammar showName) a -> ViewGrammar showName a
forall (repr :: * -> *) a.
Trans (SomeComb repr) repr =>
SomeComb repr a -> repr a
optimizeGrammar (SomeComb (ViewGrammar showName) a -> ViewGrammar showName a)
-> (ObserveSharing Name (SomeComb (ViewGrammar showName)) a
    -> SomeComb (ViewGrammar showName) a)
-> ObserveSharing Name (SomeComb (ViewGrammar showName)) a
-> ViewGrammar showName a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ObserveSharing Name (SomeComb (ViewGrammar showName)) a
-> SomeComb (ViewGrammar showName) a
forall (repr :: * -> *) a. ObserveSharing Name repr a -> repr a
observeSharing