reworked udo's tree viewer

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9149]
This commit is contained in:
parrt 2011-10-21 10:58:00 -08:00
parent 6c104b7724
commit 542a57b49a
15 changed files with 492 additions and 658 deletions

View File

@ -1,6 +1,37 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
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;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNState;
import org.antlr.v4.runtime.atn.RuleTransition;
import org.antlr.v4.runtime.misc.IntervalSet;
/** This is the default error handling mechanism for ANTLR parsers
@ -100,6 +131,9 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy {
/** Make sure that the current lookahead symbol is consistent with
* what were expecting at this point in the ATN.
*
* TODO: see if we can merge sync() and recoverInline(). are they same?
* does one call the other?
*/
@Override
public void sync(BaseRecognizer recognizer) {

View File

@ -28,11 +28,16 @@
*/
package org.antlr.v4.runtime;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNState;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.tree.*;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeListener;
import org.antlr.v4.runtime.tree.Trees;
import org.antlr.v4.runtime.tree.gui.TreeViewer;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
/** Rules can return start/stop info as well as possible trees and templates.
* Each context knows about invoking context and pointer into ATN so we
@ -297,6 +302,11 @@ public class RuleContext implements ParseTree.RuleNode {
return new Interval(start, stop);
}
public void inspect(BaseRecognizer parser) {
TreeViewer viewer = new TreeViewer(parser, this);
viewer.open();
}
/** 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.

View File

@ -29,7 +29,11 @@
package org.antlr.v4.runtime.tree;
import java.util.*;
import org.antlr.v4.runtime.BaseRecognizer;
import org.antlr.v4.runtime.tree.gui.TreeViewer;
import java.util.ArrayList;
import java.util.List;
/** A generic AST implementation with no payload. You must subclass to
* actually have any user data. ANTLR v3 uses a list of children approach
@ -250,6 +254,11 @@ public abstract class BaseAST implements AST {
*/
public List<? extends Tree> getAncestors() { return Trees.getAncestors(this); }
public void inspect(BaseRecognizer parser) {
TreeViewer viewer = new TreeViewer(parser, this);
viewer.open();
}
/** Don't use standard tree printing mechanism since ASTs can have nil
* root nodes.
*/

View File

@ -31,7 +31,6 @@ package org.antlr.v4.runtime.tree;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.tree.gui.ASTViewer;
/** A tree node that is wrapper for a Token object. */
public class CommonAST extends BaseAST {
@ -128,12 +127,6 @@ public class CommonAST extends BaseAST {
stopIndex = index;
}
// TODO: move to basetree when i settle on how runtime works
public void inspect() {
ASTViewer viewer = new ASTViewer(this);
viewer.open();
}
public String toString() {
if ( isNil() ) {
return "nil";

View File

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project />

View File

@ -1,72 +0,0 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
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.tree.gui;
import javax.swing.*;
import java.awt.*;
/*
* Created by JFormDesigner on Mon Jan 18 14:54:16 PST 2010
*/
/**
* @author Terence Parr
*/
public class ASTViewFrame extends JFrame {
public ASTViewFrame() {
initComponents();
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
scrollPane1 = new JScrollPane();
tree = new JTree();
//======== this ========
setTitle("ANTLR AST Viewer");
Container contentPane = getContentPane();
contentPane.setLayout(new GridLayout(1, 1));
//======== scrollPane1 ========
{
scrollPane1.setViewportView(tree);
}
contentPane.add(scrollPane1);
pack();
setLocationRelativeTo(getOwner());
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
// Generated using JFormDesigner non-commercial license
private JScrollPane scrollPane1;
public JTree tree;
// JFormDesigner - End of variables declaration //GEN-END:variables
}

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_15" class="java.beans.XMLDecoder">
<object class="com.jformdesigner.model.FormModel">
<void property="contentType">
<string>form/swing</string>
</void>
<void property="root">
<object class="com.jformdesigner.model.FormRoot">
<void method="add">
<object class="com.jformdesigner.model.FormWindow">
<string>javax.swing.JFrame</string>
<object class="com.jformdesigner.model.FormLayoutManager">
<class>java.awt.GridLayout</class>
<void method="setProperty">
<string>columns</string>
<int>1</int>
</void>
</object>
<void method="setProperty">
<string>title</string>
<string>ANTLR AST Viewer</string>
</void>
<void method="add">
<object class="com.jformdesigner.model.FormContainer">
<string>javax.swing.JScrollPane</string>
<object class="com.jformdesigner.model.FormLayoutManager">
<class>javax.swing.JScrollPane</class>
</object>
<void property="name">
<string>scrollPane1</string>
</void>
<void method="add">
<object class="com.jformdesigner.model.FormComponent">
<string>javax.swing.JTree</string>
<void property="name">
<string>tree</string>
</void>
<void method="auxiliary">
<void method="setProperty">
<string>JavaCodeGenerator.variableModifiers</string>
<int>1</int>
</void>
</void>
</object>
</void>
</object>
</void>
<void property="name">
<string>this</string>
</void>
</object>
<object class="com.jformdesigner.model.FormLayoutConstraints">
<null/>
<void method="setProperty">
<string>location</string>
<object class="java.awt.Point">
<int>0</int>
<int>0</int>
</object>
</void>
<void method="setProperty">
<string>size</string>
<object class="java.awt.Dimension">
<int>400</int>
<int>300</int>
</object>
</void>
</object>
</void>
</object>
</void>
</object>
</java>

View File

@ -1,56 +0,0 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
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.tree.gui;
import org.antlr.v4.runtime.tree.*;
/** */
public class ASTViewer {
ASTAdaptor adaptor;
Object root;
public ASTViewer(ASTAdaptor adaptor, Object root) {
this.adaptor = adaptor;
this.root = root;
}
public ASTViewer(Object root) {
this.adaptor = new CommonASTAdaptor();
this.root = root;
}
public void open() {
ASTViewFrame m = new ASTViewFrame();
m.tree.setModel(new JTreeASTModel(adaptor, root));
m.pack();
m.setSize(800,600);
m.setVisible(true);
}
}

View File

@ -1,164 +0,0 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
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.tree.gui;
import org.abego.treelayout.TreeForTreeLayout;
import org.abego.treelayout.util.*;
import org.antlr.v4.runtime.tree.Tree;
import java.util.*;
public class AntlrTreeLayouter {
// TODO: provide public interface to the configuration/nodeExtent
private double gapBetweenLevels = 50;
private double gapBetweenNodes = 10;
private double nodeWidth = 60;
private double nodeHeight = 20;
public TreeViewer.AntlrTreeLayout layout(Tree tree) {
return new TreeViewer.AntlrTreeLayout(new AntlrTreeForTreeLayout(tree),
new FixedNodeExtentProvider<Tree>(nodeWidth, nodeHeight),
// new TreeViewer.VariableExtentProvide<Tree>(),
new DefaultConfiguration<Tree>(gapBetweenLevels,
gapBetweenNodes));
}
private static class AntlrTreeForTreeLayout implements TreeForTreeLayout<Tree> {
private static class AntlrTreeChildrenIterable implements Iterable<Tree> {
private final Tree tree;
public AntlrTreeChildrenIterable(Tree tree) {
this.tree = tree;
}
@Override
public Iterator<Tree> iterator() {
return new Iterator<Tree>() {
private int i = 0;
@Override
public boolean hasNext() {
return tree.getChildCount() > i;
}
@Override
public Tree next() {
if (!hasNext())
throw new NoSuchElementException();
return tree.getChild(i++);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
private static class AntlrTreeChildrenReverseIterable implements
Iterable<Tree>
{
private final Tree tree;
public AntlrTreeChildrenReverseIterable(Tree tree) {
this.tree = tree;
}
@Override
public Iterator<Tree> iterator() {
return new Iterator<Tree>() {
private int i = tree.getChildCount();
@Override
public boolean hasNext() {
return i > 0;
}
@Override
public Tree next() {
if (!hasNext())
throw new NoSuchElementException();
return tree.getChild(--i);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
private Tree root;
public AntlrTreeForTreeLayout(Tree root) {
this.root = root;
}
@Override
public boolean isLeaf(Tree node) {
return node.getChildCount() == 0;
}
@Override
public boolean isChildOfParent(Tree node, Tree parentNode) {
return node.getParent() == parentNode;
}
@Override
public Tree getRoot() {
return root;
}
@Override
public Tree getLastChild(Tree parentNode) {
return (Tree) parentNode
.getChild(parentNode.getChildCount() - 1);
}
@Override
public Tree getFirstChild(Tree parentNode) {
return (Tree) parentNode.getChild(0);
}
@Override
public Iterable<Tree> getChildrenReverse(Tree node) {
return new AntlrTreeChildrenReverseIterable(node);
}
@Override
public Iterable<Tree> getChildren(Tree node) {
return new AntlrTreeChildrenIterable(node);
}
}
}

View File

@ -1,11 +0,0 @@
package org.antlr.v4.runtime.tree.gui;
import org.antlr.v4.runtime.tree.Tree;
public class DefaultTreeTextProvider implements TreeTextProvider {
@Override
public String getText(Tree node) {
return String.valueOf(node.getPayload());
}
}

View File

@ -1,78 +0,0 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
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.tree.gui;
import org.antlr.v4.runtime.tree.*;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.*;
public class JTreeASTModel implements TreeModel {
ASTAdaptor adaptor;
Object root;
public JTreeASTModel(ASTAdaptor adaptor, Object root) {
this.adaptor = adaptor;
this.root = root;
}
public JTreeASTModel(Object root) {
this.adaptor = new CommonASTAdaptor();
this.root = root;
}
public int getChildCount(Object parent) {
return adaptor.getChildCount(parent);
}
public int getIndexOfChild(Object parent, Object child){
if ( parent==null ) return -1;
return adaptor.getChildIndex(child);
}
public Object getChild(Object parent, int index){
return adaptor.getChild(parent, index);
}
public boolean isLeaf(Object node) {
return getChildCount(node)==0;
}
public Object getRoot() { return root; }
public void valueForPathChanged(TreePath treePath, Object o) {
}
public void addTreeModelListener(TreeModelListener treeModelListener) {
}
public void removeTreeModelListener(TreeModelListener treeModelListener) {
}
}

View File

@ -0,0 +1,149 @@
/*
[The "BSD license"]
Copyright (c) 2011 Udo Borkowski and Terence Parr
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.tree.gui;
import org.abego.treelayout.TreeForTreeLayout;
import org.antlr.v4.runtime.tree.Tree;
import java.util.Iterator;
import java.util.NoSuchElementException;
/** Adaptor ANTLR trees to abego.treelayout.TreeForTreeLayout */
class TreeLayoutAdaptor implements TreeForTreeLayout<Tree> {
private static class AntlrTreeChildrenIterable implements Iterable<Tree> {
private final Tree tree;
public AntlrTreeChildrenIterable(Tree tree) {
this.tree = tree;
}
@Override
public Iterator<Tree> iterator() {
return new Iterator<Tree>() {
private int i = 0;
@Override
public boolean hasNext() {
return tree.getChildCount() > i;
}
@Override
public Tree next() {
if (!hasNext())
throw new NoSuchElementException();
return tree.getChild(i++);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
private static class AntlrTreeChildrenReverseIterable implements
Iterable<Tree>
{
private final Tree tree;
public AntlrTreeChildrenReverseIterable(Tree tree) {
this.tree = tree;
}
@Override
public Iterator<Tree> iterator() {
return new Iterator<Tree>() {
private int i = tree.getChildCount();
@Override
public boolean hasNext() {
return i > 0;
}
@Override
public Tree next() {
if (!hasNext())
throw new NoSuchElementException();
return tree.getChild(--i);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
private Tree root;
public TreeLayoutAdaptor(Tree root) {
this.root = root;
}
@Override
public boolean isLeaf(Tree node) {
return node.getChildCount() == 0;
}
@Override
public boolean isChildOfParent(Tree node, Tree parentNode) {
return node.getParent() == parentNode;
}
@Override
public Tree getRoot() {
return root;
}
@Override
public Tree getLastChild(Tree parentNode) {
return (Tree) parentNode
.getChild(parentNode.getChildCount() - 1);
}
@Override
public Tree getFirstChild(Tree parentNode) {
return (Tree) parentNode.getChild(0);
}
@Override
public Iterable<Tree> getChildrenReverse(Tree node) {
return new AntlrTreeChildrenReverseIterable(node);
}
@Override
public Iterable<Tree> getChildren(Tree node) {
return new AntlrTreeChildrenIterable(node);
}
}

View File

@ -1,3 +1,32 @@
/*
[The "BSD license"]
Copyright (c) 2011 Udo Borkowski and Terence Parr
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.tree.gui;
import org.antlr.v4.runtime.tree.Tree;

View File

@ -1,95 +1,123 @@
/*
[The "BSD license"]
Copyright (c) 2011 Udo Borkowski and Terence Parr
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.tree.gui;
import org.abego.treelayout.*;
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.BaseRecognizer;
import org.antlr.v4.runtime.tree.Tree;
import org.antlr.v4.runtime.tree.Trees;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
public class TreeViewer extends JComponent {
private Font font = new Font(Font.MONOSPACED, Font.PLAIN, 12);
private int arcSize = 10;
public int getArcSize() {
return arcSize;
public class DefaultTreeTextProvider implements TreeTextProvider {
BaseRecognizer parser;
public DefaultTreeTextProvider(BaseRecognizer parser) {
this.parser = parser;
}
public void setArcSize(int arcSize) {
this.arcSize = arcSize;
@Override
public String getText(Tree node) {
return String.valueOf(Trees.getNodeText(node, parser));
}
}
// ----------------------------------------------------------------------
private Color boxColor = Color.orange;
public Color getBoxColor() {
return boxColor;
public static class VariableExtentProvide implements NodeExtentProvider<Tree> {
TreeViewer viewer;
public VariableExtentProvide(TreeViewer viewer) {
this.viewer = viewer;
}
@Override
public double getWidth(Tree tree) {
FontMetrics fontMetrics = viewer.getFontMetrics(viewer.font);
String s = viewer.getText(tree);
int w = fontMetrics.stringWidth(s) + viewer.nodeWidthPadding*2;
return w;
}
public void setBoxColor(Color boxColor) {
this.boxColor = boxColor;
@Override
public double getHeight(Tree tree) {
FontMetrics fontMetrics = viewer.getFontMetrics(viewer.font);
int h = fontMetrics.getHeight() + viewer.nodeHeightPadding*2;
String s = viewer.getText(tree);
String[] lines = s.split("\n");
return h * lines.length;
}
}
// ----------------------------------------------------------------------
protected TreeTextProvider treeTextProvider;
protected TreeLayout<Tree> treeLayout;
private Color borderColor = Color.darkGray;
protected String fontName = Font.MONOSPACED;
protected int fontStyle = Font.PLAIN;
protected int fontSize = 12;
protected Font font = new Font(fontName, fontStyle, fontSize);
public Color getBorderColor() {
return borderColor;
}
protected double gapBetweenLevels = 30;
protected double gapBetweenNodes = 10;
protected int nodeWidthPadding = 2; // added to left/right
protected int nodeHeightPadding = 1; // added above/below
protected int arcSize = 0; // make an arc in node outline?
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
protected Color boxColor = Color.white;
protected Color borderColor = Color.white;
protected Color textColor = Color.black;
// ----------------------------------------------------------------------
protected BaseRecognizer parser;
private Color textColor = Color.black;
public Color getTextColor() {
return textColor;
}
public void setTextColor(Color textColor) {
this.textColor = textColor;
}
private TreeViewer.AntlrTreeLayout treeLayout;
private TreeForTreeLayout<Tree> getTree() {
return treeLayout.getTree();
}
private Iterable<Tree> getChildren(Tree parent) {
return getTree().getChildren(parent);
}
private Rectangle2D.Double getBoundsOfNode(Tree node) {
return treeLayout.getNodeBounds().get(node);
}
private String getText(Tree tree) {
return treeTextProvider.getText(tree);
}
public TreeViewer(Tree tree) {
this.treeLayout = layouter.layout(tree);
public TreeViewer(BaseRecognizer parser, Tree tree) {
this.parser = parser;
setTreeTextProvider(new DefaultTreeTextProvider(parser));
this.treeLayout =
new TreeLayout<Tree>(new TreeLayoutAdaptor(tree),
new TreeViewer.VariableExtentProvide(this),
new DefaultConfiguration<Tree>(gapBetweenLevels,
gapBetweenNodes));
Dimension size = treeLayout.getBounds().getBounds().getSize();
setPreferredSize(size);
setFont(font);
}
// -------------------------------------------------------------------
// painting
// ---------------- PAINT -----------------------------------------------
private void paintEdges(Graphics g, Tree parent) {
protected void paintEdges(Graphics g, Tree parent) {
if (!getTree().isLeaf(parent)) {
Rectangle2D.Double b1 = getBoundsOfNode(parent);
double x1 = b1.getCenterX();
double y1 = b1.getCenterY();
for (Tree child : getChildren(parent)) {
for (Tree child : getTree().getChildren(parent)) {
Rectangle2D.Double b2 = getBoundsOfNode(child);
g.drawLine((int) x1, (int) y1, (int) b2.getCenterX(),
(int) b2.getCenterY());
@ -99,7 +127,7 @@ public class TreeViewer extends JComponent {
}
}
private void paintBox(Graphics g, Tree tree) {
protected void paintBox(Graphics g, Tree tree) {
// draw the box in the background
g.setColor(boxColor);
Rectangle2D.Double box = getBoundsOfNode(tree);
@ -114,8 +142,8 @@ public class TreeViewer extends JComponent {
String s = getText(tree);
String[] lines = s.split("\n");
FontMetrics m = getFontMetrics(font);
int x = (int) box.x + arcSize / 2;
int y = (int) box.y + m.getAscent() + m.getLeading() + 1;
int x = (int) box.x + arcSize / 2 + nodeWidthPadding;
int y = (int) box.y + m.getAscent() + m.getLeading() + 1 + nodeHeightPadding;
for (int i = 0; i < lines.length; i++) {
g.drawString(lines[i], x, y);
y += m.getHeight();
@ -136,35 +164,13 @@ public class TreeViewer extends JComponent {
// ----------------------------------------------------------------------
public static class VariableExtentProvide<Tree> implements NodeExtentProvider<Tree> {
@Override
public double getHeight(Tree tree) {
// FontMetrics m = getFontMetrics(font);
// String text = treeTextProvider.getText(tree);
// int x = (int) box.x + arcSize / 2;
// int y = (int) box.y + m.getAscent() + m.getLeading() + 1;
// int hgt = metrics.getHeight();
// // get the advance of my text in this font and render context
// int adv = metrics.stringWidth(text);
return 0;
protected Rectangle2D.Double getBoundsOfNode(Tree node) {
return treeLayout.getNodeBounds().get(node);
}
@Override
public double getWidth(Tree tree) {
return 0;
protected String getText(Tree tree) {
return treeTextProvider.getText(tree);
}
}
public static class AntlrTreeLayout extends TreeLayout<Tree> {
public AntlrTreeLayout(TreeForTreeLayout<Tree> tree,
NodeExtentProvider<Tree> nodeExtentProvider,
Configuration<Tree> configuration) {
super(tree, nodeExtentProvider, configuration);
}
}
// ----------------------------------------------------------------------
private TreeTextProvider treeTextProvider = new DefaultTreeTextProvider();
public TreeTextProvider getTreeTextProvider() {
return treeTextProvider;
@ -174,18 +180,13 @@ public class TreeViewer extends JComponent {
this.treeTextProvider = treeTextProvider;
}
// ----------------------------------------------------------------------
private AntlrTreeLayouter layouter = new AntlrTreeLayouter();
// ----------------------------------------------------------------------
private static void showInDialog(JComponent panel) {
protected static void showInDialog(TreeViewer viewer) {
JDialog dialog = new JDialog();
Container contentPane = dialog.getContentPane();
((JComponent) contentPane).setBorder(BorderFactory.createEmptyBorder(
10, 10, 10, 10));
contentPane.add(panel);
contentPane.add(viewer);
contentPane.setBackground(Color.white);
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
@ -195,4 +196,61 @@ public class TreeViewer extends JComponent {
showInDialog(this);
}
// ---------------------------------------------------
public void setFontSize(int sz) {
fontSize = sz;
font = new Font(fontName, fontStyle, fontSize);
}
public void setFontName(String name) {
fontName = name;
font = new Font(fontName, fontStyle, fontSize);
}
@Override
public Font getFont() {
return font;
}
@Override
public void setFont(Font font) {
this.font = font;
}
public int getArcSize() {
return arcSize;
}
public void setArcSize(int arcSize) {
this.arcSize = arcSize;
}
public Color getBoxColor() {
return boxColor;
}
public void setBoxColor(Color boxColor) {
this.boxColor = boxColor;
}
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
public Color getTextColor() {
return textColor;
}
public void setTextColor(Color textColor) {
this.textColor = textColor;
}
protected TreeForTreeLayout<Tree> getTree() {
return treeLayout.getTree();
}
}

View File

@ -1,23 +1,36 @@
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import org.antlr.v4.runtime.tree.gui.*;
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
import java.awt.*;
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.
*/
import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.CommonTokenStream;
public class TestT {
public static class MyTreeTextProvider implements TreeTextProvider {
BaseRecognizer parser;
public MyTreeTextProvider(BaseRecognizer parser) {
this.parser = parser;
}
@Override
public String getText(Tree node) {
return String.valueOf(Trees.getNodeText(node, parser));
}
}
public static void main(String[] args) throws Exception {
TLexer t = new TLexer(new ANTLRFileStream(args[0]));
CommonTokenStream tokens = new CommonTokenStream(t);
@ -30,11 +43,7 @@ public class TestT {
TParser.sContext tree = p.s();
System.out.println(tree.toStringTree(p));
TreeViewer tv = new TreeViewer(tree);
tv.setTreeTextProvider(new MyTreeTextProvider(p));
tv.setBoxColor(Color.lightGray);
tv.setBorderColor(Color.darkGray);
tv.open();
tree.inspect(p);
//
// ParseTreeWalker walker = new ParseTreeWalker();
// TListener listener = new BlankTListener() {