got sync in

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6883]
This commit is contained in:
parrt 2010-05-22 12:23:36 -08:00
parent 03d9f0ba32
commit eaaa98bde9
13 changed files with 64 additions and 28 deletions

View File

@ -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

View File

@ -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>);"

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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() {

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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();