use of org.antlr.v4.tool.ast.QuantifierAST in project antlr4 by tunnelvisionlabs.
the class ParserATNFactory method optional.
/**
* From {@code (A)?} build either:
*
* <pre>
* o--A->o
* | ^
* o---->|
* </pre>
*
* or, if {@code A} is a block, just add an empty alt to the end of the
* block
*/
@NotNull
@Override
public Handle optional(@NotNull GrammarAST optAST, @NotNull Handle blk) {
BlockStartState blkStart = (BlockStartState) blk.left;
ATNState blkEnd = blk.right;
preventEpsilonOptionalBlocks.add(Tuple.create(currentRule, blkStart, blkEnd));
boolean greedy = ((QuantifierAST) optAST).isGreedy();
// no way to express SLL restriction
blkStart.sll = false;
blkStart.nonGreedy = !greedy;
epsilon(blkStart, blk.right, !greedy);
optAST.atnState = blk.left;
return blk;
}
use of org.antlr.v4.tool.ast.QuantifierAST in project antlr4 by antlr.
the class ParserATNFactory method star.
/**
* From {@code (blk)*} build {@code ( blk+ )?} with *two* decisions, one for
* entry and one for choosing alts of {@code blk}.
*
* <pre>
* |-------------|
* v |
* o--[o-blk-o]->o o
* | ^
* -----------------|
* </pre>
*
* Note that the optional bypass must jump outside the loop as
* {@code (A|B)*} is not the same thing as {@code (A|B|)+}.
*/
@Override
public Handle star(GrammarAST starAST, Handle elem) {
StarBlockStartState blkStart = (StarBlockStartState) elem.left;
BlockEndState blkEnd = (BlockEndState) elem.right;
preventEpsilonClosureBlocks.add(new Triple<Rule, ATNState, ATNState>(currentRule, blkStart, blkEnd));
StarLoopEntryState entry = newState(StarLoopEntryState.class, starAST);
entry.nonGreedy = !((QuantifierAST) starAST).isGreedy();
atn.defineDecisionState(entry);
LoopEndState end = newState(LoopEndState.class, starAST);
StarLoopbackState loop = newState(StarLoopbackState.class, starAST);
entry.loopBackState = loop;
end.loopBackState = loop;
BlockAST blkAST = (BlockAST) starAST.getChild(0);
if (((QuantifierAST) starAST).isGreedy()) {
if (expectNonGreedy(blkAST)) {
g.tool.errMgr.grammarError(ErrorType.EXPECTED_NON_GREEDY_WILDCARD_BLOCK, g.fileName, starAST.getToken(), starAST.getToken().getText());
}
// loop enter edge (alt 1)
epsilon(entry, blkStart);
// bypass loop edge (alt 2)
epsilon(entry, end);
} else {
// if not greedy, priority to exit branch; make it first
// bypass loop edge (alt 1)
epsilon(entry, end);
// loop enter edge (alt 2)
epsilon(entry, blkStart);
}
// block end hits loop back
epsilon(blkEnd, loop);
// loop back to entry/exit decision
epsilon(loop, entry);
// decision is to enter/exit; blk is its own decision
starAST.atnState = entry;
return new Handle(entry, end);
}
use of org.antlr.v4.tool.ast.QuantifierAST in project antlr4 by tunnelvisionlabs.
the class ParserATNFactory method plus.
/**
* From {@code (blk)+} build
*
* <pre>
* |---------|
* v |
* [o-blk-o]->o->o
* </pre>
*
* We add a decision for loop back node to the existing one at {@code blk}
* start.
*/
@NotNull
@Override
public Handle plus(@NotNull GrammarAST plusAST, @NotNull Handle blk) {
PlusBlockStartState blkStart = (PlusBlockStartState) blk.left;
BlockEndState blkEnd = (BlockEndState) blk.right;
preventEpsilonClosureBlocks.add(Tuple.create(currentRule, blkStart, blkEnd));
PlusLoopbackState loop = newState(PlusLoopbackState.class, plusAST);
loop.nonGreedy = !((QuantifierAST) plusAST).isGreedy();
// no way to express SLL restriction
loop.sll = false;
atn.defineDecisionState(loop);
LoopEndState end = newState(LoopEndState.class, plusAST);
blkStart.loopBackState = loop;
end.loopBackState = loop;
plusAST.atnState = loop;
// blk can see loop back
epsilon(blkEnd, loop);
BlockAST blkAST = (BlockAST) plusAST.getChild(0);
if (((QuantifierAST) plusAST).isGreedy()) {
if (expectNonGreedy(blkAST)) {
g.tool.errMgr.grammarError(ErrorType.EXPECTED_NON_GREEDY_WILDCARD_BLOCK, g.fileName, plusAST.getToken(), plusAST.getToken().getText());
}
// loop back to start
epsilon(loop, blkStart);
// or exit
epsilon(loop, end);
} else {
// if not greedy, priority to exit branch; make it first
// exit
epsilon(loop, end);
// loop back to start
epsilon(loop, blkStart);
}
return new Handle(blkStart, end);
}
use of org.antlr.v4.tool.ast.QuantifierAST in project antlr4 by tunnelvisionlabs.
the class ParserATNFactory method star.
/**
* From {@code (blk)*} build {@code ( blk+ )?} with *two* decisions, one for
* entry and one for choosing alts of {@code blk}.
*
* <pre>
* |-------------|
* v |
* o--[o-blk-o]->o o
* | ^
* -----------------|
* </pre>
*
* Note that the optional bypass must jump outside the loop as
* {@code (A|B)*} is not the same thing as {@code (A|B|)+}.
*/
@NotNull
@Override
public Handle star(@NotNull GrammarAST starAST, @NotNull Handle elem) {
StarBlockStartState blkStart = (StarBlockStartState) elem.left;
BlockEndState blkEnd = (BlockEndState) elem.right;
preventEpsilonClosureBlocks.add(Tuple.create(currentRule, blkStart, blkEnd));
StarLoopEntryState entry = newState(StarLoopEntryState.class, starAST);
entry.nonGreedy = !((QuantifierAST) starAST).isGreedy();
// no way to express SLL restriction
entry.sll = false;
atn.defineDecisionState(entry);
LoopEndState end = newState(LoopEndState.class, starAST);
StarLoopbackState loop = newState(StarLoopbackState.class, starAST);
entry.loopBackState = loop;
end.loopBackState = loop;
BlockAST blkAST = (BlockAST) starAST.getChild(0);
if (((QuantifierAST) starAST).isGreedy()) {
if (expectNonGreedy(blkAST)) {
g.tool.errMgr.grammarError(ErrorType.EXPECTED_NON_GREEDY_WILDCARD_BLOCK, g.fileName, starAST.getToken(), starAST.getToken().getText());
}
// loop enter edge (alt 1)
epsilon(entry, blkStart);
// bypass loop edge (alt 2)
epsilon(entry, end);
} else {
// if not greedy, priority to exit branch; make it first
// bypass loop edge (alt 1)
epsilon(entry, end);
// loop enter edge (alt 2)
epsilon(entry, blkStart);
}
// block end hits loop back
epsilon(blkEnd, loop);
// loop back to entry/exit decision
epsilon(loop, entry);
// decision is to enter/exit; blk is its own decision
starAST.atnState = entry;
return new Handle(entry, end);
}
use of org.antlr.v4.tool.ast.QuantifierAST in project antlr4 by antlr.
the class ParserATNFactory method plus.
/**
* From {@code (blk)+} build
*
* <pre>
* |---------|
* v |
* [o-blk-o]->o->o
* </pre>
*
* We add a decision for loop back node to the existing one at {@code blk}
* start.
*/
@Override
public Handle plus(GrammarAST plusAST, Handle blk) {
PlusBlockStartState blkStart = (PlusBlockStartState) blk.left;
BlockEndState blkEnd = (BlockEndState) blk.right;
preventEpsilonClosureBlocks.add(new Triple<Rule, ATNState, ATNState>(currentRule, blkStart, blkEnd));
PlusLoopbackState loop = newState(PlusLoopbackState.class, plusAST);
loop.nonGreedy = !((QuantifierAST) plusAST).isGreedy();
atn.defineDecisionState(loop);
LoopEndState end = newState(LoopEndState.class, plusAST);
blkStart.loopBackState = loop;
end.loopBackState = loop;
plusAST.atnState = loop;
// blk can see loop back
epsilon(blkEnd, loop);
BlockAST blkAST = (BlockAST) plusAST.getChild(0);
if (((QuantifierAST) plusAST).isGreedy()) {
if (expectNonGreedy(blkAST)) {
g.tool.errMgr.grammarError(ErrorType.EXPECTED_NON_GREEDY_WILDCARD_BLOCK, g.fileName, plusAST.getToken(), plusAST.getToken().getText());
}
// loop back to start
epsilon(loop, blkStart);
// or exit
epsilon(loop, end);
} else {
// if not greedy, priority to exit branch; make it first
// exit
epsilon(loop, end);
// loop back to start
epsilon(loop, blkStart);
}
return new Handle(blkStart, end);
}
Aggregations