forked from jasder/antlr
got sync in
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6883]
This commit is contained in:
parent
03d9f0ba32
commit
eaaa98bde9
|
@ -83,7 +83,6 @@ public abstract class BaseRecognizer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/** Match current input symbol against ttype. Attempt
|
||||
* single token insertion or deletion error recovery. If
|
||||
* that fails, throw MismatchedTokenException.
|
||||
|
@ -115,6 +114,15 @@ public abstract class BaseRecognizer {
|
|||
return matchedSymbol;
|
||||
}
|
||||
|
||||
// like matchSet but w/o consume; error checking routine.
|
||||
public void sync(LABitSet expecting) {
|
||||
if ( expecting.member(state.input.LA(1)) ) return;
|
||||
LABitSet followSet = computeErrorRecoverySet();
|
||||
followSet.orInPlace(expecting);
|
||||
NoViableAltException e = new NoViableAltException(this, followSet);
|
||||
recoverFromMismatchedSet(e, followSet);
|
||||
}
|
||||
|
||||
/** Match the wildcard: in a symbol */
|
||||
public void matchAny() {
|
||||
state.errorRecovery = false;
|
||||
|
@ -601,7 +609,6 @@ public abstract class BaseRecognizer {
|
|||
throw e;
|
||||
}
|
||||
|
||||
/** Not currently used */
|
||||
public Object recoverFromMismatchedSet(RecognitionException e,
|
||||
LABitSet follow)
|
||||
throws RecognitionException
|
||||
|
|
|
@ -121,7 +121,7 @@ else {
|
|||
}
|
||||
>>
|
||||
|
||||
LL1StarBlock(choice, alts, error) ::= <<
|
||||
LL1StarBlock(choice, alts, error, sync) ::= <<
|
||||
<choice.loopLabel>:
|
||||
while (true) {
|
||||
switch ( state.input.LA(1) ) {
|
||||
|
@ -130,21 +130,22 @@ while (true) {
|
|||
break;}; separator="\n">
|
||||
<cases(ttypes=choice.exitLook)>
|
||||
break <choice.loopLabel>;
|
||||
default :
|
||||
<error>
|
||||
}
|
||||
<sync>
|
||||
}
|
||||
>>
|
||||
|
||||
LL1StarBlockSingleAlt(choice, expr, alts, preamble, iteration, error) ::= <<
|
||||
LL1StarBlockSingleAlt(choice, expr, alts, preamble, iteration, error, sync) ::= <<
|
||||
<preamble; separator="\n">
|
||||
while ( <expr> ) {
|
||||
<alts; separator="\n">
|
||||
<iteration>
|
||||
<sync>
|
||||
}
|
||||
>>
|
||||
|
||||
LL1PlusBlock(choice, alts, error, earlyExitError) ::= <<
|
||||
LL1PlusBlock(choice, alts, error, earlyExitError, sync) ::= <<
|
||||
<sync>
|
||||
int <choice.loopCounterVar> = 0;
|
||||
<choice.loopLabel>:
|
||||
while (true) {
|
||||
|
@ -155,22 +156,25 @@ while (true) {
|
|||
<cases(ttypes=choice.exitLook)>
|
||||
if ( <choice.loopCounterVar> >= 1 ) break <choice.loopLabel>;
|
||||
else <earlyExitError>
|
||||
default :
|
||||
<error>
|
||||
}
|
||||
<sync>
|
||||
}
|
||||
>>
|
||||
|
||||
LL1PlusBlockSingleAlt(choice, expr, alts, preamble, iteration,
|
||||
error, earlyExitError) ::=
|
||||
error, earlyExitError, sync) ::=
|
||||
<<
|
||||
<sync>
|
||||
<preamble; separator="\n">
|
||||
do {
|
||||
<alts; separator="\n">
|
||||
<iteration>
|
||||
<sync>
|
||||
} while ( <expr> );
|
||||
>>
|
||||
|
||||
Sync(s) ::= "sync(<s.expecting.name>);"
|
||||
|
||||
ThrowNoViableAlt(t) ::= "throw new NoViableAlt(this, <t.expecting.name>);"
|
||||
ThrowEarlyExitException(t) ::= "throw new ThrowEarlyExitException(this, <t.expecting.name>);"
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ public class AnalysisPipeline {
|
|||
System.out.println("\nDECISION "+s.decision);
|
||||
|
||||
// TRY LINEAR APPROX FIXED LOOKAHEAD FIRST
|
||||
LinearApproximator lin = new LinearApproximator(g);
|
||||
LinearApproximator lin = new LinearApproximator(g, s.decision);
|
||||
DFA dfa = lin.createDFA(s);
|
||||
|
||||
// IF NOT LINEAR APPROX, TRY NFA TO DFA CONVERSION
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.antlr.v4.analysis;
|
||||
|
||||
import org.antlr.runtime.Token;
|
||||
import org.antlr.v4.automata.*;
|
||||
import org.antlr.v4.misc.IntervalSet;
|
||||
import org.antlr.v4.misc.OrderedHashSet;
|
||||
|
@ -65,13 +66,13 @@ public class LinearApproximator {
|
|||
*/
|
||||
OrderedHashSet<NFAConfig>[] configs;
|
||||
|
||||
public LinearApproximator(Grammar g) {
|
||||
public LinearApproximator(Grammar g, int decision) {
|
||||
this.g = g;
|
||||
this.decision = decision;
|
||||
}
|
||||
|
||||
public LinearApproximator(Grammar g, int k) {
|
||||
this(g);
|
||||
public LinearApproximator(Grammar g, int decision, int k) {
|
||||
this(g, decision);
|
||||
max_k = k;
|
||||
}
|
||||
|
||||
|
@ -212,6 +213,10 @@ public class LinearApproximator {
|
|||
}
|
||||
}
|
||||
|
||||
/** Compute FOLLOW of element but don't leave rule to compute global
|
||||
* context-free FOLLOW. Used for rule invocation, match token, and
|
||||
* error sync'ing.
|
||||
*/
|
||||
public IntervalSet LOOK(NFAState s) {
|
||||
System.out.println("LOOK("+s.stateNumber+")");
|
||||
lookBusy.clear();
|
||||
|
@ -226,8 +231,9 @@ public class LinearApproximator {
|
|||
if ( lookBusy.contains(ac) ) return;
|
||||
lookBusy.add(ac);
|
||||
|
||||
if ( s instanceof RuleStopState && !context.isEmpty() ) {
|
||||
_LOOK(context.returnState, context.parent, fset);
|
||||
if ( s instanceof RuleStopState ) {
|
||||
if ( !context.isEmpty() ) _LOOK(context.returnState, context.parent, fset);
|
||||
else fset.add(Token.EOR_TOKEN_TYPE); // hit end of rule
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.Map;
|
|||
/** */
|
||||
public class NFA {
|
||||
public static final int INVALID_ALT_NUMBER = -1;
|
||||
public static final int INVALID_DECISION_NUMBER = -1;
|
||||
|
||||
public Grammar g;
|
||||
public List<NFAState> states = new ArrayList<NFAState>();
|
||||
|
@ -38,6 +39,7 @@ public class NFA {
|
|||
public int defineDecisionState(DecisionState s) {
|
||||
decisionToNFAState.add(s);
|
||||
s.decision = decisionToNFAState.size()-1;
|
||||
System.out.println("dec state "+s.stateNumber+" gets dec # "+s.decision);
|
||||
return s.decision;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,18 +17,21 @@ public abstract class Choice extends SrcOp {
|
|||
public List<SrcOp> preamble;
|
||||
public IntervalSet expecting;
|
||||
public ThrowNoViableAlt error;
|
||||
public Sync sync;
|
||||
|
||||
public Choice(OutputModelFactory factory, GrammarAST blkOrEbnfRootAST, List<CodeBlock> alts) {
|
||||
super(factory, blkOrEbnfRootAST);
|
||||
this.alts = alts;
|
||||
this.decision = ((BlockStartState)blkOrEbnfRootAST.nfaState).decision;
|
||||
|
||||
LinearApproximator approx = new LinearApproximator(factory.g);
|
||||
// TODO: use existing lookahead! don't compute
|
||||
LinearApproximator approx = new LinearApproximator(factory.g, decision);
|
||||
NFAState decisionState = ast.nfaState;
|
||||
expecting = approx.LOOK(decisionState);
|
||||
System.out.println("expecting="+expecting);
|
||||
System.out.println(blkOrEbnfRootAST.toStringTree()+" loop expecting="+expecting);
|
||||
|
||||
this.error = new ThrowNoViableAlt(factory, blkOrEbnfRootAST, expecting);
|
||||
this.sync = new Sync(factory, blkOrEbnfRootAST, expecting);
|
||||
}
|
||||
|
||||
public void addPreambleOp(SrcOp op) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.antlr.v4.codegen.src;
|
||||
|
||||
import org.antlr.v4.analysis.LinearApproximator;
|
||||
import org.antlr.v4.automata.NFA;
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.codegen.RuleContextDecl;
|
||||
import org.antlr.v4.misc.IntervalSet;
|
||||
|
@ -47,8 +48,7 @@ public class InvokeRule extends SrcOp implements LabeledOp {
|
|||
factory.currentRule.peek().addDecl(d);
|
||||
}
|
||||
|
||||
// compute follow
|
||||
LinearApproximator approx = new LinearApproximator(factory.g);
|
||||
LinearApproximator approx = new LinearApproximator(factory.g, NFA.INVALID_DECISION_NUMBER);
|
||||
IntervalSet fset = approx.LOOK(ast.nfaState.transition(0).target);
|
||||
System.out.println("follow="+follow);
|
||||
follow = factory.createFollowBitSet(ast, fset);
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.List;
|
|||
|
||||
/** */
|
||||
public abstract class LL1Loop extends LL1Choice {
|
||||
public Object expr;
|
||||
public OutputModelObject expr;
|
||||
public List<SrcOp> iteration;
|
||||
|
||||
public LL1Loop(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) {
|
||||
|
@ -21,7 +21,7 @@ public abstract class LL1Loop extends LL1Choice {
|
|||
iteration.add(op);
|
||||
}
|
||||
|
||||
public void addLookaheadTempVar(IntervalSet look) {
|
||||
public void addCodeForLookaheadTempVar(IntervalSet look) {
|
||||
expr = factory.getLL1Test(look, ast);
|
||||
if ( expr instanceof TestSetInline ) {
|
||||
TestSetInline e = (TestSetInline) expr;
|
||||
|
@ -30,8 +30,6 @@ public abstract class LL1Loop extends LL1Choice {
|
|||
CaptureNextToken nextToken = new CaptureNextToken(e.varName);
|
||||
addPreambleOp(nextToken);
|
||||
addIterationOp(nextToken);
|
||||
iteration = new ArrayList<SrcOp>();
|
||||
iteration.add(nextToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ public class LL1PlusBlockSingleAlt extends LL1Loop {
|
|||
public LL1PlusBlockSingleAlt(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) {
|
||||
super(factory, blkAST, alts);
|
||||
IntervalSet loopBackLook = altLookSets[2]; // loop exit is alt 1
|
||||
addLookaheadTempVar(loopBackLook);
|
||||
addCodeForLookaheadTempVar(loopBackLook);
|
||||
}
|
||||
// @Override
|
||||
// public List<String> getChildren() {
|
||||
|
|
|
@ -11,6 +11,6 @@ public class LL1StarBlockSingleAlt extends LL1Loop {
|
|||
public LL1StarBlockSingleAlt(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) {
|
||||
super(factory, blkAST, alts);
|
||||
IntervalSet look = altLookSets[1];
|
||||
addLookaheadTempVar(look);
|
||||
addCodeForLookaheadTempVar(look);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.antlr.v4.codegen.src;
|
||||
|
||||
import org.antlr.v4.analysis.LinearApproximator;
|
||||
import org.antlr.v4.automata.NFA;
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.misc.IntervalSet;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
|
@ -39,7 +40,7 @@ public class MatchToken extends SrcOp implements LabeledOp {
|
|||
factory.currentRule.peek().addDecl(d);
|
||||
}
|
||||
|
||||
LinearApproximator approx = new LinearApproximator(factory.g);
|
||||
LinearApproximator approx = new LinearApproximator(factory.g, NFA.INVALID_DECISION_NUMBER);
|
||||
IntervalSet fset = approx.LOOK(ast.nfaState.transition(0).target);
|
||||
System.out.println("follow="+fset);
|
||||
follow = factory.createFollowBitSet(ast, fset);
|
||||
|
|
|
@ -1,5 +1,20 @@
|
|||
package org.antlr.v4.codegen.src;
|
||||
|
||||
import org.antlr.v4.automata.BlockStartState;
|
||||
import org.antlr.v4.codegen.OutputModelFactory;
|
||||
import org.antlr.v4.misc.IntervalSet;
|
||||
import org.antlr.v4.tool.GrammarAST;
|
||||
|
||||
/** */
|
||||
public class Sync extends SrcOp {
|
||||
public int decision;
|
||||
public BitSetDecl expecting;
|
||||
public Sync(OutputModelFactory factory, GrammarAST blkOrEbnfRootAST,
|
||||
IntervalSet expecting)
|
||||
{
|
||||
super(factory, blkOrEbnfRootAST);
|
||||
this.decision = ((BlockStartState)blkOrEbnfRootAST.nfaState).decision;
|
||||
this.expecting = factory.createExpectingBitSet(ast, decision, expecting);
|
||||
factory.defineBitSet(this.expecting);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ public class TestLinearApproximateLookahead extends BaseTest {
|
|||
return;
|
||||
}
|
||||
DecisionState blk = (DecisionState)s.transition(0).target;
|
||||
LinearApproximator lin = new LinearApproximator(g);
|
||||
LinearApproximator lin = new LinearApproximator(g,blk.decision);
|
||||
DFA dfa = lin.createDFA(blk);
|
||||
String result = null;
|
||||
if ( dfa!=null ) result = dfa.toString();
|
||||
|
|
Loading…
Reference in New Issue