package project.phase2.ll1parsergenerator.dfastuff; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.util.*; import project.phase2.ll1parsergenerator.dfastuff.IFiniteAutomaton.AcceptLabel; /** * Main running class. */ public class DFABuilderMain { private static final String USAGE = "USAGE: \"java DFABuilderMain lexicalSpecFile [testingFile [outputFile]]\""; /** * This method is the main driving method for the application to demonstrate * its use on a lexical specification and testing file. * * @param args */ public static void main(String[] args) { if (args.length < 1) { System.out.println(USAGE); System.exit(0); } DFABuilderLogger logger = new DFABuilderLogger(); String lexFile = args[0], testFile = null, outFile = null; if (args.length > 1) testFile = args[1]; if (args.length > 2) outFile = args[2]; try { if (outFile != null) { File out = new File(outFile); if (!out.exists()) out.createNewFile(); logger = new DFABuilderLogger(new PrintWriter(out)); } logger.log("-NFA CONSTRUCTION BEGINNING-"); Scanner lexScanner = new Scanner(new File(lexFile)); NFA lex = Parser.parseNFA(lexScanner); logger.log("-NFA CONSTRUCTION COMPLETE-"); logger.log(""); logger.output("NFA Successfully Generated From Specifications"); logger.output("Final NFA Size: " + lex.getStates().size()); logger.log("Final NFA: " + lex); logger.line(); logger.log("-DFA CONSTRUCTION BEGINNING-"); DFA dfa = DFA.fromNFA(lex); logger.log("-DFA CONSTRUCTION COMPLETE-"); logger.log(""); logger.output("DFA Successfully Generated From NFA"); logger.output("Final DFA Size: " + dfa.getStates().size()); logger.log("Final DFA: " + dfa); logger.line(); logger.log("-DFA MINIMIZATION BEGINNING-"); DFA min = dfa.minimize(); logger.log("-DFA MINIMIZATION COMPLETE-"); logger.log(""); logger.output("DFA Successfully Minimized"); logger.output("Final MinDFA Size: " + min.getStates().size()); logger.log("Final MinDFA: " + min); logger.line(); if (testFile != null) { Map<String, Integer> countMap = new HashMap<String, Integer>(); Set<String> failedTok = new HashSet<String>(); int acceptedTokens = 0; int failedTokens = 0; logger.log("-BEGINNING TO TEST INPUT FILE-"); FileReader testReader = new FileReader(new File(testFile)); int currRead; char charRead; AcceptLabel al; String currToken = ""; while ((currRead = testReader.read()) != -1) { charRead = (char) currRead; if (Character.isWhitespace(charRead)) { if (currToken.length() > 0) { al = min.testInput(Arrays.copyOfRange( currToken.split(""), 1, currToken.length() + 1)); if (al.isAccepted()) { logger.log(currToken + " accepted as " + al.getLabel() + "."); acceptedTokens++; if (countMap.get(al.getLabel()) != null) { countMap.put(al.getLabel(), countMap.get(al.getLabel()) + 1); } else { countMap.put(al.getLabel(), 1); } } else { logger.log(currToken + " rejected."); failedTokens++; failedTok.add(currToken); } } currToken = ""; } else { currToken += charRead; } } if (currToken.length() > 0) { al = min.testInput(Arrays.copyOfRange(currToken.split(""), 1, currToken.length() + 1)); if (al.isAccepted()) { logger.log(currToken + " accepted as " + al.getLabel() + "."); acceptedTokens++; if (countMap.get(al.getLabel()) != null) { countMap.put(al.getLabel(), countMap.get(al.getLabel()) + 1); } else { countMap.put(al.getLabel(), 1); } } else { logger.log(currToken + " rejected."); failedTokens++; failedTok.add(currToken); } } logger.log("-COMPLETED TESTING INPUT FILE-"); logger.log(""); logger.output("Input File Completed Testing"); logger.output("Testing Verdict: " + ((failedTokens > 0) ? ("Reject") : ("Accept"))); logger.line(); logger.output("There were " + acceptedTokens + " accepted tokens and " + failedTokens + " rejected tokens in the file, a total of " + (acceptedTokens + failedTokens) + " tokens."); logger.output("Accepted Token Breakdown:"); for (Map.Entry<String, Integer> elt : countMap.entrySet()) { logger.output(elt.getKey() + ": " + elt.getValue()); } logger.line(); logger.output("Rejected Tokens:"); for (String str : failedTok) { logger.output(str); } logger.line(); logger.output("Completed All Requested Operations."); logger.output("If an output file was provided, see it for more detailed output."); } } catch (IOException io) { System.out.println(USAGE); System.out.println(io.getMessage()); io.printStackTrace(); } finally { logger.close(); } } /** * An inner class to be used for output to the STDOut and Output file. This * is implemented as a singleton so any running class can obtain it. */ public static class DFABuilderLogger { /** * The output writer to write to if it is initialized. */ private PrintWriter mOutputWriter = null; /** * Singleton instance so that other running apps can obtain this. */ private static DFABuilderLogger mInstance = null; // // CTOR // private DFABuilderLogger(PrintWriter outputWriter) { mOutputWriter = outputWriter; mInstance = this; } private DFABuilderLogger() { this(null); } public static DFABuilderLogger getInstance() { if (mInstance == null) new DFABuilderLogger(); return mInstance; } public void line() { this.output(""); } public void log(String str) { if (mOutputWriter != null) mOutputWriter.println(str); } public void output(String str) { System.out.println(str); this.log(str); } public void close() { if (mOutputWriter != null) mOutputWriter.close(); } } }