1 (* Copyright (C
) 2002-2005 Henry Cejtin
, Matthew Fluet
, Suresh
2 * Jagannathan
, and Stephen Weeks
.
4 * MLton is released under a BSD
-style license
.
5 * See the file MLton
-LICENSE for details
.
8 structure ChoicePattern
: CHOICE_PATTERN
=
21 Concat v
=> seq
[str
"Concat ", Vector.layout layout v
]
22 | Choice v
=> seq
[str
"Choice ", Vector.layout layout v
]
23 |
String s
=> seq
[str
"\"", String.layout s
, str
"\""]
26 fun fromString (s
: string): t Result
.t
=
29 exception Error
of string
30 fun error ss
= raise Error (concat ss
)
38 state
: state
): int * t
=
40 fun accum () = String (String.fromListRev ac
) :: prev
42 Concat (Vector.fromListRev (accum ())) :: prevChoices
44 loop (cur
+ 1, String.sub (s
, cur
) :: ac
,
45 prev
, prevChoices
, state
)
50 val c
= String.sub (s
, cur
)
55 loop (cur
+ 1, [], [], [],
58 loop (cur
, [], t
:: accum (), prevChoices
,
65 Choice (Vector.fromList (finishChoice ())))
67 error
["unmatched } at position ",
71 Nest _
=> loop (cur
+ 1, [], [], finishChoice (),
73 | Normal
=> keepChar cur
)
79 then error
["terminating backslash"]
87 error
["unmatched { at position ",
90 (cur
, Concat (Vector.fromListRev (accum ()))))
93 Result
.Yes (#
2 (loop (0, [], [], [], Normal
)))
94 handle Error s
=> Result
.No s
98 Trace
.trace ("ChoicePattern.fromString", String.layout
, Result
.layout layout
)
101 fun foldDown (v
, a
, f
) =
106 else loop (i
- 1, f (Vector.sub (v
, i
), a
))
108 loop (Vector.length v
- 1, a
)
111 fun expandTree (t
: t
): string list
=
114 Vector.fold (v
, [], fn (t
, ac
) =>
117 foldDown (v
, [""], fn (t
, ac
) =>
119 (expandTree t
, [], fn (s
, all
) =>
121 (ac
, all
, fn (s
', all
) =>
122 concat
[s
, s
'] :: all
)))
125 fun expand (s
: string): string list Result
.t
=
126 Result
.map (fromString s
, expandTree
)