I started redesigning the Parser Combinators following the
paper by Hutton where he describes adding error reports by
rewriting everything to operate on a 3-state object. A parser
can result in an [OK ...] state or it can be [Error ...] or [Fail ...].
This way you can record some local state at the point that
an error is discovered and propagate that back down the
call stack wrapping more local knowledge at each step.
So for the simple tests I've put it to, viz.
0 0 (abcd\ne) string-input
(abc) str exec
report
pc
0 0 (abed\ne) string-input
(abd) str
(abc) str alt exec
report
pc
0 0 (abed\ne) string-input
(a)(c) range
(a)(c) range then
exec
report
pq
That is two success tests and one failure test, I get the following
(promising) output:
$ gsnd -q -dNOSAFER
pc11a.ps
OK
[(a) (b) (c)]
remainder:[[(d) [0 3]] {0 4 (\ne) string-input}]
stack:
:stack
Fail
[[(after) [(a) []]] [[(after) [(b) []]] [[{(c) eq} (not satisfied)] [[(e) [0 2]] {0 3 (d\ne) string-input}]]]]
stack:
:stack
OK
[(a) (b)]
remainder:{0 2 (ed\ne) string-input}
stack:
:stack
The "stack:...:stack" parts are just demonstrating that the stacks
are left nice and clean after each test. And the Failure report has
the pieces for a nice error message, but it's not quite there yet IMO.
I suppose the next logical step is to try to build a regex engine or
a tokenizer with it. to be continued...