From afe31a858a3d0a287cee91ef4f7e226bcecae161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Wed, 10 Oct 2018 19:24:34 +0200 Subject: [PATCH 1/6] Split Main in Main and LexGenerator. This is a minor refactoring to support refacotring #214 In the future, LexGenerator.generate() will not be static and have internal state in order to support multithreading. --- jflex/src/main/java/jflex/LexGenerator.java | 131 ++++++++++++++++++++ jflex/src/main/java/jflex/Main.java | 112 +---------------- 2 files changed, 136 insertions(+), 107 deletions(-) create mode 100644 jflex/src/main/java/jflex/LexGenerator.java diff --git a/jflex/src/main/java/jflex/LexGenerator.java b/jflex/src/main/java/jflex/LexGenerator.java new file mode 100644 index 000000000..265ec066a --- /dev/null +++ b/jflex/src/main/java/jflex/LexGenerator.java @@ -0,0 +1,131 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * JFlex 1.7.1-SNAPSHOT * + * Copyright (C) 1998-2018 Gerwin Klein * + * All rights reserved. * + * * + * License: BSD * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +package jflex; + +import static jflex.Options.encoding; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.file.Files; +import java.nio.file.Paths; + +/** + * This is the main class of JFlex controlling the scanner generation process. It is responsible for + * parsing the commandline, getting input files, starting up the GUI if necessary, etc. + * + * @author Gerwin Klein + * @author Régis Décamps + * @version JFlex 1.7.1-SNAPSHOT + */ +public class LexGenerator { + + /** JFlex version */ + public static final String version = "1.7.1-SNAPSHOT"; // $NON-NLS-1$ + + /** + * 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; + Reader inputReader = null; + + totalTime.start(); + + try { + Out.println(ErrorMessages.READING, inputFile.toString()); + inputReader = + new InputStreamReader(Files.newInputStream(Paths.get(inputFile.toString())), encoding); + scanner = new LexScan(inputReader); + scanner.setFile(inputFile); + parser = new LexParse(scanner); + } catch (IOException 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(); + } + } +} diff --git a/jflex/src/main/java/jflex/Main.java b/jflex/src/main/java/jflex/Main.java index ea1ce4ce8..ea932b437 100644 --- a/jflex/src/main/java/jflex/Main.java +++ b/jflex/src/main/java/jflex/Main.java @@ -10,18 +10,12 @@ package jflex; import static jflex.ErrorMessages.NO_ENCODING; -import static jflex.Options.encoding; import static jflex.Options.setEncoding; import static jflex.Options.unused_warning; import static jflex.Out.error; import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; import java.lang.reflect.Field; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -48,104 +42,6 @@ public class Main { /** JFlex version */ public static final String version = "1.7.1-SNAPSHOT"; // $NON-NLS-1$ - /** - * 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; - Reader inputReader = null; - - totalTime.start(); - - try { - Out.println(ErrorMessages.READING, inputFile.toString()); - inputReader = - new InputStreamReader(Files.newInputStream(Paths.get(inputFile.toString())), encoding); - scanner = new LexScan(inputReader); - scanner.setFile(inputFile); - parser = new LexParse(scanner); - } catch (IOException 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(); - } - } - /** * parseOptions. * @@ -153,7 +49,7 @@ public static void generate(File inputFile) { * @return a {@link java.util.List} object. * @throws jflex.SilentExit if any. */ - public static List parseOptions(String argv[]) throws SilentExit { + private static List parseOptions(String argv[]) throws SilentExit { List files = new ArrayList<>(); for (int i = 0; i < argv.length; i++) { @@ -377,7 +273,7 @@ private static void printUnicodePropertyValuesAndAliases(String unicodeVersion) } /** Prints the cli usage on stdout. */ - public static void printUsage() { + private static void printUsage() { Out.println(""); // $NON-NLS-1$ Out.println("Usage: jflex "); Out.println(""); @@ -418,7 +314,9 @@ public static void generate(String argv[]) throws SilentExit { List files = parseOptions(argv); if (files.size() > 0) { - for (File file : files) generate(file); + for (File file : files) { + LexGenerator.generate(file); + } } else { new MainFrame(); } From 939d6c651dedd62ca2cfbaa53b0fa2e11c58b6d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Wed, 10 Oct 2018 19:30:35 +0200 Subject: [PATCH 2/6] Make Main non instanciable. --- jflex/src/main/java/jflex/LexGenerator.java | 2 +- jflex/src/main/java/jflex/Main.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jflex/src/main/java/jflex/LexGenerator.java b/jflex/src/main/java/jflex/LexGenerator.java index 265ec066a..d9107356a 100644 --- a/jflex/src/main/java/jflex/LexGenerator.java +++ b/jflex/src/main/java/jflex/LexGenerator.java @@ -29,7 +29,7 @@ public class LexGenerator { /** JFlex version */ - public static final String version = "1.7.1-SNAPSHOT"; // $NON-NLS-1$ + public static final String VERSION = "1.7.1-SNAPSHOT"; // $NON-NLS-1$ /** * Generates a scanner for the specified input file. diff --git a/jflex/src/main/java/jflex/Main.java b/jflex/src/main/java/jflex/Main.java index ea932b437..2bb749d34 100644 --- a/jflex/src/main/java/jflex/Main.java +++ b/jflex/src/main/java/jflex/Main.java @@ -39,9 +39,6 @@ */ public class Main { - /** JFlex version */ - public static final String version = "1.7.1-SNAPSHOT"; // $NON-NLS-1$ - /** * parseOptions. * @@ -133,7 +130,7 @@ private static List parseOptions(String argv[]) throws SilentExit { if (Objects.equals(argv[i], "--version") || Objects.equals(argv[i], "-version")) { // $NON-NLS-1$ //$NON-NLS-2$ - Out.println(ErrorMessages.THIS_IS_JFLEX, version); + Out.println(ErrorMessages.THIS_IS_JFLEX, LexGenerator.VERSION); throw new SilentExit(0); } @@ -300,7 +297,7 @@ private static void printUsage() { Out.println("--help"); Out.println("-h print this message"); Out.println(""); - Out.println(ErrorMessages.THIS_IS_JFLEX, version); + Out.println(ErrorMessages.THIS_IS_JFLEX, LexGenerator.VERSION); Out.println("Have a nice day!"); } @@ -338,4 +335,7 @@ public static void main(String argv[]) { System.exit(e.exitCode()); } } + + // Only CLI, not meant for instanciation. + private Main() {} } From f37dc625c99b655eb01f81c9a9293dc0d5de2b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Wed, 10 Oct 2018 19:36:45 +0200 Subject: [PATCH 3/6] Adapt code to refactoring. --- .../src/main/java/de/jflex/plugin/maven/JFlexMojo.java | 4 ++-- jflex/src/main/java/jflex/Emitter.java | 2 +- jflex/src/main/java/jflex/Out.java | 2 +- jflex/src/main/java/jflex/anttask/JFlexTask.java | 4 ++-- jflex/src/main/java/jflex/gui/GeneratorThread.java | 4 ++-- jflex/src/main/java/jflex/gui/MainFrame.java | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/jflex-maven-plugin/src/main/java/de/jflex/plugin/maven/JFlexMojo.java b/jflex-maven-plugin/src/main/java/de/jflex/plugin/maven/JFlexMojo.java index c0efc382e..c81418b61 100644 --- a/jflex-maven-plugin/src/main/java/de/jflex/plugin/maven/JFlexMojo.java +++ b/jflex-maven-plugin/src/main/java/de/jflex/plugin/maven/JFlexMojo.java @@ -21,7 +21,7 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -import jflex.Main; +import jflex.LexGenerator; import jflex.Options; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; @@ -235,7 +235,7 @@ private void parseLexFile(File lexFile) throws MojoFailureException, MojoExecuti } try { - Main.generate(lexFile); + LexGenerator.generate(lexFile); getLog().info(" generated " + generatedFile); } catch (Exception e) { throw new MojoExecutionException(e.getMessage(), e); diff --git a/jflex/src/main/java/jflex/Emitter.java b/jflex/src/main/java/jflex/Emitter.java index 81b1869ce..630b2b533 100644 --- a/jflex/src/main/java/jflex/Emitter.java +++ b/jflex/src/main/java/jflex/Emitter.java @@ -408,7 +408,7 @@ private void emitNextInput() { private void emitHeader() { println("// DO NOT EDIT"); - println("// Generated by JFlex " + Main.version + " http://jflex.de/"); + println("// Generated by JFlex " + LexGenerator.VERSION + " http://jflex.de/"); String path = FileUtil.getRelativePath(Options.getRootDirectory(), inputFile); if (File.separatorChar == '\\') { path = FileUtil.slashify(path); diff --git a/jflex/src/main/java/jflex/Out.java b/jflex/src/main/java/jflex/Out.java index d610c9b87..be6a69b8c 100644 --- a/jflex/src/main/java/jflex/Out.java +++ b/jflex/src/main/java/jflex/Out.java @@ -403,7 +403,7 @@ public static void printSystemInfo() { err("OS version: " + System.getProperty("os.version")); err("Encoding: " + System.getProperty("file.encoding")); err("Unicode versions: " + UnicodeProperties.UNICODE_VERSIONS); - err("JFlex version: " + Main.version); + err("JFlex version: " + LexGenerator.VERSION); } /** diff --git a/jflex/src/main/java/jflex/anttask/JFlexTask.java b/jflex/src/main/java/jflex/anttask/JFlexTask.java index ccc9c2bc7..8b70bc4b7 100644 --- a/jflex/src/main/java/jflex/anttask/JFlexTask.java +++ b/jflex/src/main/java/jflex/anttask/JFlexTask.java @@ -16,7 +16,7 @@ import java.io.LineNumberReader; import java.util.regex.Matcher; import java.util.regex.Pattern; -import jflex.Main; +import jflex.LexGenerator; import jflex.Options; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; @@ -69,7 +69,7 @@ public void execute() throws BuildException { File destFile = new File(outputDir, className + ".java"); if (inputFile.lastModified() > destFile.lastModified()) { - Main.generate(inputFile); + LexGenerator.generate(inputFile); if (!Options.verbose) System.out.println("Generated: " + destFile.getName()); } } catch (IOException e1) { diff --git a/jflex/src/main/java/jflex/gui/GeneratorThread.java b/jflex/src/main/java/jflex/gui/GeneratorThread.java index 939e706f7..40e1e9376 100644 --- a/jflex/src/main/java/jflex/gui/GeneratorThread.java +++ b/jflex/src/main/java/jflex/gui/GeneratorThread.java @@ -13,7 +13,7 @@ import java.util.Objects; import jflex.ErrorMessages; import jflex.GeneratorException; -import jflex.Main; +import jflex.LexGenerator; import jflex.Options; import jflex.Out; @@ -62,7 +62,7 @@ public void run() { if (!Objects.equals(outputDir, "")) { Options.setDir(outputDir); } - Main.generate(new File(inputFile)); + LexGenerator.generate(new File(inputFile)); Out.statistics(); parent.generationFinished(true); } catch (GeneratorException e) { diff --git a/jflex/src/main/java/jflex/gui/MainFrame.java b/jflex/src/main/java/jflex/gui/MainFrame.java index 7dd12986d..9ec5181d4 100644 --- a/jflex/src/main/java/jflex/gui/MainFrame.java +++ b/jflex/src/main/java/jflex/gui/MainFrame.java @@ -17,7 +17,7 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; -import jflex.Main; +import jflex.LexGenerator; import jflex.Out; /** @@ -53,7 +53,7 @@ public final class MainFrame extends Frame implements Handles { /** Constructor for MainFrame. */ public MainFrame() { - super("JFlex " + Main.version); + super("JFlex " + LexGenerator.VERSION); buildContent(); addWindowListener( From 5d63d4eb662e765a892e3b64182c7193a10b6668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Thu, 11 Oct 2018 00:09:10 +0200 Subject: [PATCH 4/6] Update javadoc --- jflex/src/main/java/jflex/LexGenerator.java | 3 +-- jflex/src/main/java/jflex/Main.java | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/jflex/src/main/java/jflex/LexGenerator.java b/jflex/src/main/java/jflex/LexGenerator.java index d9107356a..41b7d759e 100644 --- a/jflex/src/main/java/jflex/LexGenerator.java +++ b/jflex/src/main/java/jflex/LexGenerator.java @@ -19,8 +19,7 @@ import java.nio.file.Paths; /** - * This is the main class of JFlex controlling the scanner generation process. It is responsible for - * parsing the commandline, getting input files, starting up the GUI if necessary, etc. + * This is the generator of JFlex, controlling the scanner generation process. * * @author Gerwin Klein * @author Régis Décamps diff --git a/jflex/src/main/java/jflex/Main.java b/jflex/src/main/java/jflex/Main.java index 2bb749d34..7ea79a449 100644 --- a/jflex/src/main/java/jflex/Main.java +++ b/jflex/src/main/java/jflex/Main.java @@ -30,8 +30,10 @@ import jflex.unicode.UnicodeProperties; /** - * This is the main class of JFlex controlling the scanner generation process. It is responsible for - * parsing the commandline, getting input files, starting up the GUI if necessary, etc. + * This is the command-line interface. + * + *

