diff --git a/runtime/Java/pom.xml b/runtime/Java/pom.xml index 918673472..3ae405e3e 100644 --- a/runtime/Java/pom.xml +++ b/runtime/Java/pom.xml @@ -11,14 +11,6 @@ ANTLR 4 Runtime The ANTLR 4 Runtime - - - org.abego.treelayout - org.abego.treelayout.core - 1.0.1 - - - src @@ -38,7 +30,7 @@ - + org.apache.felix maven-bundle-plugin 2.5.4 @@ -46,7 +38,7 @@ bundle-manifest process-classes - + org.antlr.antlr4-runtime-osgi ANTLR 4 Runtime @@ -55,37 +47,21 @@ ${project.version} - + manifest - + - + maven-jar-plugin 2.4 - + ${project.build.outputDirectory}/META-INF/MANIFEST.MF - + - - org.apache.maven.plugins - maven-shade-plugin - 2.3 - - - package - - ${project.build.directory}/dependency-reduced-pom.xml - - - shade - - - - diff --git a/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java b/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java index d2f9ea70e..6cde47e67 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java @@ -34,7 +34,6 @@ import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTreeVisitor; import org.antlr.v4.runtime.tree.RuleNode; import org.antlr.v4.runtime.tree.Trees; -import org.antlr.v4.runtime.tree.gui.TreeViewer; import javax.print.PrintException; import javax.swing.*; @@ -183,49 +182,6 @@ public class RuleContext implements RuleNode { @Override public T accept(ParseTreeVisitor visitor) { return visitor.visitChildren(this); } - /** Call this method to view a parse tree in a dialog box visually. */ - public Future inspect(Parser parser) { - List ruleNames = parser != null ? Arrays.asList(parser.getRuleNames()) : null; - return inspect(ruleNames); - } - - public Future inspect(List ruleNames) { - TreeViewer viewer = new TreeViewer(ruleNames, this); - return viewer.open(); - } - - /** Save this tree in a postscript file */ - public void save(Parser parser, String fileName) - throws IOException, PrintException - { - List ruleNames = parser != null ? Arrays.asList(parser.getRuleNames()) : null; - save(ruleNames, fileName); - } - - /** Save this tree in a postscript file using a particular font name and size */ - public void save(Parser parser, String fileName, - String fontName, int fontSize) - throws IOException - { - List ruleNames = parser != null ? Arrays.asList(parser.getRuleNames()) : null; - save(ruleNames, fileName, fontName, fontSize); - } - - /** Save this tree in a postscript file */ - public void save(List ruleNames, String fileName) - throws IOException, PrintException - { - Trees.writePS(this, ruleNames, fileName); - } - - /** Save this tree in a postscript file using a particular font name and size */ - public void save(List ruleNames, String fileName, - String fontName, int fontSize) - throws IOException - { - Trees.writePS(this, ruleNames, fileName, fontName, fontSize); - } - /** Print out a whole tree, not just a node, in LISP format * (root child1 .. childN). Print just a node if this is a leaf. * We have to know the recognizer so we can get rule names. diff --git a/runtime/Java/src/org/antlr/v4/runtime/misc/TestRig.java b/runtime/Java/src/org/antlr/v4/runtime/misc/TestRig.java index 6c35a9028..9f656fea5 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/misc/TestRig.java +++ b/runtime/Java/src/org/antlr/v4/runtime/misc/TestRig.java @@ -1,270 +1,29 @@ -/* - * [The "BSD license"] - * Copyright (c) 2012 Terence Parr - * Copyright (c) 2012 Sam Harwell - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - package org.antlr.v4.runtime.misc; -import org.antlr.v4.runtime.ANTLRInputStream; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.DiagnosticErrorListener; -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.atn.PredictionMode; - -import javax.print.PrintException; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -/** Run a lexer/parser combo, optionally printing tree string or generating - * postscript file. Optionally taking input file. +/** A proxy for the real org.antlr.v4.gui.TestRig that we moved to tool + * artifact from runtime. * - * $ java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName - * [-tree] - * [-tokens] [-gui] [-ps file.ps] - * [-trace] - * [-diagnostics] - * [-SLL] - * [input-filename(s)] + * @deprecated + * @since 4.5.1 */ public class TestRig { - public static final String LEXER_START_RULE_NAME = "tokens"; - - protected String grammarName; - protected String startRuleName; - protected final List inputFiles = new ArrayList(); - protected boolean printTree = false; - protected boolean gui = false; - protected String psFile = null; - protected boolean showTokens = false; - protected boolean trace = false; - protected boolean diagnostics = false; - protected String encoding = null; - protected boolean SLL = false; - - public TestRig(String[] args) throws Exception { - if ( args.length < 2 ) { - System.err.println("java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName\n" + - " [-tokens] [-tree] [-gui] [-ps file.ps] [-encoding encodingname]\n" + - " [-trace] [-diagnostics] [-SLL]\n"+ - " [input-filename(s)]"); - System.err.println("Use startRuleName='tokens' if GrammarName is a lexer grammar."); - System.err.println("Omitting input-filename makes rig read from stdin."); - return; - } - int i=0; - grammarName = args[i]; - i++; - startRuleName = args[i]; - i++; - while ( i=args.length ) { - System.err.println("missing encoding on -encoding"); - return; - } - encoding = args[i]; - i++; - } - else if ( arg.equals("-ps") ) { - if ( i>=args.length ) { - System.err.println("missing filename on -ps"); - return; - } - psFile = args[i]; - i++; - } - } - } - - public static void main(String[] args) throws Exception { - TestRig testRig = new TestRig(args); - if(args.length >= 2) { - testRig.process(); - } - } - - public void process() throws Exception { -// System.out.println("exec "+grammarName+"."+startRuleName); - String lexerName = grammarName+"Lexer"; - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - Class lexerClass = null; + public static void main(String[] args) { try { - lexerClass = cl.loadClass(lexerName).asSubclass(Lexer.class); - } - catch (java.lang.ClassNotFoundException cnfe) { - // might be pure lexer grammar; no Lexer suffix then - lexerName = grammarName; + Class testRigClass = Class.forName("org.antlr.v4.gui.TestRig"); + System.err.println("Warning: TestRig moved to org.antlr.v4.gui.TestRig; calling automatically"); try { - lexerClass = cl.loadClass(lexerName).asSubclass(Lexer.class); + Method mainMethod = testRigClass.getMethod("main", String[].class); + mainMethod.invoke(null, (Object)args); } - catch (ClassNotFoundException cnfe2) { - System.err.println("Can't load "+lexerName+" as lexer or parser"); - return; + catch (Exception nsme) { + System.err.println("Problems calling org.antlr.v4.gui.TestRig.main(args)"); } } - - Constructor lexerCtor = lexerClass.getConstructor(CharStream.class); - Lexer lexer = lexerCtor.newInstance((CharStream)null); - - Class parserClass = null; - Parser parser = null; - if ( !startRuleName.equals(LEXER_START_RULE_NAME) ) { - String parserName = grammarName+"Parser"; - parserClass = cl.loadClass(parserName).asSubclass(Parser.class); - if ( parserClass==null ) { - System.err.println("Can't load "+parserName); - } - Constructor parserCtor = parserClass.getConstructor(TokenStream.class); - parser = parserCtor.newInstance((TokenStream)null); - } - - if ( inputFiles.size()==0 ) { - InputStream is = System.in; - Reader r; - if ( encoding!=null ) { - r = new InputStreamReader(is, encoding); - } - else { - r = new InputStreamReader(is); - } - - process(lexer, parserClass, parser, is, r); - return; - } - for (String inputFile : inputFiles) { - InputStream is = System.in; - if ( inputFile!=null ) { - is = new FileInputStream(inputFile); - } - Reader r; - if ( encoding!=null ) { - r = new InputStreamReader(is, encoding); - } - else { - r = new InputStreamReader(is); - } - - if ( inputFiles.size()>1 ) { - System.err.println(inputFile); - } - process(lexer, parserClass, parser, is, r); - } - } - - protected void process(Lexer lexer, Class parserClass, Parser parser, InputStream is, Reader r) throws IOException, IllegalAccessException, InvocationTargetException, PrintException { - try { - ANTLRInputStream input = new ANTLRInputStream(r); - lexer.setInputStream(input); - CommonTokenStream tokens = new CommonTokenStream(lexer); - - tokens.fill(); - - if ( showTokens ) { - for (Object tok : tokens.getTokens()) { - System.out.println(tok); - } - } - - if ( startRuleName.equals(LEXER_START_RULE_NAME) ) return; - - if ( diagnostics ) { - parser.addErrorListener(new DiagnosticErrorListener()); - parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION); - } - - if ( printTree || gui || psFile!=null ) { - parser.setBuildParseTree(true); - } - - if ( SLL ) { // overrides diagnostics - parser.getInterpreter().setPredictionMode(PredictionMode.SLL); - } - - parser.setTokenStream(tokens); - parser.setTrace(trace); - - try { - Method startRule = parserClass.getMethod(startRuleName); - ParserRuleContext tree = (ParserRuleContext)startRule.invoke(parser, (Object[])null); - - if ( printTree ) { - System.out.println(tree.toStringTree(parser)); - } - if ( gui ) { - tree.inspect(parser); - } - if ( psFile!=null ) { - tree.save(parser, psFile); // Generate postscript - } - } - catch (NoSuchMethodException nsme) { - System.err.println("No method for rule "+startRuleName+" or it has arguments"); - } - } - finally { - if ( r!=null ) r.close(); - if ( is!=null ) is.close(); + catch (ClassNotFoundException cnfe) { + System.err.println("Use of TestRig now requires the use of the tool jar, antlr-4.X-complete.jar"); + System.err.println("Maven users need group ID org.antlr and artifact ID antlr4"); } } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/Trees.java b/runtime/Java/src/org/antlr/v4/runtime/tree/Trees.java index 153e6178b..c58ee3dbe 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/Trees.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/Trees.java @@ -37,12 +37,7 @@ import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.misc.Interval; import org.antlr.v4.runtime.misc.Predicate; import org.antlr.v4.runtime.misc.Utils; -import org.antlr.v4.runtime.tree.gui.TreePostScriptGenerator; -import org.antlr.v4.runtime.tree.gui.TreeTextProvider; -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -51,41 +46,6 @@ import java.util.List; /** A set of utility routines useful for all kinds of ANTLR trees. */ public class Trees { - - public static String getPS(Tree t, List ruleNames, - String fontName, int fontSize) - { - TreePostScriptGenerator psgen = - new TreePostScriptGenerator(ruleNames, t, fontName, fontSize); - return psgen.getPS(); - } - - public static String getPS(Tree t, List ruleNames) { - return getPS(t, ruleNames, "Helvetica", 11); - } - - public static void writePS(Tree t, List ruleNames, - String fileName, - String fontName, int fontSize) - throws IOException - { - String ps = getPS(t, ruleNames, fontName, fontSize); - FileWriter f = new FileWriter(fileName); - BufferedWriter bw = new BufferedWriter(f); - try { - bw.write(ps); - } - finally { - bw.close(); - } - } - - public static void writePS(Tree t, List ruleNames, String fileName) - throws IOException - { - writePS(t, ruleNames, fileName, "Helvetica", 11); - } - /** Print out a whole tree in LISP form. {@link #getNodeText} is used on the * node payloads to get the text for the nodes. Detect * parse trees and extract data appropriately. @@ -104,38 +64,23 @@ public class Trees { return toStringTree(t, ruleNamesList); } - /** Print out a whole tree in LISP form. Arg nodeTextProvider is used on the - * node payloads to get the text for the nodes. - * - * @since 4.5.1 - */ - public static String toStringTree(Tree t, TreeTextProvider nodeTextProvider) { - if ( t==null ) return "null"; - String s = Utils.escapeWhitespace(nodeTextProvider.getText(t), false); - if ( t.getChildCount()==0 ) return s; - StringBuilder buf = new StringBuilder(); - buf.append("("); - s = Utils.escapeWhitespace(nodeTextProvider.getText(t), false); - buf.append(s); - buf.append(' '); - for (int i = 0; i0 ) buf.append(' '); - buf.append(toStringTree(t.getChild(i), nodeTextProvider)); - } - buf.append(")"); - return buf.toString(); - } - /** Print out a whole tree in LISP form. {@link #getNodeText} is used on the * node payloads to get the text for the nodes. */ public static String toStringTree(final Tree t, final List ruleNames) { - return toStringTree(t, new TreeTextProvider() { - @Override - public String getText(Tree node) { - return getNodeText(node, ruleNames); - } - }); + String s = Utils.escapeWhitespace(getNodeText(t, ruleNames), false); + if ( t.getChildCount()==0 ) return s; + StringBuilder buf = new StringBuilder(); + buf.append("("); + s = Utils.escapeWhitespace(getNodeText(t, ruleNames), false); + buf.append(s); + buf.append(' '); + for (int i = 0; i0 ) buf.append(' '); + buf.append(toStringTree(t.getChild(i), ruleNames)); + } + buf.append(")"); + return buf.toString(); } public static String getNodeText(Tree t, Parser recog) { @@ -204,7 +149,7 @@ public class Trees { if ( t==null || u==null || t.getParent()==null ) return false; Tree p = u.getParent(); while ( p!=null ) { - if ( t == p ) return true; + if ( t==p ) return true; p = p.getParent(); } return false; diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/InterpreterTreeTextProvider.java b/tool-testsuite/test/org/antlr/v4/test/tool/InterpreterTreeTextProvider.java index 96bdc7c0f..1a555c4ed 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/InterpreterTreeTextProvider.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/InterpreterTreeTextProvider.java @@ -3,7 +3,7 @@ package org.antlr.v4.test.tool; import org.antlr.v4.runtime.tree.ErrorNode; import org.antlr.v4.runtime.tree.Tree; import org.antlr.v4.runtime.tree.Trees; -import org.antlr.v4.runtime.tree.gui.TreeTextProvider; +import org.antlr.v4.gui.TreeTextProvider; import org.antlr.v4.tool.GrammarInterpreterRuleContext; import java.util.Arrays; diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestAmbigParseTrees.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestAmbigParseTrees.java index 148cfc2e2..992b11679 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestAmbigParseTrees.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestAmbigParseTrees.java @@ -14,7 +14,7 @@ import org.antlr.v4.runtime.atn.PredictionMode; import org.antlr.v4.runtime.atn.RuleStartState; import org.antlr.v4.runtime.atn.Transition; import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.Trees; +import org.antlr.v4.gui.Trees; import org.antlr.v4.tool.Grammar; import org.antlr.v4.tool.GrammarParserInterpreter; import org.antlr.v4.tool.LexerGrammar; diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestGrammarParserInterpreter.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestGrammarParserInterpreter.java index aa28877e2..d2afde633 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestGrammarParserInterpreter.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestGrammarParserInterpreter.java @@ -34,7 +34,7 @@ import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.InterpreterRuleContext; import org.antlr.v4.runtime.LexerInterpreter; import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.Trees; +import org.antlr.v4.gui.Trees; import org.antlr.v4.tool.Grammar; import org.antlr.v4.tool.GrammarParserInterpreter; import org.antlr.v4.tool.LexerGrammar; diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestLookaheadTrees.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestLookaheadTrees.java index be047ac9c..36c816340 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestLookaheadTrees.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestLookaheadTrees.java @@ -7,7 +7,7 @@ import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.atn.DecisionInfo; import org.antlr.v4.runtime.atn.LookaheadEventInfo; import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.Trees; +import org.antlr.v4.gui.Trees; import org.antlr.v4.tool.Grammar; import org.antlr.v4.tool.GrammarParserInterpreter; import org.antlr.v4.tool.LexerGrammar; diff --git a/tool/pom.xml b/tool/pom.xml index 1ef4c1032..890f70bf5 100644 --- a/tool/pom.xml +++ b/tool/pom.xml @@ -46,6 +46,11 @@ 4.0.8 compile + + org.abego.treelayout + org.abego.treelayout.core + 1.0.1 + @@ -93,14 +98,14 @@ package - ${project.build.directory}/dependency-reduced-pom.xml - + ${project.build.directory}/dependency-reduced-pom.xml + shade - + diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/BasicFontMetrics.java b/tool/src/org/antlr/v4/gui/BasicFontMetrics.java similarity index 98% rename from runtime/Java/src/org/antlr/v4/runtime/tree/gui/BasicFontMetrics.java rename to tool/src/org/antlr/v4/gui/BasicFontMetrics.java index e280aaf99..b424a003a 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/BasicFontMetrics.java +++ b/tool/src/org/antlr/v4/gui/BasicFontMetrics.java @@ -28,7 +28,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.antlr.v4.runtime.tree.gui; +package org.antlr.v4.gui; /** Font metrics. The only way to generate accurate images * in any format that contain text is to know the font metrics. diff --git a/runtime/Java/src/org/antlr/v4/runtime/misc/GraphicsSupport.java b/tool/src/org/antlr/v4/gui/GraphicsSupport.java similarity index 99% rename from runtime/Java/src/org/antlr/v4/runtime/misc/GraphicsSupport.java rename to tool/src/org/antlr/v4/gui/GraphicsSupport.java index a35c17cc1..eb9546dc8 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/misc/GraphicsSupport.java +++ b/tool/src/org/antlr/v4/gui/GraphicsSupport.java @@ -28,7 +28,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.antlr.v4.runtime.misc; +package org.antlr.v4.gui; import javax.imageio.ImageIO; import javax.print.DocFlavor; diff --git a/runtime/Java/src/org/antlr/v4/runtime/misc/JFileChooserConfirmOverwrite.java b/tool/src/org/antlr/v4/gui/JFileChooserConfirmOverwrite.java similarity index 98% rename from runtime/Java/src/org/antlr/v4/runtime/misc/JFileChooserConfirmOverwrite.java rename to tool/src/org/antlr/v4/gui/JFileChooserConfirmOverwrite.java index 302274de9..59cbb69c2 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/misc/JFileChooserConfirmOverwrite.java +++ b/tool/src/org/antlr/v4/gui/JFileChooserConfirmOverwrite.java @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.antlr.v4.runtime.misc; +package org.antlr.v4.gui; import javax.swing.*; import java.io.File; diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/PostScriptDocument.java b/tool/src/org/antlr/v4/gui/PostScriptDocument.java similarity index 99% rename from runtime/Java/src/org/antlr/v4/runtime/tree/gui/PostScriptDocument.java rename to tool/src/org/antlr/v4/gui/PostScriptDocument.java index 13832d425..7faf2db3a 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/PostScriptDocument.java +++ b/tool/src/org/antlr/v4/gui/PostScriptDocument.java @@ -28,7 +28,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.antlr.v4.runtime.tree.gui; +package org.antlr.v4.gui; import java.awt.*; import java.util.HashMap; diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/SystemFontMetrics.java b/tool/src/org/antlr/v4/gui/SystemFontMetrics.java similarity index 98% rename from runtime/Java/src/org/antlr/v4/runtime/tree/gui/SystemFontMetrics.java rename to tool/src/org/antlr/v4/gui/SystemFontMetrics.java index a3447d306..fb2b17aaf 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/SystemFontMetrics.java +++ b/tool/src/org/antlr/v4/gui/SystemFontMetrics.java @@ -28,7 +28,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.antlr.v4.runtime.tree.gui; +package org.antlr.v4.gui; import java.awt.*; import java.awt.font.FontRenderContext; diff --git a/tool/src/org/antlr/v4/gui/TestRig.java b/tool/src/org/antlr/v4/gui/TestRig.java new file mode 100644 index 000000000..4812e5cc6 --- /dev/null +++ b/tool/src/org/antlr/v4/gui/TestRig.java @@ -0,0 +1,270 @@ +/* + * [The "BSD license"] + * Copyright (c) 2012 Terence Parr + * Copyright (c) 2012 Sam Harwell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.antlr.v4.gui; + +import org.antlr.v4.runtime.ANTLRInputStream; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.DiagnosticErrorListener; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.atn.PredictionMode; + +import javax.print.PrintException; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** Run a lexer/parser combo, optionally printing tree string or generating + * postscript file. Optionally taking input file. + * + * $ java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName + * [-tree] + * [-tokens] [-gui] [-ps file.ps] + * [-trace] + * [-diagnostics] + * [-SLL] + * [input-filename(s)] + */ +public class TestRig { + public static final String LEXER_START_RULE_NAME = "tokens"; + + protected String grammarName; + protected String startRuleName; + protected final List inputFiles = new ArrayList(); + protected boolean printTree = false; + protected boolean gui = false; + protected String psFile = null; + protected boolean showTokens = false; + protected boolean trace = false; + protected boolean diagnostics = false; + protected String encoding = null; + protected boolean SLL = false; + + public TestRig(String[] args) throws Exception { + if ( args.length < 2 ) { + System.err.println("java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName\n" + + " [-tokens] [-tree] [-gui] [-ps file.ps] [-encoding encodingname]\n" + + " [-trace] [-diagnostics] [-SLL]\n"+ + " [input-filename(s)]"); + System.err.println("Use startRuleName='tokens' if GrammarName is a lexer grammar."); + System.err.println("Omitting input-filename makes rig read from stdin."); + return; + } + int i=0; + grammarName = args[i]; + i++; + startRuleName = args[i]; + i++; + while ( i=args.length ) { + System.err.println("missing encoding on -encoding"); + return; + } + encoding = args[i]; + i++; + } + else if ( arg.equals("-ps") ) { + if ( i>=args.length ) { + System.err.println("missing filename on -ps"); + return; + } + psFile = args[i]; + i++; + } + } + } + + public static void main(String[] args) throws Exception { + TestRig testRig = new TestRig(args); + if(args.length >= 2) { + testRig.process(); + } + } + + public void process() throws Exception { +// System.out.println("exec "+grammarName+"."+startRuleName); + String lexerName = grammarName+"Lexer"; + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + Class lexerClass = null; + try { + lexerClass = cl.loadClass(lexerName).asSubclass(Lexer.class); + } + catch (java.lang.ClassNotFoundException cnfe) { + // might be pure lexer grammar; no Lexer suffix then + lexerName = grammarName; + try { + lexerClass = cl.loadClass(lexerName).asSubclass(Lexer.class); + } + catch (ClassNotFoundException cnfe2) { + System.err.println("Can't load "+lexerName+" as lexer or parser"); + return; + } + } + + Constructor lexerCtor = lexerClass.getConstructor(CharStream.class); + Lexer lexer = lexerCtor.newInstance((CharStream)null); + + Class parserClass = null; + Parser parser = null; + if ( !startRuleName.equals(LEXER_START_RULE_NAME) ) { + String parserName = grammarName+"Parser"; + parserClass = cl.loadClass(parserName).asSubclass(Parser.class); + if ( parserClass==null ) { + System.err.println("Can't load "+parserName); + } + Constructor parserCtor = parserClass.getConstructor(TokenStream.class); + parser = parserCtor.newInstance((TokenStream)null); + } + + if ( inputFiles.size()==0 ) { + InputStream is = System.in; + Reader r; + if ( encoding!=null ) { + r = new InputStreamReader(is, encoding); + } + else { + r = new InputStreamReader(is); + } + + process(lexer, parserClass, parser, is, r); + return; + } + for (String inputFile : inputFiles) { + InputStream is = System.in; + if ( inputFile!=null ) { + is = new FileInputStream(inputFile); + } + Reader r; + if ( encoding!=null ) { + r = new InputStreamReader(is, encoding); + } + else { + r = new InputStreamReader(is); + } + + if ( inputFiles.size()>1 ) { + System.err.println(inputFile); + } + process(lexer, parserClass, parser, is, r); + } + } + + protected void process(Lexer lexer, Class parserClass, Parser parser, InputStream is, Reader r) throws IOException, IllegalAccessException, InvocationTargetException, PrintException { + try { + ANTLRInputStream input = new ANTLRInputStream(r); + lexer.setInputStream(input); + CommonTokenStream tokens = new CommonTokenStream(lexer); + + tokens.fill(); + + if ( showTokens ) { + for (Object tok : tokens.getTokens()) { + System.out.println(tok); + } + } + + if ( startRuleName.equals(LEXER_START_RULE_NAME) ) return; + + if ( diagnostics ) { + parser.addErrorListener(new DiagnosticErrorListener()); + parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION); + } + + if ( printTree || gui || psFile!=null ) { + parser.setBuildParseTree(true); + } + + if ( SLL ) { // overrides diagnostics + parser.getInterpreter().setPredictionMode(PredictionMode.SLL); + } + + parser.setTokenStream(tokens); + parser.setTrace(trace); + + try { + Method startRule = parserClass.getMethod(startRuleName); + ParserRuleContext tree = (ParserRuleContext)startRule.invoke(parser, (Object[])null); + + if ( printTree ) { + System.out.println(tree.toStringTree(parser)); + } + if ( gui ) { + Trees.inspect(tree, parser); + } + if ( psFile!=null ) { + Trees.save(tree, parser, psFile); // Generate postscript + } + } + catch (NoSuchMethodException nsme) { + System.err.println("No method for rule "+startRuleName+" or it has arguments"); + } + } + finally { + if ( r!=null ) r.close(); + if ( is!=null ) is.close(); + } + } +} diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeLayoutAdaptor.java b/tool/src/org/antlr/v4/gui/TreeLayoutAdaptor.java similarity index 99% rename from runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeLayoutAdaptor.java rename to tool/src/org/antlr/v4/gui/TreeLayoutAdaptor.java index deb9658a2..6024e3b69 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeLayoutAdaptor.java +++ b/tool/src/org/antlr/v4/gui/TreeLayoutAdaptor.java @@ -28,7 +28,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.antlr.v4.runtime.tree.gui; +package org.antlr.v4.gui; import org.abego.treelayout.TreeForTreeLayout; import org.antlr.v4.runtime.tree.Tree; diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreePostScriptGenerator.java b/tool/src/org/antlr/v4/gui/TreePostScriptGenerator.java similarity index 99% rename from runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreePostScriptGenerator.java rename to tool/src/org/antlr/v4/gui/TreePostScriptGenerator.java index fc7e83e25..d78a1c873 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreePostScriptGenerator.java +++ b/tool/src/org/antlr/v4/gui/TreePostScriptGenerator.java @@ -28,7 +28,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.antlr.v4.runtime.tree.gui; +package org.antlr.v4.gui; import org.abego.treelayout.Configuration; import org.abego.treelayout.NodeExtentProvider; diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeTextProvider.java b/tool/src/org/antlr/v4/gui/TreeTextProvider.java similarity index 97% rename from runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeTextProvider.java rename to tool/src/org/antlr/v4/gui/TreeTextProvider.java index c73037418..9a88fc083 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeTextProvider.java +++ b/tool/src/org/antlr/v4/gui/TreeTextProvider.java @@ -28,7 +28,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.antlr.v4.runtime.tree.gui; +package org.antlr.v4.gui; import org.antlr.v4.runtime.tree.Tree; diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeViewer.java b/tool/src/org/antlr/v4/gui/TreeViewer.java similarity index 99% rename from runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeViewer.java rename to tool/src/org/antlr/v4/gui/TreeViewer.java index 273ec8324..0ca15f303 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/gui/TreeViewer.java +++ b/tool/src/org/antlr/v4/gui/TreeViewer.java @@ -28,15 +28,13 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.antlr.v4.runtime.tree.gui; +package org.antlr.v4.gui; import org.abego.treelayout.NodeExtentProvider; import org.abego.treelayout.TreeForTreeLayout; import org.abego.treelayout.TreeLayout; import org.abego.treelayout.util.DefaultConfiguration; import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.misc.GraphicsSupport; -import org.antlr.v4.runtime.misc.JFileChooserConfirmOverwrite; import org.antlr.v4.runtime.misc.Utils; import org.antlr.v4.runtime.tree.ErrorNode; import org.antlr.v4.runtime.tree.Tree; diff --git a/tool/src/org/antlr/v4/gui/Trees.java b/tool/src/org/antlr/v4/gui/Trees.java new file mode 100644 index 000000000..53796ab23 --- /dev/null +++ b/tool/src/org/antlr/v4/gui/Trees.java @@ -0,0 +1,120 @@ +package org.antlr.v4.gui; + +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.misc.Utils; +import org.antlr.v4.runtime.tree.Tree; + +import javax.print.PrintException; +import javax.swing.*; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.Future; + +public class Trees { + /** Call this method to view a parse tree in a dialog box visually. */ + public static Future inspect(Tree t, List ruleNames) { + TreeViewer viewer = new TreeViewer(ruleNames, t); + return viewer.open(); + } + + /** Call this method to view a parse tree in a dialog box visually. */ + public static Future inspect(Tree t, Parser parser) { + List ruleNames = parser != null ? Arrays.asList(parser.getRuleNames()) : null; + return inspect(t, ruleNames); + } + + /** Save this tree in a postscript file */ + public static void save(Tree t, Parser parser, String fileName) + throws IOException, PrintException + { + List ruleNames = parser != null ? Arrays.asList(parser.getRuleNames()) : null; + save(t, ruleNames, fileName); + } + + /** Save this tree in a postscript file using a particular font name and size */ + public static void save(Tree t, Parser parser, String fileName, + String fontName, int fontSize) + throws IOException + { + List ruleNames = parser != null ? Arrays.asList(parser.getRuleNames()) : null; + save(t, ruleNames, fileName, fontName, fontSize); + } + + /** Save this tree in a postscript file */ + public static void save(Tree t, List ruleNames, String fileName) + throws IOException, PrintException + { + writePS(t, ruleNames, fileName); + } + + /** Save this tree in a postscript file using a particular font name and size */ + public static void save(Tree t, + List ruleNames, String fileName, + String fontName, int fontSize) + throws IOException + { + writePS(t, ruleNames, fileName, fontName, fontSize); + } + + public static String getPS(Tree t, List ruleNames, + String fontName, int fontSize) + { + TreePostScriptGenerator psgen = + new TreePostScriptGenerator(ruleNames, t, fontName, fontSize); + return psgen.getPS(); + } + + public static String getPS(Tree t, List ruleNames) { + return getPS(t, ruleNames, "Helvetica", 11); + } + + public static void writePS(Tree t, List ruleNames, + String fileName, + String fontName, int fontSize) + throws IOException + { + String ps = getPS(t, ruleNames, fontName, fontSize); + FileWriter f = new FileWriter(fileName); + BufferedWriter bw = new BufferedWriter(f); + try { + bw.write(ps); + } + finally { + bw.close(); + } + } + + public static void writePS(Tree t, List ruleNames, String fileName) + throws IOException + { + writePS(t, ruleNames, fileName, "Helvetica", 11); + } + + /** Print out a whole tree in LISP form. Arg nodeTextProvider is used on the + * node payloads to get the text for the nodes. + * + * @since 4.5.1 + */ + public static String toStringTree(Tree t, TreeTextProvider nodeTextProvider) { + if ( t==null ) return "null"; + String s = Utils.escapeWhitespace(nodeTextProvider.getText(t), false); + if ( t.getChildCount()==0 ) return s; + StringBuilder buf = new StringBuilder(); + buf.append("("); + s = Utils.escapeWhitespace(nodeTextProvider.getText(t), false); + buf.append(s); + buf.append(' '); + for (int i = 0; i0 ) buf.append(' '); + buf.append(toStringTree(t.getChild(i), nodeTextProvider)); + } + buf.append(")"); + return buf.toString(); + } + + private Trees() { + } +}