@@ -22,18 +22,25 @@ data GrammarST : (state : Type) -> (tok : Type) -> (consumes : Bool) -> Type ->
2222 Fail : String -> GrammarST st tok c ty
2323 Commit : GrammarST st tok False ()
2424
25- SeqEat : GrammarST st tok True a -> Inf (a -> GrammarST st tok c2 b) ->
25+ SeqEat : GrammarST st tok True a ->
26+ Inf (a -> GrammarST st tok c2 b) ->
2627 GrammarST st tok True b
2728 SeqEmpty : {c1, c2 : Bool } ->
28- GrammarST st tok c1 a -> (a -> GrammarST st tok c2 b) ->
29+ GrammarST st tok c1 a ->
30+ (a -> GrammarST st tok c2 b) ->
2931 GrammarST st tok (c1 || c2) b
3032 Alt : {c1, c2 : Bool } ->
31- GrammarST st tok c1 ty -> GrammarST st tok c2 ty ->
33+ GrammarST st tok c1 ty ->
34+ GrammarST st tok c2 ty ->
3235 GrammarST st tok (c1 && c2) ty
3336
3437 Get : GrammarST st tok False st
3538 Put : st -> GrammarST st tok False ()
3639
40+ Run : GrammarST inner tok c a ->
41+ (init : inner) ->
42+ GrammarST outer tok c (a, inner)
43+
3744
3845public export
3946Grammar : (tok : Type ) -> (consumes : Bool ) -> Type -> Type
@@ -87,10 +94,22 @@ Functor (GrammarST st tok c) where
8794 = SeqEat act (\ val => map f (next val))
8895 map f (SeqEmpty act next)
8996 = SeqEmpty act (\ val => map f (next val))
90- -- The remaining constructors (NextIs, EOF, Commit, Get, Put) have a fixed type,
97+ -- The remaining constructors (NextIs, EOF, Commit, Get, Put, Run ) have a fixed type,
9198 -- so a sequence must be used.
99+ map {c = True } f p = SeqEmpty p (Empty . f)
92100 map {c = False } f p = SeqEmpty p (Empty . f)
93101
102+ export
103+ run : GrammarST inner tok c a ->
104+ inner ->
105+ GrammarST outer tok c (a, inner)
106+ run = Run
107+
108+ export
109+ lift : Grammar tok c a ->
110+ GrammarST st tok c a
111+ lift g = map fst $ Run g ()
112+
94113||| Sequence a grammar with value type `a -> b` and a grammar
95114||| with value type `a`. If both succeed, apply the function
96115||| from the first grammar to the value from the second grammar.
@@ -132,6 +151,7 @@ mapToken f (SeqEmpty act next) = SeqEmpty (mapToken f act) (\x => mapToken f (ne
132151mapToken f (Alt x y) = Alt (mapToken f x) (mapToken f y)
133152mapToken f Get = Get
134153mapToken f (Put x) = Put x
154+ mapToken f (Run sub init ) = Run (mapToken f sub) init
135155
136156||| Always succeed with the given value.
137157export
@@ -219,11 +239,20 @@ shorter : (more : List tok) -> .(ys : List tok) ->
219239shorter more [] = lteRefl
220240shorter more (x :: xs) = LTESucc (lteSuccLeft (shorter more xs))
221241
242+ upgradeRes : {c : Bool } -> {xs : List tok} ->
243+ outerST ->
244+ ParseResult innerST xs c ty ->
245+ ParseResult outerST xs c (ty, innerST)
246+ upgradeRes state (Failure inner com msg xs) = Failure state com msg xs
247+ upgradeRes state (EmptyRes inner com val xs) = EmptyRes state com (val, inner) xs
248+ upgradeRes state (NonEmptyRes inner com val xs) = NonEmptyRes state com (val, inner) xs
249+
222250doParse : {c : Bool } ->
223251 (state : st) ->
224252 (commit : Bool ) -> (xs : List tok) -> (act : GrammarST st tok c ty) ->
225253 ParseResult st xs c ty
226254doParse state com xs act with (sizeAccessible xs)
255+ doParse state com xs (Run sub init ) | sml = upgradeRes state (doParse init com xs sub | sml)
227256 doParse state com xs Get | sml = EmptyRes state com state xs
228257 doParse state com xs (Put newState) | sml = EmptyRes newState com () xs
229258 doParse state com xs (Empty val) | sml = EmptyRes state com val xs
0 commit comments