It is responsible for parsing the commandline, getting input files, starting up the GUI if + * necessary, etc. and invokes {@link LexGenerator} accordingly. * * @author Gerwin Klein * @author Régis Décamps From 5d7ae8cce7cbdda0f46c63b3c825fa95fd6c07b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Thu, 11 Oct 2018 00:16:32 +0200 Subject: [PATCH 5/6] Remove hack to fetch cup.jar in the ant build. --- scripts/mk-release.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/mk-release.sh b/scripts/mk-release.sh index 77021a82d..a2ee98cb2 100755 --- a/scripts/mk-release.sh +++ b/scripts/mk-release.sh @@ -3,9 +3,6 @@ # fail on error set -e -# a hack for enabling ant builds outside the repo until we figure out something better -CUP_URL="https://raw.githubusercontent.com/jflex-de/jflex/05632859c94c348dee7d243e4a36bd656c132e96/cup/cup/java-cup-11b.jar" - VERSION="1.7.1-SNAPSHOT" JFLEX_JAR="jflex-full-$VERSION.jar" @@ -44,9 +41,6 @@ echo "------[ Packaging jflex ]" cp ../../pom.xml parent.xml perl -pi -e "s|../pom.xml|parent.xml|" pom.xml -# hack for ant build outside repo -perl -pi -e "s|||" build.xml - # build things "$MVN" package From 84a4c63cd4ac672319b519a0fe69809b11e95430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20D=C3=A9camps?= Date: Thu, 11 Oct 2018 00:18:48 +0200 Subject: [PATCH 6/6] Revert "Remove hack to fetch cup.jar in the ant build." This reverts commit 5d7ae8cce7cbdda0f46c63b3c825fa95fd6c07b4. Wrong branch --- scripts/mk-release.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/mk-release.sh b/scripts/mk-release.sh index a2ee98cb2..77021a82d 100755 --- a/scripts/mk-release.sh +++ b/scripts/mk-release.sh @@ -3,6 +3,9 @@ # fail on error set -e +# a hack for enabling ant builds outside the repo until we figure out something better +CUP_URL="https://raw.githubusercontent.com/jflex-de/jflex/05632859c94c348dee7d243e4a36bd656c132e96/cup/cup/java-cup-11b.jar" + VERSION="1.7.1-SNAPSHOT" JFLEX_JAR="jflex-full-$VERSION.jar" @@ -41,6 +44,9 @@ echo "------[ Packaging jflex ]" cp ../../pom.xml parent.xml perl -pi -e "s|../pom.xml|parent.xml|" pom.xml +# hack for ant build outside repo +perl -pi -e "s|||" build.xml + # build things "$MVN" package