use of suite.ebnf.Grammar in project suite by stupidsing.
the class BuildLr method build.
private Blr build(IList<Pair<String, Set<String>>> ps, Grammar eg, Transition nextx) {
Fun<Streamlet2<String, Transition>, Blr> mergeAll = st2 -> {
Transition next = newTransition(readLookahead.readLookahead(eg, nextx.keySet()));
State state1 = newState(nextx);
st2.sink((egn, next1) -> {
next.put_(egn, Pair.of(state1, null));
merges.add(Pair.of(next, next1));
});
return new Blr(1, next);
};
Pair<String, Set<String>> k;
Blr blr;
switch(eg.type) {
case AND___:
if (!eg.children.isEmpty()) {
Grammar tail = new Grammar(GrammarType.AND___, List_.right(eg.children, 1));
Blr blr1 = build(ps, tail, nextx);
Blr blr0 = build(ps, eg.children.get(0), blr1.next);
blr = new Blr(blr0.nTokens + blr1.nTokens, blr0.next);
} else
blr = new Blr(0, nextx);
break;
case ENTITY:
k = Pair.of(eg.content, nextx.keySet());
Transition next1 = transitions.computeIfAbsent(k, k_ -> new Transition());
blr = mergeAll.apply(Read.each2(eg.content, next1));
break;
case NAMED_:
Reduce reduce = new Reduce();
Transition next = newTransition(nextx.keySet(), Pair.of(null, reduce));
Blr blr1 = build(ps, eg.children.get(0), next);
reduce.n = blr1.nTokens;
reduce.name = eg.content;
blr = new Blr(1, blr1.next);
break;
case OR____:
List<Pair<String, Transition>> pairs = new ArrayList<>();
for (Grammar eg1 : Read.from(eg.children)) {
String egn = "OR." + System.identityHashCode(eg1);
pairs.add(Pair.of(egn, build(ps, new Grammar(GrammarType.NAMED_, egn, eg1), nextx).next));
}
blr = mergeAll.apply(Read.from2(pairs));
break;
case STRING:
State state1 = newState(nextx);
blr = new Blr(1, kv(eg.content, state1));
break;
default:
blr = Fail.t("LR parser cannot recognize " + eg.type);
}
return blr;
}
use of suite.ebnf.Grammar in project suite by stupidsing.
the class TopDownParse method parse.
public Ast parse(String entity, String s) {
Parse parse = new Parse(s);
Ast node = parse.parse(0, build(new Grammar(GrammarType.ENTITY, entity)));
if (node != null)
return node;
else {
IntIntPair pos = parse.findPosition(parse.errorPosition);
return Fail.t("syntax error for entity " + parse.errorEntity + " at " + pos);
}
}
use of suite.ebnf.Grammar in project suite by stupidsing.
the class TopDownParse method build.
private Parser build(Grammar eg) {
Parser parser, g;
List<Parser> parsers;
switch(eg.type) {
case AND___:
parsers = buildChildren(eg);
parser = (parse, st) -> {
Outlet<State> o = Outlet.of(st);
for (Parser g_ : parsers) o = o.concatMap(st_ -> st_.pr(parse, g_));
return o;
};
break;
case ENTITY:
parser = buildEntity(eg.content);
break;
case EXCEPT:
Parser parser0 = build(eg.children.get(0));
Parser parser1 = build(eg.children.get(1));
parser = (parse, st) -> st.p(parse, parser0).filter(st1 -> {
String in1 = parse.in.substring(st.pos, st1.pos);
return new State(null, 0, null, 0).p(new Parse(in1), parser1).count() == 0;
});
break;
case NAMED_:
parser = deepen(build(eg.children.get(0)), eg.content);
break;
case ONCE__:
g = build(eg.children.get(0));
parser = (parse, st) -> Outlet.of(st.pr(parse, g).take(1));
break;
case OPTION:
g = build(eg.children.get(0));
parser = (parse, st) -> st.pr(parse, g).cons(st);
break;
case OR____:
parsers = buildChildren(eg);
parser = (parse, st) -> Outlet.of(parsers).concatMap(g_ -> st.pr(parse, g_));
break;
case REPT0_:
parser = buildRepeat(eg, true);
break;
case REPT0H:
parser = buildRepeatHeadRecursion(eg);
break;
case REPT1_:
parser = buildRepeat(eg, false);
break;
case STRING:
ExpectFun e = expect.string(eg.content);
parser = skipWhitespaces((parse, st) -> parse.expect(st, e, st.pos));
break;
default:
parser = null;
}
return parser;
}
use of suite.ebnf.Grammar in project suite by stupidsing.
the class ReadLookahead method mergeLookahead.
private void mergeLookahead(Grammar eg, LookaheadSet ls) {
switch(eg.type) {
case AND___:
if (!eg.children.isEmpty()) {
LookaheadSet ls0 = readLookahead(eg.children.get(0));
ls.lookaheads.addAll(ls0.lookaheads);
if (ls0.isPassThru) {
Grammar tail = new Grammar(GrammarType.AND___, List_.right(eg.children, 1));
ls.merge(readLookahead(tail));
}
}
break;
case ENTITY:
ls.merge(readLookahead(grammarByEntity.get(eg.content)));
break;
case NAMED_:
ls.merge(readLookahead(eg.children.get(0)));
break;
case OR____:
for (Grammar eg1 : eg.children) ls.merge(readLookahead(eg1));
break;
case STRING:
ls.lookaheads.add(eg.content);
break;
default:
Fail.t("LR parser cannot recognize " + eg.type);
}
}
use of suite.ebnf.Grammar in project suite by stupidsing.
the class ReduceHeadRecursion method getHeadRecursionForm.
private HeadRecursionForm getHeadRecursionForm(Grammar en0, String entity) {
List<Grammar> empty = List.of();
Grammar en = expand(en0);
HeadRecursionForm hrf;
if (en.type == GrammarType.AND___ && en.children.isEmpty())
hrf = new HeadRecursionForm(empty, empty);
else if (en.type == GrammarType.AND___) {
HeadRecursionForm hrf0 = getHeadRecursionForm(en.children.get(0), entity);
List<Grammar> tail = List_.right(en.children, 1);
Fun<List<Grammar>, List<Grammar>> fun = list -> Read.from(list).map(en_ -> {
List<Grammar> ens1 = new ArrayList<>();
ens1.add(en_);
ens1.addAll(tail);
return new Grammar(GrammarType.AND___, ens1);
}).toList();
hrf = new HeadRecursionForm(fun.apply(hrf0.listb), fun.apply(hrf0.listc));
} else if (en.type == GrammarType.NAMED_ && String_.equals(en.content, entity))
hrf = new HeadRecursionForm(empty, List.of(new Grammar(GrammarType.AND___)));
else if (en.type == GrammarType.OR____) {
List<HeadRecursionForm> hrfs = Read.from(en.children).map(en_ -> getHeadRecursionForm(en_, entity)).toList();
List<Grammar> listb = Read.from(hrfs).flatMap(hrf_ -> hrf_.listb).toList();
List<Grammar> listc = Read.from(hrfs).flatMap(hrf_ -> hrf_.listc).toList();
hrf = new HeadRecursionForm(listb, listc);
} else
hrf = new HeadRecursionForm(List.of(en), empty);
return hrf;
}
Aggregations