1 {-# LANGUAGE PatternSynonyms #-}
2 {-# LANGUAGE TemplateHaskell #-}
3 {-# LANGUAGE ViewPatterns #-}
4 {-# LANGUAGE UndecidableInstances #-}
5 module Symantic.Parser.Grammar.Optimize where
7 import Data.Bool (Bool)
8 import Data.Char (Char)
9 import Data.Either (Either(..), either)
10 import Data.Eq (Eq(..))
11 import qualified Prelude as Pre
13 import Symantic.Base.Univariant
14 import Symantic.Parser.Grammar.Combinators
15 import Symantic.Parser.Grammar.ObserveSharing
16 import Symantic.Parser.Staging hiding (Haskell(..))
17 import qualified Symantic.Parser.Staging as Hask
18 -- import qualified Language.Haskell.TH.Syntax as TH
22 Pure :: Hask.Haskell a -> Grammar a
23 Satisfy :: Hask.Haskell (Char -> Bool) -> Grammar Char
25 Try :: Grammar a -> Grammar a
26 Look :: Grammar a -> Grammar a
27 NegLook :: Grammar a -> Grammar ()
28 (:<*>) :: Grammar (a -> b) -> Grammar a -> Grammar b
29 (:<|>) :: Grammar a -> Grammar a -> Grammar a
31 Branch :: Grammar (Either a b) -> Grammar (a -> c) -> Grammar (b -> c) -> Grammar c
32 Match :: Eq a => [Hask.Haskell (a -> Bool)] -> [Grammar b] -> Grammar a -> Grammar b -> Grammar b
33 ChainPre :: Grammar (a -> a) -> Grammar a -> Grammar a
34 ChainPost :: Grammar a -> Grammar (a -> a) -> Grammar a
35 Def :: Pointer -> Grammar a -> Grammar a
36 Ref :: Bool -> Pointer -> Grammar a
38 pattern (:<$>) :: Hask.Haskell (a -> b) -> Grammar a -> Grammar b
39 pattern (:$>) :: Grammar a -> Hask.Haskell b -> Grammar b
40 pattern (:<$) :: Hask.Haskell a -> Grammar b -> Grammar a
41 pattern (:*>) :: Grammar a -> Grammar b -> Grammar b
42 pattern (:<*) :: Grammar a -> Grammar b -> Grammar a
43 pattern x :<$> p = Pure x :<*> p
44 pattern p :$> x = p :*> Pure x
45 pattern x :<$ p = Pure x :<* p
46 pattern x :<* p = Hask.Const :<$> x :<*> p
47 pattern p :*> x = Hask.Id :<$ p :<*> x
50 infixl 4 :<*>, :<*, :*>
51 infixl 4 :<$>, :<$, :$>
53 instance Applicable Grammar where
56 instance Alternable Grammar where
60 instance Selectable Grammar where
62 instance Matchable Grammar where
64 instance Foldable Grammar where
67 instance Charable Grammar where
69 instance Lookable Grammar where
72 instance Letable Grammar where
85 Symantic Grammar repr where
88 Satisfy p -> satisfy p
91 Look x -> look (sym x)
92 NegLook x -> negLook (sym x)
93 x :<*> y -> sym x <*> sym y
94 x :<|> y -> sym x <|> sym y
96 Branch lr l r -> branch (sym lr) (sym l) (sym r)
97 Match cs bs a b -> conditional cs (sym Pre.<$> bs) (sym a) (sym b)
98 ChainPre x y -> chainPre (sym x) (sym y)
99 ChainPost x y -> chainPost (sym x) (sym y)
100 Def n x -> def n (sym x)
103 type instance Unlift Grammar = repr
113 ) => Unliftable Grammar where
116 Satisfy p -> satisfy p
118 Try x -> try (unlift x)
119 Look x -> look (unlift x)
120 NegLook x -> negLook (unlift x)
121 x :<*> y -> unlift x <*> unlift y
122 x :<|> y -> unlift x <|> unlift y
124 Branch lr l r -> branch (unlift lr) (unlift l) (unlift r)
125 Match cs bs a b -> conditional cs (unlift Pre.<$> bs) (unlift a) (unlift b)
126 ChainPre x y -> chainPre (unlift x) (unlift y)
127 ChainPost x y -> chainPost (unlift x) (unlift y)
128 Ref{..} -> let_ let_rec let_name
139 ) => Grammar repr a -> repr a
143 optimizeGrammar :: Grammar a -> Grammar a
144 optimizeGrammar = \case
145 -- Recurse into shared and/or recursive 'let' definition
146 Def n x -> Def n (optimizeGrammar x)
148 -- Applicable Right Absorption Law
149 Empty :<*> _ -> Empty
152 -- Applicable Failure Weakening Law
153 u :<*> Empty -> optimizeGrammar (u :*> Empty)
154 u :<* Empty -> optimizeGrammar (u :*> Empty)
155 -- Branch Absorption Law
156 Branch Empty _ _ -> empty
157 -- Branch Weakening Law
158 Branch b Empty Empty -> optimizeGrammar (b :*> Empty)
160 -- Applicable Identity Law
162 -- Flip const optimisation
163 Hask.Flip Hask.:@ Hask.Const :<$> u -> optimizeGrammar (u :*> Pure Hask.Id)
165 f :<$> Pure x -> Pure (f Hask.:@ x)
166 -- Functor Composition Law
167 -- (a shortcut that could also have been be caught
168 -- by the Composition Law and Homomorphism law)
169 f :<$> (g :<$> p) -> optimizeGrammar ((Hask.:.) Hask.:@ f Hask.:@ g :<$> p)
171 u :<*> (v :<*> w) -> optimizeGrammar (optimizeGrammar (optimizeGrammar ((Hask.:.) :<$> u) :<*> v) :<*> w)
173 Hask.Flip Hask.:@ Hask.Const :<$> p :<*> q -> p :*> q
175 Hask.Const :<$> p :<*> q -> p :<* q
176 -- Reassociation Law 1
177 (u :*> v) :<*> w -> optimizeGrammar (u :*> optimizeGrammar (v :<*> w))
179 u :<*> Pure x -> optimizeGrammar (Hask.Flip Hask.:@ (Hask.:$) Hask.:@ x :<$> u)
180 -- Right Absorption Law
181 (_ :<$> p) :*> q -> p :*> q
182 -- Left Absorption Law
183 p :<* (_ :<$> q) -> p :<* q
184 -- Reassociation Law 2
185 u :<*> (v :<* w) -> optimizeGrammar (optimizeGrammar (u :<*> v) :<* w)
186 -- Reassociation Law 3
187 u :<*> (v :$> x) -> optimizeGrammar (optimizeGrammar (u :<*> Pure x) :<* v)
196 (u :<|> v) :<|> w -> u :<|> optimizeGrammar (v :<|> w)
201 (u :$> _) :*> v -> u :*> v
203 u :*> (v :*> w) -> optimizeGrammar (optimizeGrammar (u :*> v) :*> w)
207 u :<* (v :$> _) -> optimizeGrammar (u :<* v)
209 x :<$ u -> optimizeGrammar (u :$> x)
211 (u :<* v) :<* w -> optimizeGrammar (u :<* optimizeGrammar (v :<* w))
217 -- Pure negative-lookahead
218 NegLook Pure{} -> Empty
220 -- Dead negative-lookahead
221 NegLook Empty -> Pure Hask.unit
222 -- Double Negation Law
223 NegLook (NegLook p) -> optimizeGrammar (Look (Try p) :*> Pure Hask.unit)
224 -- Zero Consumption Law
225 NegLook (Try p) -> optimizeGrammar (NegLook p)
227 Look (Look p) -> Look p
228 -- Right Identity Law
229 NegLook (Look p) -> optimizeGrammar (NegLook p)
232 Look (NegLook p) -> NegLook p
234 NegLook (Try p :<|> q) -> optimizeGrammar (optimizeGrammar (NegLook p) :*> optimizeGrammar (NegLook q))
235 -- Distributivity Law
236 Look p :<|> Look q -> optimizeGrammar (Look (optimizeGrammar (Try p :<|> q)))
238 Look (p :$> x) -> optimizeGrammar (optimizeGrammar (Look p) :$> x)
240 Look (f :<$> p) -> optimizeGrammar (f :<$> optimizeGrammar (Look p))
242 p :<*> NegLook q -> optimizeGrammar (optimizeGrammar (p :<*> Pure Hask.unit) :<* NegLook q)
244 NegLook (p :$> _) -> optimizeGrammar (NegLook p)
246 NegLook (_ :<$> p) -> optimizeGrammar (NegLook p)
248 Try (p :$> x) -> optimizeGrammar (optimizeGrammar (Try p) :$> x)
250 Try (f :<$> p) -> optimizeGrammar (f :<$> optimizeGrammar (Try p))
252 -- pure Left/Right laws
253 Branch (Pure (unlift -> lr)) l r ->
255 Left v -> optimizeGrammar (l :<*> Pure (Hask.Haskell (ValueCode (Value v) c)))
256 where c = Code [|| case $$(getCode lr) of Left x -> x ||]
257 Right v -> optimizeGrammar (r :<*> Pure (Hask.Haskell (ValueCode (Value v) c)))
258 where c = Code [|| case $$(getCode lr) of Right x -> x ||]
259 -- Generalised Identity law
260 Branch b (Pure (unlift -> l)) (Pure (unlift -> r)) ->
261 optimizeGrammar (Hask.Haskell (ValueCode v c) :<$> b)
263 v = Value (either (getValue l) (getValue r))
264 c = Code [|| either $$(getCode l) $$(getCode r) ||]
266 Branch (x :*> y) p q ->
267 optimizeGrammar (x :*> optimizeGrammar (Branch y p q))
268 -- Negated Branch law
270 Branch (Pure (Hask.Haskell (ValueCode v c)) :<*> b) Empty l
272 v = Value (either Right Left)
273 c = Code [||either Right Left||]
275 Branch (Branch b Empty (Pure (unlift -> lr))) Empty br ->
276 optimizeGrammar (Branch (optimizeGrammar (Pure (Hask.Haskell (ValueCode (Value v) c)) :<*> b)) Empty br)
279 v (Right r) = case getValue lr r of
282 c = Code [|| \case Left{} -> Left ()
283 Right r -> case $$(getCode lr) r of
285 Right rr -> Right rr ||]
286 -- Distributivity Law
287 f :<$> Branch b l r -> optimizeGrammar (Branch b (optimizeGrammar ((Hask..@) (Hask..) f :<$> l))
288 (optimizeGrammar ((Hask..@) (Hask..) f :<$> r)))