@Override public void outAConcat(AConcat node) { AUnExp[] unExps = (AUnExp[]) node.getUnExps().toArray(new AUnExp[0]); if (unExps.length == 0) { setOut(node, new NFA()); } else if (unExps.length == 1) { setOut(node, getOut(unExps[0])); // free memory if (getOut(unExps[0]) != null) setOut(unExps[0], null); } else { NFA result = null; for (int i = unExps.length - 1; i >= 0; i--) { Object o = getOut(unExps[i]); NFA nfa = (o instanceof NFA) ? (NFA) o : new NFA((CharSet) o); if (result == null) { result = nfa; } else { result = nfa.concatenate(result); } // free memory if (getOut(unExps[i]) != null) setOut(unExps[i], null); } setOut(node, result); } }
@Override public void outARegExp(ARegExp node) { AConcat[] concats = (AConcat[]) node.getConcats().toArray(new AConcat[0]); NFA result = null; if (concats.length > 1) { for (int i = concats.length - 1; i >= 0; i--) { Object o = getOut(concats[i]); NFA nfa = (o instanceof NFA) ? (NFA) o : new NFA((CharSet) o); if (result == null) { result = nfa; } else { result = nfa.alternate(result); } // free memory if (getOut(concats[i]) != null) setOut(concats[i], null); } setOut(node, result); } else if (concats.length == 1) { setOut(node, getOut(concats[0])); // free memory if (getOut(concats[0]) != null) setOut(concats[0], null); } }
@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]); if (nfa != null) { if (result == null) { result = nfa; } else { result = nfa.merge(result); } // free memory if (getOut(tokenDefs[i]) != null) setOut(tokenDefs[i], null); } } if (result != null) setOut(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(); switch (c) { 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; } // free memory if (getOut(node.getBasic()) != null) setOut(node.getBasic(), null); if (getOut(node.getUnOp()) != null) setOut(node.getUnOp(), null); }
/** * Generates a scanner for the specified input file. * * @param inputFile a file containing a lexical specification to generate a scanner for. */ public static void generate(File inputFile) { Out.resetCounters(); Timer totalTime = new Timer(); Timer time = new Timer(); LexScan scanner = null; LexParse parser = null; FileReader inputReader = null; totalTime.start(); try { Out.println(ErrorMessages.READING, inputFile.toString()); inputReader = new FileReader(inputFile); scanner = new LexScan(inputReader); scanner.setFile(inputFile); parser = new LexParse(scanner); } catch (FileNotFoundException e) { Out.error(ErrorMessages.CANNOT_OPEN, inputFile.toString()); throw new GeneratorException(); } try { NFA nfa = (NFA) parser.parse().value; Out.checkErrors(); if (Options.dump) Out.dump(ErrorMessages.get(ErrorMessages.NFA_IS) + Out.NL + nfa + Out.NL); if (Options.dot) nfa.writeDot(Emitter.normalize("nfa.dot", null)); // $NON-NLS-1$ Out.println(ErrorMessages.NFA_STATES, nfa.numStates); time.start(); DFA dfa = nfa.getDFA(); time.stop(); Out.time(ErrorMessages.DFA_TOOK, time); dfa.checkActions(scanner, parser); nfa = null; if (Options.dump) Out.dump(ErrorMessages.get(ErrorMessages.DFA_IS) + Out.NL + dfa + Out.NL); if (Options.dot) dfa.writeDot(Emitter.normalize("dfa-big.dot", null)); // $NON-NLS-1$ Out.checkErrors(); time.start(); dfa.minimize(); time.stop(); Out.time(ErrorMessages.MIN_TOOK, time); if (Options.dump) Out.dump(ErrorMessages.get(ErrorMessages.MIN_DFA_IS) + Out.NL + dfa); if (Options.dot) dfa.writeDot(Emitter.normalize("dfa-min.dot", null)); // $NON-NLS-1$ time.start(); Emitter e = new Emitter(inputFile, parser, dfa); e.emit(); time.stop(); Out.time(ErrorMessages.WRITE_TOOK, time); totalTime.stop(); Out.time(ErrorMessages.TOTAL_TIME, totalTime); } catch (ScannerException e) { Out.error(e.file, e.message, e.line, e.column); throw new GeneratorException(); } catch (MacroException e) { Out.error(e.getMessage()); throw new GeneratorException(); } catch (IOException e) { Out.error(ErrorMessages.IO_ERROR, e.toString()); throw new GeneratorException(); } catch (OutOfMemoryError e) { Out.error(ErrorMessages.OUT_OF_MEMORY); throw new GeneratorException(); } catch (GeneratorException e) { throw new GeneratorException(); } catch (Exception e) { e.printStackTrace(); throw new GeneratorException(); } }
// Calculates the start state of the DFA private void findStart(NFA nfa) { DFAState dummy = new DFAState("", false, new HashSet<State>(), new HashMap<String, DFAState>()); dummy.addState(nfa.getStart()); start = closure(dummy); }