!7 cprint { srecord Superposition(Cl options) { *(O... options) { this.options = asList(options); } } class State extends ProbabilisticMachine2.State { ImmutableListWalker inputWalker; Chain stack; public State makeDescendant() { State s = prepareDescendant(new State); s.inputWalker = inputWalker; s.stack = stack; ret s; } void doneWithSubroutine { if (stack == null) ret; State s = makeDescendant(); s.stack = dropFirst(s.stack); process(s, first(stack)); } void step { doneWithSubroutine(); } } record SequenceCons(a, b) > State { void step { State s = makeDescendant(); s.stack = chainPlus(s.stack, b); process(s, a); } } asclass GrammarClass {} sclass Statement > GrammarClass {} abstract class Executable { abstract void step(State state) {} } record grab(what) > Executable { void step(State state) { if (state.inputWalker.atEnd()) ret; S token = state.inputWalker!; if (eq(token, what)) { State s = state.makeDescendant(); s.inputWalker = s.inputWalker.next(); } } } // what: string or a GrammarClass class EndOfInput > Executable { void step(State state) { print("end of input reached"); super.step(); } } // what: string or a GrammarClass Executable sequence(O... steps) { if (empty(steps)) ret new Executable; ret foldl_noSeed((a, b) -> new SequenceCons(a, b), steps); } start-thread { Superposition main = sequence( new Superposition( sequence( new grab("I"), new grab("think"), new Superposition( sequence( new grab("that"), new grab(Statement) ), new grab(Statement) ) ), sequence( new grab("Do"), new grab("you"), new grab("think"), new grab("that"), new grab(Statement), new grab("?") ), new grab(Statement) ), new EndOfInput); printIndentedStruct(main); S input = "I think that you're right"; new ProbabilisticMachine2 pm; State state = pm.addState(new State); state.inputWalker = new ImmutableListWalker(javaTokC(input)); process(state, main); } void process(State state, O code) { if (code cast Superposition) { fOr (O option : code.options) pm.addState(state.prepareDescendant(new State { void step { process(state, option); } })); } else if (code cast Executable) { pm.addState(new State { void step { code.step(state, code); } }); } else fail("Unknown code type: " + code); } }