Skip to content
This repository was archived by the owner on Nov 12, 2025. It is now read-only.

Commit 458fb7e

Browse files
committed
add Run constructor to GrammarST
This allows a grammar with a different state type to be run in the current input stream context. Problematically, this causes the compiler to hang while processing `doParse`.
1 parent 68380ea commit 458fb7e

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

libs/contrib/Text/Parser/Core.idr

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

3845
public export
3946
Grammar : (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
132151
mapToken f (Alt x y) = Alt (mapToken f x) (mapToken f y)
133152
mapToken f Get = Get
134153
mapToken f (Put x) = Put x
154+
mapToken f (Run sub init) = Run (mapToken f sub) init
135155

136156
||| Always succeed with the given value.
137157
export
@@ -219,11 +239,20 @@ shorter : (more : List tok) -> .(ys : List tok) ->
219239
shorter more [] = lteRefl
220240
shorter 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+
222250
doParse : {c : Bool} ->
223251
(state : st) ->
224252
(commit : Bool) -> (xs : List tok) -> (act : GrammarST st tok c ty) ->
225253
ParseResult st xs c ty
226254
doParse 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

Comments
 (0)