diff --git a/src/main/java/org/sablecc/sablecc/ConstructNFA.java b/src/main/java/org/sablecc/sablecc/ConstructNFA.java index 0ba83abd258cd96e7aaadcd37b8151219d594d93..761ab6a6ab882e8dd20d0065c7a23a74f564411a 100644 --- a/src/main/java/org/sablecc/sablecc/ConstructNFA.java +++ b/src/main/java/org/sablecc/sablecc/ConstructNFA.java @@ -16,81 +16,65 @@ public class ConstructNFA extends DepthFirstAdapter private ResolveIds ids; private String stateName; + private Map<Node, Object> nodeValues; // values are of type CharSet or NFA + private Map<PTokenDef, NFA> nfasByToken; + private NFA fullNFA; + ConstructNFA(ResolveIds ids, String stateName) { this.ids = ids; this.stateName = stateName; - } - - @Override - public void outStart(Start node) - { - setOut(node, getOut(node.getPGrammar())); - // free memory - if(getOut(node.getPGrammar()) != null) - setOut(node.getPGrammar(), null); + this.nodeValues = new HashMap<>(); + this.nfasByToken = new HashMap<>(); + this.fullNFA = null; } - @Override - public void outAGrammar(AGrammar node) - { - setOut(node, getOut(node.getTokens())); - - // free memory - if(getOut(node.getTokens()) != null) - setOut(node.getTokens(), null); + public NFA getNFA() { + return this.fullNFA; } @Override public void outAHelperDef(AHelperDef node) { - setOut(node, getOut(node.getRegExp())); + this.nodeValues.put(node, this.nodeValues.get(node.getRegExp())); // free memory - if(getOut(node.getRegExp()) != null) - setOut(node.getRegExp(), null); + this.nodeValues.remove(node.getRegExp()); } @Override public void outATokens(ATokens node) { ATokenDef[] tokenDefs = (ATokenDef[]) node.getTokenDefs().toArray(new ATokenDef[0]); - NFA result = null; for(int i = tokenDefs.length - 1; i >= 0 ; i--) { - NFA nfa = (NFA) getOut(tokenDefs[i]); + NFA nfa = this.nfasByToken.get(tokenDefs[i]); if(nfa != null) { - if(result == null) + if(fullNFA == null) { - result = nfa; + fullNFA = nfa; } else { - result = nfa.merge(result); + fullNFA = nfa.merge(fullNFA); } // free memory - if(getOut(tokenDefs[i]) != null) - setOut(tokenDefs[i], null); + this.nfasByToken.remove(tokenDefs[i]); } } - - if(result != null) - setOut(node, result); } @Override public void outATokenDef(ATokenDef node) { - Set set - = (Set) getOut(node.getStateList()); - Object o1 = getOut(node.getRegExp()); + Set<String> set = stateNamesFromStateList(node.getStateList()); + Object o1 = this.nodeValues.get(node.getRegExp()); - if((set - == null) || (set.size() == 0) || set.contains(stateName)) + if(set.isEmpty() || set.contains(stateName)) { //System.out.print("*"); @@ -98,7 +82,7 @@ public class ConstructNFA extends DepthFirstAdapter String name = ids.names.get(node); n1.states[n1.states.length - 1].accept = name; - setOut(node, n1); + this.nfasByToken.put(node, n1); } else { @@ -106,17 +90,17 @@ public class ConstructNFA extends DepthFirstAdapter } // free memory - if(getOut(node.getStateList()) != null) - setOut(node.getStateList(), null); - if(getOut(node.getRegExp()) != null) - setOut(node.getRegExp(), null); + this.nodeValues.remove(node.getRegExp()); } - @Override - public void outAStateList(AStateList node) + private static Set<String> stateNamesFromStateList(PStateList stateList) { - Set set - = new TreeSet(); + if (stateList == null) { + return Collections.emptySet(); + } + + final AStateList node = (AStateList)stateList; + Set<String> set = new TreeSet<>(); AStateListTail[] stateListTails = (AStateListTail[]) node.getStateLists().toArray(new AStateListTail[0]); for(int i = stateListTails.length - 1; i >= 0 ; i--) @@ -126,8 +110,7 @@ public class ConstructNFA extends DepthFirstAdapter } set.add(node.getId().getText().toUpperCase()); - setOut(node, set - ); + return set; } @Override @@ -140,7 +123,7 @@ public class ConstructNFA extends DepthFirstAdapter { for(int i = concats.length - 1; i >= 0 ; i--) { - Object o = getOut(concats[i]); + Object o = this.nodeValues.get(concats[i]); NFA nfa = (o instanceof NFA) ? (NFA) o : new NFA((CharSet) o); if(result == null) @@ -153,18 +136,16 @@ public class ConstructNFA extends DepthFirstAdapter } // free memory - if(getOut(concats[i]) != null) - setOut(concats[i], null); + this.nodeValues.remove(concats[i]); } - setOut(node, result); + this.nodeValues.put(node, result); } else if(concats.length == 1) { - setOut(node, getOut(concats[0])); + this.nodeValues.put(node, this.nodeValues.get(concats[0])); // free memory - if(getOut(concats[0]) != null) - setOut(concats[0], null); + this.nodeValues.remove(concats[0]); } } @@ -175,15 +156,14 @@ public class ConstructNFA extends DepthFirstAdapter if(unExps.length == 0) { - setOut(node, new NFA()); + this.nodeValues.put(node, new NFA()); } else if(unExps.length == 1) { - setOut(node, getOut(unExps[0])); + this.nodeValues.put(node, this.nodeValues.get(unExps[0])); // free memory - if(getOut(unExps[0]) != null) - setOut(unExps[0], null); + this.nodeValues.remove(unExps[0]); } else { @@ -191,7 +171,7 @@ public class ConstructNFA extends DepthFirstAdapter for(int i = unExps.length - 1; i >= 0 ; i--) { - Object o = getOut(unExps[i]); + Object o = this.nodeValues.get(unExps[i]); NFA nfa = (o instanceof NFA) ? (NFA) o : new NFA((CharSet) o); if(result == null) @@ -204,76 +184,56 @@ public class ConstructNFA extends DepthFirstAdapter } // free memory - if(getOut(unExps[i]) != null) - setOut(unExps[i], null); + this.nodeValues.remove(unExps[i]); } - setOut(node, result); + this.nodeValues.put(node, result); } } @Override public void outAUnExp(AUnExp node) { - Object o = getOut(node.getBasic()); - - char c = ' '; - if(node.getUnOp() != null) - c = ((Character) getOut(node.getUnOp())).charValue(); + Object o = this.nodeValues.get(node.getBasic()); - switch(c) + if(node.getUnOp() instanceof AStarUnOp) { - case '*': - { - NFA n = (o instanceof NFA) ? (NFA) o : new NFA((CharSet) o); - setOut(node, n.zeroOrMore()); - } - break; - case '?': - { - NFA n = (o instanceof NFA) ? (NFA) o : new NFA((CharSet) o); - setOut(node, n.zeroOrOne()); - } - break; - case '+': - { - NFA n = (o instanceof NFA) ? (NFA) o : new NFA((CharSet) o); - setOut(node, n.oneOrMore()); - } - break; - default: - { - setOut(node, o); - } - break; + NFA n = (o instanceof NFA) ? (NFA) o : new NFA((CharSet) o); + this.nodeValues.put(node, n.zeroOrMore()); + } + else if(node.getUnOp() instanceof AQMarkUnOp) + { + NFA n = (o instanceof NFA) ? (NFA) o : new NFA((CharSet) o); + this.nodeValues.put(node, n.zeroOrOne()); + } + else if(node.getUnOp() instanceof APlusUnOp) + { + NFA n = (o instanceof NFA) ? (NFA) o : new NFA((CharSet) o); + this.nodeValues.put(node, n.oneOrMore()); + } + else + { + this.nodeValues.put(node, o); } // free memory - if(getOut(node.getBasic()) != null) - setOut(node.getBasic(), null); - if(getOut(node.getUnOp()) != null) - setOut(node.getUnOp(), null); + this.nodeValues.remove(node.getBasic()); } @Override public void outACharBasic(ACharBasic node) { - char c = ((Character) getOut(node.getChar())).charValue(); - setOut(node, new CharSet(c)); - - // free memory - if(getOut(node.getChar()) != null) - setOut(node.getChar(), null); + char c = charValue(node.getChar()); + this.nodeValues.put(node, new CharSet(c)); } @Override public void outASetBasic(ASetBasic node) { - setOut(node, getOut(node.getSet())); + this.nodeValues.put(node, this.nodeValues.get(node.getSet())); // free memory - if(getOut(node.getSet()) != null) - setOut(node.getSet(), null); + this.nodeValues.remove(node.getSet()); } @Override @@ -282,50 +242,50 @@ public class ConstructNFA extends DepthFirstAdapter String s = node.getString().getText(); s = s.substring(1, s.length() -1); - setOut(node, new NFA(s)); + this.nodeValues.put(node, new NFA(s)); } @Override public void outAIdBasic(AIdBasic node) { - Object o = getOut(ids.helpers.get(node.getId().getText())); + Object o = this.nodeValues.get(ids.helpers.get(node.getId().getText())); if(o instanceof NFA) { - setOut(node, ((NFA) o).clone()); + this.nodeValues.put(node, ((NFA) o).clone()); } else { - setOut(node, ((CharSet) o).clone()); + this.nodeValues.put(node, ((CharSet) o).clone()); } } @Override public void outARegExpBasic(ARegExpBasic node) { - setOut(node, getOut(node.getRegExp())); + this.nodeValues.put(node, this.nodeValues.get(node.getRegExp())); // free memory - if(getOut(node.getRegExp()) != null) - setOut(node.getRegExp(), null); - } - - @Override - public void outACharChar(ACharChar node) - { - setOut(node, node.getChar().getText().charAt(1)); - } - - @Override - public void outADecChar(ADecChar node) - { - setOut(node, (char)Integer.parseInt(node.getDecChar().getText())); + this.nodeValues.remove(node.getRegExp()); } - @Override - public void outAHexChar(AHexChar node) - { - setOut(node, (char)Integer.parseInt(node.getHexChar().getText().substring(2), 16)); + private static char charValue(final PChar node) { + if(node instanceof ACharChar) + { + return ((ACharChar)node).getChar().getText().charAt(1); + } + else if(node instanceof ADecChar) + { + return (char)Integer.parseInt(((ADecChar)node).getDecChar().getText()); + } + else if(node instanceof AHexChar) + { + return (char)Integer.parseInt(((AHexChar)node).getHexChar().getText().substring(2), 16); + } + else + { + throw new IllegalArgumentException("Unhandled char type: " + node.getClass()); + } } @Override @@ -333,22 +293,16 @@ public class ConstructNFA extends DepthFirstAdapter { try { - CharSet cs1 = (CharSet) getOut(node.getLeft()); - CharSet cs2 = (CharSet) getOut(node.getRight()); - char binop = (Character) getOut(node.getBinOp()); + CharSet cs1 = (CharSet) this.nodeValues.get(node.getLeft()); + CharSet cs2 = (CharSet) this.nodeValues.get(node.getRight()); - switch(binop) + if(node.getBinOp() instanceof APlusBinOp) { - case '+': - { - setOut(node, cs1.union(cs2)); - } - break; - case '-': - { - setOut(node, cs1.diff(cs2)); - } - break; + this.nodeValues.put(node, cs1.union(cs2)); + } + else if(node.getBinOp() instanceof AMinusBinOp) + { + this.nodeValues.put(node, cs1.diff(cs2)); } } catch(Exception e) @@ -357,84 +311,22 @@ public class ConstructNFA extends DepthFirstAdapter } // free memory - if(getOut(node.getLeft()) != null) - setOut(node.getLeft(), null); - if(getOut(node.getBinOp()) != null) - setOut(node.getBinOp(), null); - if(getOut(node.getRight()) != null) - setOut(node.getRight(), null); + this.nodeValues.remove(node.getLeft()); + this.nodeValues.remove(node.getRight()); } @Override public void outAIntervalSet(AIntervalSet node) { - char c1 = ((Character) getOut(node.getLeft())).charValue(); - char c2 = ((Character) getOut(node.getRight())).charValue(); + char c1 = charValue(node.getLeft()); + char c2 = charValue(node.getRight()); if(c1 > c2) { throw new RuntimeException(node + " is invalid."); } - setOut(node, new CharSet(c1, c2)); - - // free memory - if(getOut(node.getLeft()) != null) - setOut(node.getLeft(), null); - if(getOut(node.getRight()) != null) - setOut(node.getRight(), null); - } - - @Override - public void outAStarUnOp(AStarUnOp node) - { - setOut(node, '*'); - } - - @Override - public void outAQMarkUnOp(AQMarkUnOp node) - { - setOut(node, '?'); - } - - @Override - public void outAPlusUnOp(APlusUnOp node) - { - setOut(node, '+'); - } - - @Override - public void outAPlusBinOp(APlusBinOp node) - { - setOut(node, '+'); - } - - @Override - public void outAMinusBinOp(AMinusBinOp node) - { - setOut(node, '-'); - } - - @Override - public Object getOut(Node node) - { - if(node == null) - { - return null; - } - - return super.getOut(node); - } - - @Override - public void setOut(Node node, Object out) - { - if(node == null) - { - throw new NullPointerException(); - } - - super.setOut(node, out); + this.nodeValues.put(node, new CharSet(c1, c2)); } } diff --git a/src/main/java/org/sablecc/sablecc/GenLexer.java b/src/main/java/org/sablecc/sablecc/GenLexer.java index 7aa607bcfaf9a7be7de12f8142e32367f64f0479..c72a0b4ce5224c9dadc1227f585f92992d0462e3 100644 --- a/src/main/java/org/sablecc/sablecc/GenLexer.java +++ b/src/main/java/org/sablecc/sablecc/GenLexer.java @@ -81,7 +81,7 @@ public class GenLexer extends AnalysisAdapter tree.apply(nfaConstructor); System.out.println(); - NFA nfa = (NFA) nfaConstructor.getOut(tree); + NFA nfa = nfaConstructor.getNFA(); nfaConstructor = null; System.out.println(" - Constructing DFA.");