got more NFA created

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6732]
This commit is contained in:
parrt 2010-02-26 19:13:08 -08:00
parent 29175a418c
commit bf08801022
7 changed files with 761 additions and 531 deletions

View File

@ -6,7 +6,8 @@ import org.antlr.v4.tool.GrammarAST;
public class ActionTransition extends Transition {
public GrammarAST actionAST;
public ActionTransition(GrammarAST actionAST) {
public ActionTransition(GrammarAST actionAST, NFAState target) {
super(target);
this.actionAST = actionAST;
}

View File

@ -2,7 +2,7 @@ package org.antlr.v4.automata;
/** */
public class BasicState extends NFAState {
public Transition target;
public Transition transition;
/** For o-A->o type NFA tranitions, record the label that leads to this
* state. Useful for creating rich error messages when we find

View File

@ -17,4 +17,13 @@ public class BlockStartState extends NFAState {
new ArrayList<Transition>(INITIAL_NUM_TRANSITIONS);
public BlockStartState(NFA nfa) { super(nfa); }
@Override
public int getNumberOfTransitions() { return transitions.size(); }
@Override
public void addTransition(Transition e) { transitions.add(e); }
@Override
public Transition transition(int i) { return transitions.get(i); }
}

View File

@ -10,6 +10,8 @@ import org.antlr.v4.tool.TerminalAST;
import java.util.Collection;
import java.util.List;
// TODO: investigate o-X->o for basic states with typename for transition
/** Superclass of NFABuilder.g that provides actual NFA construction routines. */
public class ParserNFAFactory implements NFAFactory {
public Grammar g;
@ -41,22 +43,22 @@ public class ParserNFAFactory implements NFAFactory {
this.currentRule = g.getRule(name);
}
public NFAState newState() {
NFAState n = new BasicState(nfa);
public BasicState newState(GrammarAST node) {
BasicState n = new BasicState(nfa);
n.ast = node;
nfa.addState(n);
return n;
}
public BasicState newState() { return newState(null); }
/** From label A build Graph o-A->o */
public Handle tokenRef(TerminalAST node) {
System.out.println("tokenRef: "+node);
NFAState left = newState();
NFAState right = newState();
left.ast = node;
right.ast = node;
BasicState left = newState(node);
BasicState right = newState(node);
int ttype = g.getTokenType(node.getText());
Transition e = new AtomTransition(ttype, right);
left.addTransition(e);
left.transition = new AtomTransition(ttype, right);
return new Handle(left, right);
}
@ -65,19 +67,20 @@ public class ParserNFAFactory implements NFAFactory {
*/
public Handle set(IntSet set, GrammarAST associatedAST) { return null; }
public Handle tree(List<Handle> els) {
return null;
}
public Handle range(GrammarAST a, GrammarAST b) { return null; }
/** From char 'c' build Grip o-intValue(c)->o
public Handle not(Handle A) {
return null;
}
/** From char 'c' build o-intValue(c)->o
*/
public Handle charLiteral(GrammarAST charLiteralAST) { return null; }
/** From char 'c' build Grip o-intValue(c)->o
* can include unicode spec likes '\u0024' later. Accepts
* actual unicode 16-bit now, of course, by default.
* TODO not supplemental char clean!
*/
public Handle charRange(String a, String b) { return null; }
/** For a non-lexer, just build a simple token reference atom.
* For a lexer, a string is a sequence of char to match. That is,
* "fog" is treated as 'f' 'o' 'g' not as a single transition in
@ -107,21 +110,37 @@ public class ParserNFAFactory implements NFAFactory {
*/
public Handle ruleRef(GrammarAST node) { return null; }
/** From an empty alternative build Grip o-e->o */
/** From an empty alternative build o-e->o */
public Handle epsilon() { return null; }
/** Build what amounts to an epsilon transition with a semantic
* predicate action. The pred is a pointer into the AST of
* the SEMPRED token.
*/
public Handle sempred(GrammarAST pred) { return null; }
public Handle sempred(GrammarAST pred) {
System.out.println("sempred: "+ pred);
BasicState left = newState(pred);
NFAState right = newState(pred);
left.transition = new PredicateTransition(pred, right);
return new Handle(left, right);
}
public Handle gated_sempred(GrammarAST pred) {
return null;
}
/** Build what amounts to an epsilon transition with an action.
* The action goes into NFA though it is ignored during analysis.
* It slows things down a bit, but I must ignore predicates after
* having seen an action (5-5-2008).
*/
public Handle action(GrammarAST action) { return null; }
public Handle action(GrammarAST action) {
System.out.println("action: "+action);
BasicState left = newState(action);
NFAState right = newState(action);
left.transition = new ActionTransition(action, right);
return new Handle(left, right);
}
/** From A B build A-e->B (that is, build an epsilon arc from right
* of A to left of B).
@ -148,7 +167,7 @@ public class ParserNFAFactory implements NFAFactory {
*
* So every alternative gets begin NFAState connected by epsilon
* and every alt right side points at a block end NFAState. There is a
* new NFAState in the NFAState in the Grip for each alt plus one for the
* new NFAState in the NFAState in the handle for each alt plus one for the
* end NFAState.
*
* Special case: only one alternative: don't make a block with alt
@ -164,6 +183,12 @@ public class ParserNFAFactory implements NFAFactory {
return null;
}
public Handle alt(List<Handle> els) {
Handle first = els.get(0);
Handle last = els.get(els.size()-1);
return new Handle(first.left, last.right);
}
/** From (A)? build either:
*
* o--A->o
@ -172,7 +197,14 @@ public class ParserNFAFactory implements NFAFactory {
*
* or, if A is a block, just add an empty alt to the end of the block
*/
public Handle optional(Handle A) { return null; }
public Handle optional(Handle A) {
OptionalBlockStartState left = new OptionalBlockStartState(nfa);
BlockEndState right = new BlockEndState(nfa);
epsilon(left, A.left);
epsilon(A.right, right);
epsilon(left, right);
return new Handle(left, right);
}
/** From (A)+ build
*

View File

@ -9,15 +9,16 @@ import org.antlr.v4.tool.GrammarAST;
* may have to combine a bunch of them as it collects predicates from
* multiple NFA configurations into a single DFA state.
*/
public class PredicateTransition extends Label {
public class PredicateTransition extends Transition {
protected SemanticContext semanticContext;
public PredicateTransition(GrammarAST predicateASTNode) {
public PredicateTransition(GrammarAST predicateASTNode, NFAState target) {
super(target);
this.semanticContext = new SemanticContext.Predicate(predicateASTNode);
}
public PredicateTransition(SemanticContext semCtx) {
this.semanticContext = semCtx;
public int compareTo(Object o) {
return 0;
}
public int hashCode() {

View File

@ -94,90 +94,89 @@ block returns [NFAFactory.Handle p]
;
alternative returns [NFAFactory.Handle p]
: ^(ALT_REWRITE alternative .)
| ^(ALT EPSILON)
| ^(ALT element+)
@init {List<NFAFactory.Handle> els = new ArrayList<NFAFactory.Handle>();}
: ^(ALT_REWRITE a=alternative .) {$p = $a.p;}
| ^(ALT EPSILON) {$p = factory.epsilon();}
| ^(ALT (e=element {els.add($e.p);})+)
{$p = factory.alt(els);}
;
element returns [NFAFactory.Handle p]
: labeledElement
| atom
| ebnf
| ACTION
| SEMPRED
| GATED_SEMPRED
| treeSpec
: labeledElement {$p = $labeledElement.p;}
| atom {$p = $atom.p;}
| ebnf {$p = $ebnf.p;}
| ACTION {$p = factory.action($ACTION);}
| SEMPRED {$p = factory.sempred($SEMPRED);}
| GATED_SEMPRED {$p = factory.gated_sempred($GATED_SEMPRED);}
| treeSpec {$p = $treeSpec.p;}
;
labeledElement returns [NFAFactory.Handle p]
: ^(ASSIGN ID atom)
| ^(ASSIGN ID block)
| ^(PLUS_ASSIGN ID atom)
| ^(PLUS_ASSIGN ID block)
: ^(ASSIGN ID atom) {$p = $atom.p;}
| ^(ASSIGN ID block) {$p = $block.p;}
| ^(PLUS_ASSIGN ID atom) {$p = $atom.p;}
| ^(PLUS_ASSIGN ID block) {$p = $block.p;}
;
treeSpec returns [NFAFactory.Handle p]
: ^(TREE_BEGIN element+)
@init {List<NFAFactory.Handle> els = new ArrayList<NFAFactory.Handle>();}
: ^(TREE_BEGIN (e=element {els.add($e.p);})+) {$p = factory.tree(els);}
;
ebnf returns [NFAFactory.Handle p]
: ^(blockSuffix block)
| block
: ^(astBlockSuffix block) {$p = $block.p;}
| ^(OPTIONAL block) {$p = factory.optional($block.p);}
| ^(CLOSURE block) {$p = factory.star($block.p);}
| ^(POSITIVE_CLOSURE block) {$p = factory.plus($block.p);}
| block {$p = $block.p;}
;
blockSuffix returns [NFAFactory.Handle p]
: ebnfSuffix
| ROOT
astBlockSuffix
: ROOT
| IMPLIES
| BANG
;
ebnfSuffix returns [NFAFactory.Handle p]
: OPTIONAL
| CLOSURE
| POSITIVE_CLOSURE
;
atom returns [NFAFactory.Handle p]
: ^(ROOT range)
| ^(BANG range)
| ^(ROOT notSet)
| ^(BANG notSet)
| range
| ^(DOT ID terminal)
| ^(DOT ID ruleref)
| terminal
| ruleref
: ^(ROOT range) {$p = $range.p;}
| ^(BANG range) {$p = $range.p;}
| ^(ROOT notSet) {$p = $notSet.p;}
| ^(BANG notSet) {$p = $notSet.p;}
| range {$p = $range.p;}
| ^(DOT ID terminal) {$p = $terminal.p;}
| ^(DOT ID ruleref) {$p = $ruleref.p;}
| terminal {$p = $terminal.p;}
| ruleref {$p = $ruleref.p;}
;
notSet returns [NFAFactory.Handle p]
: ^(NOT notTerminal)
| ^(NOT block)
: ^(NOT notTerminal) {$p = factory.not($notTerminal.p);}
| ^(NOT block) {$p = factory.not($block.p);}
;
notTerminal returns [NFAFactory.Handle p]
: TOKEN_REF
| STRING_LITERAL
: TOKEN_REF {$p = factory.tokenRef((TerminalAST)$TOKEN_REF);}
| STRING_LITERAL {$p = factory.stringLiteral($start);}
;
ruleref returns [NFAFactory.Handle p]
: ^(ROOT ^(RULE_REF ARG_ACTION?)) {factory.ruleRef($RULE_REF);}
| ^(BANG ^(RULE_REF ARG_ACTION?)) {factory.ruleRef($RULE_REF);}
| ^(RULE_REF ARG_ACTION?) {factory.ruleRef($RULE_REF);}
: ^(ROOT ^(RULE_REF ARG_ACTION?)) {$p = factory.ruleRef($RULE_REF);}
| ^(BANG ^(RULE_REF ARG_ACTION?)) {$p = factory.ruleRef($RULE_REF);}
| ^(RULE_REF ARG_ACTION?) {$p = factory.ruleRef($RULE_REF);}
;
range returns [NFAFactory.Handle p]
: ^(RANGE a=STRING_LITERAL b=STRING_LITERAL) {factory.range($a,$b);}
: ^(RANGE a=STRING_LITERAL b=STRING_LITERAL) {$p = factory.range($a,$b);}
;
terminal returns [NFAFactory.Handle p]
: ^(STRING_LITERAL .) {factory.stringLiteral($start);}
| STRING_LITERAL {factory.stringLiteral($start);}
| ^(TOKEN_REF ARG_ACTION .) {factory.tokenRef((TerminalAST)$start);}
| ^(TOKEN_REF .) {factory.tokenRef((TerminalAST)$start);}
| TOKEN_REF {factory.tokenRef((TerminalAST)$start);}
| ^(WILDCARD .) {factory.wildcard($start);}
| WILDCARD {factory.wildcard($start);}
| ^(ROOT terminal)
| ^(BANG terminal)
: ^(STRING_LITERAL .) {$p = factory.stringLiteral($start);}
| STRING_LITERAL {$p = factory.stringLiteral($start);}
| ^(TOKEN_REF ARG_ACTION .) {$p = factory.tokenRef((TerminalAST)$start);}
| ^(TOKEN_REF .) {$p = factory.tokenRef((TerminalAST)$start);}
| TOKEN_REF {$p = factory.tokenRef((TerminalAST)$start);}
| ^(WILDCARD .) {$p = factory.wildcard($start);}
| WILDCARD {$p = factory.wildcard($start);}
| ^(ROOT t=terminal) {$p = $t.p;}
| ^(BANG t=terminal) {$p = $t.p;}
;

File diff suppressed because it is too large Load Diff