reworked look comp for loops

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6884]
This commit is contained in:
parrt 2010-05-22 13:16:21 -08:00
parent eaaa98bde9
commit e1577a8071
10 changed files with 65 additions and 28 deletions

View File

@ -1,7 +1,9 @@
package org.antlr.v4.automata; package org.antlr.v4.automata;
/** */ /** Start of (A|B|...)+ loop. Not decision, inner block has decision state */
public class PlusBlockStartState extends BlockStartState { public class PlusBlockStartState extends BasicState {
public LoopbackState loopBackState; public LoopbackState loopBackState;
public BlockEndState endState;
public PlusBlockStartState(NFA nfa) { super(nfa); } public PlusBlockStartState(NFA nfa) { super(nfa); }
} }

View File

@ -1,7 +1,6 @@
package org.antlr.v4.codegen.src; package org.antlr.v4.codegen.src;
import org.antlr.v4.analysis.LinearApproximator; import org.antlr.v4.analysis.LinearApproximator;
import org.antlr.v4.automata.BlockStartState;
import org.antlr.v4.automata.NFAState; import org.antlr.v4.automata.NFAState;
import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntervalSet; import org.antlr.v4.misc.IntervalSet;
@ -22,7 +21,6 @@ public abstract class Choice extends SrcOp {
public Choice(OutputModelFactory factory, GrammarAST blkOrEbnfRootAST, List<CodeBlock> alts) { public Choice(OutputModelFactory factory, GrammarAST blkOrEbnfRootAST, List<CodeBlock> alts) {
super(factory, blkOrEbnfRootAST); super(factory, blkOrEbnfRootAST);
this.alts = alts; this.alts = alts;
this.decision = ((BlockStartState)blkOrEbnfRootAST.nfaState).decision;
// TODO: use existing lookahead! don't compute // TODO: use existing lookahead! don't compute
LinearApproximator approx = new LinearApproximator(factory.g, decision); LinearApproximator approx = new LinearApproximator(factory.g, decision);
@ -30,7 +28,7 @@ public abstract class Choice extends SrcOp {
expecting = approx.LOOK(decisionState); expecting = approx.LOOK(decisionState);
System.out.println(blkOrEbnfRootAST.toStringTree()+" loop expecting="+expecting); System.out.println(blkOrEbnfRootAST.toStringTree()+" loop expecting="+expecting);
this.error = new ThrowNoViableAlt(factory, blkOrEbnfRootAST, expecting); // this.error = new ThrowNoViableAlt(factory, blkOrEbnfRootAST, expecting);
this.sync = new Sync(factory, blkOrEbnfRootAST, expecting); this.sync = new Sync(factory, blkOrEbnfRootAST, expecting);
} }

View File

@ -2,6 +2,7 @@ package org.antlr.v4.codegen.src;
import org.antlr.v4.analysis.LinearApproximator; import org.antlr.v4.analysis.LinearApproximator;
import org.antlr.v4.automata.DFA; import org.antlr.v4.automata.DFA;
import org.antlr.v4.automata.DecisionState;
import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntervalSet; import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.tool.GrammarAST; import org.antlr.v4.tool.GrammarAST;
@ -18,6 +19,7 @@ public class LL1Choice extends Choice {
public LL1Choice(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) { public LL1Choice(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) {
super(factory, blkAST, alts); super(factory, blkAST, alts);
this.decision = ((DecisionState)blkAST.nfaState).decision;
DFA dfa = factory.g.decisionDFAs.get(decision); DFA dfa = factory.g.decisionDFAs.get(decision);
altLookSets = LinearApproximator.getLL1LookaheadSets(dfa); altLookSets = LinearApproximator.getLL1LookaheadSets(dfa);
altLook = new ArrayList<String[]>(); altLook = new ArrayList<String[]>();

View File

@ -8,7 +8,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** */ /** */
public abstract class LL1Loop extends LL1Choice { public abstract class LL1Loop extends Choice {
public OutputModelObject expr; public OutputModelObject expr;
public List<SrcOp> iteration; public List<SrcOp> iteration;

View File

@ -1,15 +1,23 @@
package org.antlr.v4.codegen.src; package org.antlr.v4.codegen.src;
import org.antlr.v4.analysis.LinearApproximator;
import org.antlr.v4.automata.BlockStartState;
import org.antlr.v4.automata.DFA; import org.antlr.v4.automata.DFA;
import org.antlr.v4.automata.PlusBlockStartState; import org.antlr.v4.automata.PlusBlockStartState;
import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntervalSet; import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.tool.GrammarAST; import org.antlr.v4.tool.GrammarAST;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** */ /** */
public class LL1PlusBlock extends LL1Loop { public class LL1PlusBlock extends LL1Loop {
/** Token names for each alt 0..n-1 */
public List<String[]> altLook;
/** Lookahead for each alt 1..n */
public IntervalSet[] altLookSets;
public String loopLabel; public String loopLabel;
public String loopCounterVar; public String loopCounterVar;
public String[] exitLook; public String[] exitLook;
@ -17,11 +25,19 @@ public class LL1PlusBlock extends LL1Loop {
public LL1PlusBlock(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) { public LL1PlusBlock(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) {
super(factory, blkAST, alts); super(factory, blkAST, alts);
PlusBlockStartState plusStart = (PlusBlockStartState)blkAST.nfaState; PlusBlockStartState plus = (PlusBlockStartState)blkAST.nfaState;
int enterExitDecision = plusStart.decision; BlockStartState blkStart = (BlockStartState)plus.transition(0).target;
DFA dfa = factory.g.decisionDFAs.get(enterExitDecision); DFA dfa = factory.g.decisionDFAs.get(blkStart.decision);
IntervalSet exitLook = dfa.startState.edge(1).label; altLookSets = LinearApproximator.getLL1LookaheadSets(dfa);
altLook = new ArrayList<String[]>();
for (int a=1; a<altLookSets.length; a++) {
IntervalSet s = altLookSets[a];
altLook.add(factory.gen.target.getTokenTypesAsTargetLabels(factory.g, s.toArray()));
}
dfa = factory.g.decisionDFAs.get(plus.loopBackState.decision);
IntervalSet exitLook = dfa.startState.edge(0).label;
this.exitLook = factory.gen.target.getTokenTypesAsTargetLabels(factory.g, exitLook.toArray()); this.exitLook = factory.gen.target.getTokenTypesAsTargetLabels(factory.g, exitLook.toArray());
loopLabel = factory.gen.target.getLoopLabel(blkAST); loopLabel = factory.gen.target.getLoopLabel(blkAST);

View File

@ -1,5 +1,8 @@
package org.antlr.v4.codegen.src; package org.antlr.v4.codegen.src;
import org.antlr.v4.analysis.LinearApproximator;
import org.antlr.v4.automata.DFA;
import org.antlr.v4.automata.PlusBlockStartState;
import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntervalSet; import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.tool.GrammarAST; import org.antlr.v4.tool.GrammarAST;
@ -9,17 +12,14 @@ import java.util.List;
/** */ /** */
public class LL1PlusBlockSingleAlt extends LL1Loop { public class LL1PlusBlockSingleAlt extends LL1Loop {
public ThrowEarlyExitException earlyExitError; public ThrowEarlyExitException earlyExitError;
public LL1PlusBlockSingleAlt(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) { public LL1PlusBlockSingleAlt(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) {
super(factory, blkAST, alts); super(factory, blkAST, alts);
PlusBlockStartState plus = (PlusBlockStartState)blkAST.nfaState;
DFA dfa = factory.g.decisionDFAs.get(plus.loopBackState.decision);
IntervalSet[] altLookSets = LinearApproximator.getLL1LookaheadSets(dfa);
IntervalSet loopBackLook = altLookSets[2]; // loop exit is alt 1 IntervalSet loopBackLook = altLookSets[2]; // loop exit is alt 1
addCodeForLookaheadTempVar(loopBackLook); addCodeForLookaheadTempVar(loopBackLook);
this.earlyExitError = new ThrowEarlyExitException(factory, blkAST, expecting);
} }
// @Override
// public List<String> getChildren() {
// final List<String> sup = super.getChildren();
// return new ArrayList<String>() {{
// if ( sup!=null ) addAll(sup); add("earlyExitError");
// }};
// }
} }

View File

@ -1,27 +1,42 @@
package org.antlr.v4.codegen.src; package org.antlr.v4.codegen.src;
import org.antlr.v4.analysis.LinearApproximator;
import org.antlr.v4.automata.BlockStartState;
import org.antlr.v4.automata.DFA; import org.antlr.v4.automata.DFA;
import org.antlr.v4.automata.StarBlockStartState; import org.antlr.v4.automata.StarBlockStartState;
import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntervalSet; import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.tool.GrammarAST; import org.antlr.v4.tool.GrammarAST;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** */ /** */
public class LL1StarBlock extends LL1Loop { public class LL1StarBlock extends LL1Loop {
/** Token names for each alt 0..n-1 */
public List<String[]> altLook;
/** Lookahead for each alt 1..n */
public IntervalSet[] altLookSets;
public String loopLabel; public String loopLabel;
public String[] exitLook; public String[] exitLook;
public LL1StarBlock(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) { public LL1StarBlock(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) {
// point at choice block inside outermost enter-exit choice // point at choice block inside outermost enter-exit choice
super(factory, ((StarBlockStartState)blkAST.nfaState).transition(0).target.ast, alts); super(factory, ((StarBlockStartState)blkAST.nfaState).transition(0).target.ast, alts);
StarBlockStartState starStart = (StarBlockStartState)blkAST.nfaState; StarBlockStartState star = (StarBlockStartState)blkAST.nfaState;
int enterExitDecision = starStart.decision; int enterExitDecision = star.decision;
// BlockStartState blkStart = (BlockStartState)starStart.transition(0).target; BlockStartState blkStart = (BlockStartState)star.transition(0).target;
// this.decision = blkStart.decision; //this.decision = blkStart.decision;
int loopbackDecision = starStart.loopBackState.decision;
DFA dfa = factory.g.decisionDFAs.get(enterExitDecision); DFA dfa = factory.g.decisionDFAs.get(blkStart.decision);
altLookSets = LinearApproximator.getLL1LookaheadSets(dfa);
altLook = new ArrayList<String[]>();
for (int a=1; a<altLookSets.length; a++) {
IntervalSet s = altLookSets[a];
altLook.add(factory.gen.target.getTokenTypesAsTargetLabels(factory.g, s.toArray()));
}
dfa = factory.g.decisionDFAs.get(enterExitDecision);
IntervalSet exitLook = dfa.startState.edge(1).label; IntervalSet exitLook = dfa.startState.edge(1).label;
this.exitLook = factory.gen.target.getTokenTypesAsTargetLabels(factory.g, exitLook.toArray()); this.exitLook = factory.gen.target.getTokenTypesAsTargetLabels(factory.g, exitLook.toArray());

View File

@ -1,5 +1,8 @@
package org.antlr.v4.codegen.src; package org.antlr.v4.codegen.src;
import org.antlr.v4.analysis.LinearApproximator;
import org.antlr.v4.automata.DFA;
import org.antlr.v4.automata.StarBlockStartState;
import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntervalSet; import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.tool.GrammarAST; import org.antlr.v4.tool.GrammarAST;
@ -10,6 +13,9 @@ import java.util.List;
public class LL1StarBlockSingleAlt extends LL1Loop { public class LL1StarBlockSingleAlt extends LL1Loop {
public LL1StarBlockSingleAlt(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) { public LL1StarBlockSingleAlt(OutputModelFactory factory, GrammarAST blkAST, List<CodeBlock> alts) {
super(factory, blkAST, alts); super(factory, blkAST, alts);
StarBlockStartState star = (StarBlockStartState)blkAST.nfaState;
DFA dfa = factory.g.decisionDFAs.get(star.loopBackState.decision);
IntervalSet[] altLookSets = LinearApproximator.getLL1LookaheadSets(dfa);
IntervalSet look = altLookSets[1]; IntervalSet look = altLookSets[1];
addCodeForLookaheadTempVar(look); addCodeForLookaheadTempVar(look);
} }

View File

@ -1,6 +1,5 @@
package org.antlr.v4.codegen.src; package org.antlr.v4.codegen.src;
import org.antlr.v4.automata.BlockStartState;
import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntervalSet; import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.tool.GrammarAST; import org.antlr.v4.tool.GrammarAST;
@ -13,7 +12,7 @@ public class Sync extends SrcOp {
IntervalSet expecting) IntervalSet expecting)
{ {
super(factory, blkOrEbnfRootAST); super(factory, blkOrEbnfRootAST);
this.decision = ((BlockStartState)blkOrEbnfRootAST.nfaState).decision; // this.decision = ((BlockStartState)blkOrEbnfRootAST.nfaState).decision;
this.expecting = factory.createExpectingBitSet(ast, decision, expecting); this.expecting = factory.createExpectingBitSet(ast, decision, expecting);
factory.defineBitSet(this.expecting); factory.defineBitSet(this.expecting);
} }

View File

@ -1,6 +1,5 @@
package org.antlr.v4.codegen.src; package org.antlr.v4.codegen.src;
import org.antlr.v4.automata.BlockStartState;
import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.IntervalSet; import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.tool.GrammarAST; import org.antlr.v4.tool.GrammarAST;
@ -15,7 +14,7 @@ public class ThrowRecognitionException extends SrcOp {
public ThrowRecognitionException(OutputModelFactory factory, GrammarAST ast, IntervalSet expecting) { public ThrowRecognitionException(OutputModelFactory factory, GrammarAST ast, IntervalSet expecting) {
super(factory, ast); super(factory, ast);
this.decision = ((BlockStartState)ast.nfaState).decision; // this.decision = ((BlockStartState)ast.nfaState).decision;
grammarLine = ast.getLine(); grammarLine = ast.getLine();
grammarLine = ast.getCharPositionInLine(); grammarLine = ast.getCharPositionInLine();
grammarFile = factory.g.fileName; grammarFile = factory.g.fileName;