├── doc ├── expresiones.md ├── funciones.md ├── proceso.md ├── variables.md ├── analizador_lexico.md ├── analizador_sintactico.md ├── intepretando_codigo.md ├── patron_interpreter.md ├── sentencias_control.md ├── antlr-preferences.png ├── instalacion.md └── instalacion-antiguo.md ├── libs └── astvisualizer │ ├── .gitignore │ ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ └── org.eclipse.jdt.core.prefs │ ├── src │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── jpavlich │ │ │ └── astvisualizer │ │ │ ├── nodes │ │ │ ├── ASTNode.java │ │ │ ├── NumericValue.java │ │ │ ├── Println.java │ │ │ ├── Program.java │ │ │ ├── Addition.java │ │ │ └── Multiplication.java │ │ │ └── VisualizationTest.java │ └── main │ │ └── java │ │ └── com │ │ └── jpavlich │ │ └── astvisualizer │ │ ├── AbstractTreeForASTLayout.java │ │ ├── ASTNodeExtentProvider.java │ │ ├── ASTVNode.java │ │ ├── ASTVisualizer.java │ │ └── ASTPane.java │ ├── .project │ ├── .classpath │ └── pom.xml ├── install_files ├── antlr4-archetype │ ├── .gitignore │ ├── src │ │ ├── test │ │ │ └── resources │ │ │ │ └── projects │ │ │ │ └── basic │ │ │ │ ├── goal.txt │ │ │ │ └── archetype.properties │ │ └── main │ │ │ └── resources │ │ │ ├── archetype-resources │ │ │ ├── test │ │ │ │ └── test.__fileExtension__ │ │ │ ├── .settings │ │ │ │ ├── org.eclipse.m2e.core.prefs │ │ │ │ ├── org.eclipse.core.resources.prefs │ │ │ │ ├── org.eclipse.jdt.core.prefs │ │ │ │ └── com.github.jknack.antlr4ide.Antlr4.prefs │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ ├── antlr4 │ │ │ │ │ └── __packageInPathFormat__ │ │ │ │ │ │ └── __grammarName__.g4 │ │ │ │ │ └── java │ │ │ │ │ └── __packageInPathFormat__ │ │ │ │ │ ├── __grammarName__CustomVisitor.java │ │ │ │ │ └── Main.java │ │ │ ├── .project │ │ │ ├── .classpath │ │ │ └── pom.xml │ │ │ └── META-INF │ │ │ └── maven │ │ │ └── archetype-metadata.xml │ ├── .settings │ │ └── org.eclipse.m2e.core.prefs │ ├── .project │ └── pom.xml └── antlr-maven.p2f ├── .gitignore ├── README.md └── LICENSE /doc/expresiones.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/funciones.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/proceso.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/variables.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/analizador_lexico.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/analizador_sintactico.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/intepretando_codigo.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/patron_interpreter.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/sentencias_control.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /libs/astvisualizer/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/test/resources/projects/basic/goal.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/test/test.__fileExtension__: -------------------------------------------------------------------------------- 1 | hello world -------------------------------------------------------------------------------- /doc/antlr-preferences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jpavlich/antlr4-tutorial/HEAD/doc/antlr-preferences.png -------------------------------------------------------------------------------- /libs/astvisualizer/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /libs/astvisualizer/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/test/java/com/jpavlich/astvisualizer/nodes/ASTNode.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer.nodes; 2 | 3 | public interface ASTNode { 4 | public Object execute(); 5 | } 6 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/src/main/antlr4/__packageInPathFormat__/__grammarName__.g4: -------------------------------------------------------------------------------- 1 | grammar ${grammarName}; 2 | 3 | start 4 | : 5 | 'hello' 'world' 6 | ; 7 | 8 | WS 9 | : 10 | [ \t\r\n]+ -> skip 11 | ; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/test/resources/projects/basic/archetype.properties: -------------------------------------------------------------------------------- 1 | #Fri Apr 01 17:10:23 COT 2016 2 | package=it.pkg 3 | version=0.1-SNAPSHOT 4 | groupId=archetype.it 5 | artifactId=basic 6 | grammarName=Language 7 | fileExtension=lang 8 | basePackage=test 9 | pkg1=a 10 | pkg2=b -------------------------------------------------------------------------------- /libs/astvisualizer/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 5 | org.eclipse.jdt.core.compiler.source=1.8 6 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding//src/test/resources=UTF-8 6 | encoding//target/generated-sources/antlr4=UTF-8 7 | encoding/=UTF-8 8 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/src/main/java/__packageInPathFormat__/__grammarName__CustomVisitor.java: -------------------------------------------------------------------------------- 1 | #set( $symbol_pound = '#' ) 2 | #set( $symbol_dollar = '$' ) 3 | #set( $symbol_escape = '\' ) 4 | 5 | package ${package}; 6 | 7 | public class ${grammarName}CustomVisitor extends ${grammarName}BaseVisitor { 8 | 9 | 10 | 11 | } 12 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/test/java/com/jpavlich/astvisualizer/nodes/NumericValue.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer.nodes; 2 | 3 | public class NumericValue implements ASTNode { 4 | int value; 5 | 6 | 7 | 8 | 9 | public NumericValue(int value) { 10 | super(); 11 | this.value = value; 12 | } 13 | 14 | 15 | 16 | 17 | @Override 18 | public Object execute() { 19 | return value; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /install_files/antlr-maven.p2f: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/test/java/com/jpavlich/astvisualizer/nodes/Println.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer.nodes; 2 | 3 | public class Println implements ASTNode { 4 | 5 | private ASTNode elementToPrint; 6 | 7 | 8 | 9 | public Println(ASTNode elementToPrint) { 10 | super(); 11 | this.elementToPrint = elementToPrint; 12 | } 13 | 14 | 15 | 16 | @Override 17 | public Object execute() { 18 | System.out.println(elementToPrint.execute()); 19 | return null; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/test/java/com/jpavlich/astvisualizer/nodes/Program.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer.nodes; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Program implements ASTNode { 7 | 8 | private List sentences = new ArrayList(); 9 | 10 | public boolean add(ASTNode e) { 11 | return sentences.add(e); 12 | } 13 | 14 | @Override 15 | public Object execute() { 16 | for (ASTNode sentence : sentences) { 17 | sentence.execute(); 18 | } 19 | return null; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/.settings/com.github.jknack.antlr4ide.Antlr4.prefs: -------------------------------------------------------------------------------- 1 | antlr4.antlrRegisteredTools=4.4@/tmp/antlr-4.4-complete.jar 2 | antlr4.antlrToolPath=/tmp/antlr-4.4-complete.jar 3 | antlr4.encoding=UTF-8 4 | antlr4.listener=true 5 | antlr4.visitor=false 6 | antlr4.vmArgs= 7 | autobuilding=false 8 | eclipse.preferences.version=1 9 | is_project_specific=true 10 | outlet.DEFAULT_OUTPUT.cleanupDerived=true 11 | outlet.DEFAULT_OUTPUT.derived=true 12 | outlet.DEFAULT_OUTPUT.directory=./target/generated-sources/antlr4 13 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/test/java/com/jpavlich/astvisualizer/nodes/Addition.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer.nodes; 2 | 3 | public class Addition implements ASTNode { 4 | 5 | private ASTNode operator1; 6 | private ASTNode operator2; 7 | 8 | 9 | 10 | public Addition(ASTNode operator1, ASTNode operator2) { 11 | super(); 12 | this.operator1 = operator1; 13 | this.operator2 = operator2; 14 | } 15 | 16 | 17 | 18 | @Override 19 | public Object execute() { 20 | return (int)operator1.execute() + (int)operator2.execute(); 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/test/java/com/jpavlich/astvisualizer/nodes/Multiplication.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer.nodes; 2 | 3 | public class Multiplication implements ASTNode { 4 | private ASTNode operator1; 5 | private ASTNode operator2; 6 | 7 | 8 | 9 | public Multiplication(ASTNode operator1, ASTNode operator2) { 10 | super(); 11 | this.operator1 = operator1; 12 | this.operator2 = operator2; 13 | } 14 | 15 | 16 | 17 | @Override 18 | public Object execute() { 19 | return (int)operator1.execute() * (int)operator2.execute(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/main/java/com/jpavlich/astvisualizer/AbstractTreeForASTLayout.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer; 2 | 3 | import java.util.List; 4 | 5 | import org.abego.treelayout.util.AbstractTreeForTreeLayout; 6 | 7 | public class AbstractTreeForASTLayout extends AbstractTreeForTreeLayout{ 8 | 9 | public AbstractTreeForASTLayout(ASTVNode root) { 10 | super(root); 11 | } 12 | 13 | @Override 14 | public List getChildrenList(ASTVNode node) { 15 | return node.getChildren(); 16 | } 17 | 18 | @Override 19 | public ASTVNode getParent(ASTVNode node) { 20 | return node.getParent(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /libs/astvisualizer/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | astvisualizer 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | antlr4-archetype 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.xtext.ui.shared.xtextBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.m2e.core.maven2Nature 21 | org.eclipse.xtext.ui.shared.xtextNature 22 | 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Tutorial de ANTLR v4 4 | 5 | [ANTLR](http://www.antlr.org/) es un framework para generar analizadores léxicos y sintácticos. Éstos pueden ser utilizados, entre otras cosas, para procesar archivos de texto estructurados. 6 | 7 | Este tutorial se enfoca en utilizar ANTLR para crear un intérprete de un lenguaje de programación sencillo. El foco del tutorial es entender la esencia de la creación de un intérprete. Por ese motivo, los algoritmos y estructuras de datos utilizados podrían no ser los más óptimos para un intérprete donde la eficiencia sea imprescindible. Sin embargo, son lo suficientemente sencillos para propósitos docentes. 8 | 9 | * [Instalación y configuración de ANTLR v4](doc/instalacion.md) 10 | * [Creación de un intérprete con ANTLR v4](https://www.youtube.com/watch?v=WrlgULIJqEw&list=PL5BoUl9EDVnBojdOv9J9S9KZPJdOc6HTw) 11 | 12 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/main/java/com/jpavlich/astvisualizer/ASTNodeExtentProvider.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer; 2 | 3 | import java.awt.Font; 4 | import java.awt.FontMetrics; 5 | import java.awt.Toolkit; 6 | 7 | import org.abego.treelayout.NodeExtentProvider; 8 | 9 | public class ASTNodeExtentProvider implements NodeExtentProvider { 10 | 11 | private Font font; 12 | 13 | 14 | 15 | public ASTNodeExtentProvider(Font font) { 16 | super(); 17 | this.font = font; 18 | } 19 | 20 | @Override 21 | public double getWidth(ASTVNode treeNode) { 22 | 23 | return Toolkit.getDefaultToolkit().getFontMetrics(font).stringWidth(treeNode.getName()) + 10; 24 | } 25 | 26 | @Override 27 | public double getHeight(ASTVNode treeNode) { 28 | return Toolkit.getDefaultToolkit().getFontMetrics(font).getHeight() * treeNode.getName().split("\n").length + 5; 29 | } 30 | 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/.project: -------------------------------------------------------------------------------- 1 | #set( $symbol_pound = '#' ) 2 | #set( $symbol_dollar = '$' ) 3 | #set( $symbol_escape = '\' ) 4 | 5 | 6 | ${artifactId} 7 | 8 | 9 | 10 | 11 | 12 | org.eclipse.xtext.ui.shared.xtextBuilder 13 | 14 | 15 | 16 | 17 | org.eclipse.jdt.core.javabuilder 18 | 19 | 20 | 21 | 22 | org.eclipse.m2e.core.maven2Builder 23 | 24 | 25 | 26 | 27 | 28 | org.eclipse.jdt.core.javanature 29 | org.eclipse.m2e.core.maven2Nature 30 | org.eclipse.xtext.ui.shared.xtextNature 31 | 32 | 33 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.jpavlich 6 | antlr4-archetype 7 | 1.0 8 | maven-archetype 9 | 10 | antlr4-archetype-archetype 11 | 12 | 13 | 14 | 15 | org.apache.maven.archetype 16 | archetype-packaging 17 | 2.4 18 | 19 | 20 | 21 | 22 | 23 | 24 | maven-archetype-plugin 25 | 2.4 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/src/main/java/__packageInPathFormat__/Main.java: -------------------------------------------------------------------------------- 1 | #set( $symbol_pound = '#' ) 2 | #set( $symbol_dollar = '$' ) 3 | #set( $symbol_escape = '\' ) 4 | 5 | package ${package}; 6 | import java.io.IOException; 7 | 8 | import org.antlr.v4.runtime.ANTLRFileStream; 9 | import org.antlr.v4.runtime.CommonTokenStream; 10 | 11 | public class Main { 12 | 13 | private static final String EXTENSION = "${fileExtension}"; 14 | 15 | public static void main(String[] args) throws IOException { 16 | String program = args.length > 1 ? args[1] : "test/test." + EXTENSION; 17 | 18 | System.out.println("Interpreting file " + program); 19 | 20 | ${grammarName}Lexer lexer = new ${grammarName}Lexer(new ANTLRFileStream(program)); 21 | CommonTokenStream tokens = new CommonTokenStream(lexer); 22 | ${grammarName}Parser parser = new ${grammarName}Parser(tokens); 23 | 24 | ${grammarName}Parser.StartContext tree = parser.start(); 25 | 26 | ${grammarName}CustomVisitor visitor = new ${grammarName}CustomVisitor(); 27 | visitor.visit(tree); 28 | 29 | System.out.println("Interpretation finished"); 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /libs/astvisualizer/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | src/main/java 21 | 22 | **/*.java 23 | 24 | 25 | 26 | src/main/antlr4 27 | 28 | **/*.g4 29 | 30 | 31 | 32 | test 33 | 34 | **/* 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/main/java/com/jpavlich/astvisualizer/ASTVNode.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer; 2 | 3 | import java.awt.Color; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class ASTVNode { 8 | private Object node; 9 | private ASTVNode parent; 10 | private List children = new ArrayList(); 11 | private Color bgColor; 12 | private Color fgColor; 13 | String name; 14 | private int yOffset; 15 | 16 | public ASTVNode(Object node, ASTVNode parent, String name, Color bgColor, Color fgColor, int yOffset) { 17 | super(); 18 | this.node = node; 19 | if (parent != null) { 20 | this.parent = parent; 21 | parent.addChild(this); 22 | } 23 | this.name = name; 24 | this.bgColor = bgColor; 25 | this.fgColor = fgColor; 26 | this.yOffset = yOffset; 27 | } 28 | 29 | public Object getNode() { 30 | return node; 31 | } 32 | 33 | public ASTVNode getParent() { 34 | return parent; 35 | } 36 | 37 | public boolean addChild(ASTVNode e) { 38 | return children.add(e); 39 | } 40 | 41 | public List getChildren() { 42 | return children; 43 | } 44 | 45 | public String getText() { 46 | return name; 47 | } 48 | 49 | 50 | 51 | public String getName() { 52 | return name; 53 | } 54 | 55 | 56 | public Color getBgColor() { 57 | return bgColor; 58 | } 59 | 60 | public Color getFgColor() { 61 | return fgColor; 62 | } 63 | 64 | public int getyOffset() { 65 | return yOffset; 66 | } 67 | 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/test/java/com/jpavlich/astvisualizer/VisualizationTest.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer; 2 | 3 | import com.jpavlich.astvisualizer.nodes.ASTNode; 4 | import com.jpavlich.astvisualizer.nodes.Addition; 5 | import com.jpavlich.astvisualizer.nodes.Multiplication; 6 | import com.jpavlich.astvisualizer.nodes.NumericValue; 7 | import com.jpavlich.astvisualizer.nodes.Program; 8 | 9 | public class VisualizationTest { 10 | 11 | public static void main(String[] args) { 12 | Program root = new Program(); 13 | 14 | root.add(new Addition(new Multiplication(new NumericValue(5), new NumericValue(8)), new NumericValue(4))); 15 | root.add(new Multiplication(new NumericValue(1), new Addition(new NumericValue(2), new NumericValue(6)))); 16 | root.add(new Addition(new Multiplication(new NumericValue(5), new NumericValue(8)), new NumericValue(4))); 17 | root.add(new Multiplication(new NumericValue(1), new Addition(new NumericValue(2), new NumericValue(6)))); 18 | root.add(new Addition(new Multiplication(new NumericValue(5), new NumericValue(8)), new NumericValue(4))); 19 | root.add(new Multiplication(new NumericValue(1), new Addition(new NumericValue(2), new NumericValue(6)))); 20 | root.add(new Addition(new Multiplication(new NumericValue(5), new NumericValue(8)), new NumericValue(4))); 21 | root.add(new Multiplication(new NumericValue(1), new Addition(new NumericValue(2), new NumericValue(6)))); 22 | 23 | new ASTVisualizer(root, ASTNode.class).visualize(1000,700); 24 | 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /libs/astvisualizer/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | org.jpavlich 6 | ast-visualizer 7 | 0.0.1-RELEASE 8 | jar 9 | 10 | ast-visualizer 11 | 12 | 13 | UTF-8 14 | 15 | 16 | 17 | 18 | 19 | org.apache.maven.plugins 20 | maven-compiler-plugin 21 | 22 | 1.8 23 | 1.8 24 | 25 | 26 | 27 | 28 | org.apache.maven.plugins 29 | maven-source-plugin 30 | 3.0.1 31 | 32 | 33 | attach-sources 34 | 35 | jar-no-fork 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | junit 46 | junit 47 | 3.8.1 48 | test 49 | 50 | 51 | org.abego.treelayout 52 | org.abego.treelayout.core 53 | 1.0.3 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/.classpath: -------------------------------------------------------------------------------- 1 | #set( $symbol_pound = '#' ) 2 | #set( $symbol_dollar = '$' ) 3 | #set( $symbol_escape = '\' ) 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /install_files/antlr4-archetype/src/main/resources/archetype-resources/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | ${groupId} 6 | ${artifactId} 7 | ${version} 8 | Antlr 4 Archetype 9 | jar 10 | 11 | 12 | 4.5.2 13 | 4.5.2 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | org.antlr 23 | antlr4-maven-plugin 24 | ${antlr4.plugin.version} 25 | 26 | 27 | -visitor 28 | 29 | 30 | 31 | 32 | antlr 33 | 34 | antlr4 35 | 36 | 37 | 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-compiler-plugin 43 | 44 | 1.8 45 | 1.8 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.antlr 54 | antlr4-runtime 55 | ${antlr4.version} 56 | 57 | 58 | 59 | org.antlr 60 | antlr4-maven-plugin 61 | ${antlr4.plugin.version} 62 | 63 | 64 | 65 | org.jpavlich 66 | ast-visualizer 67 | [0.0.1,) 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/main/java/com/jpavlich/astvisualizer/ASTVisualizer.java: -------------------------------------------------------------------------------- 1 | package com.jpavlich.astvisualizer; 2 | 3 | import java.awt.Color; 4 | import java.awt.Dimension; 5 | import java.awt.Font; 6 | import java.awt.event.WindowAdapter; 7 | import java.awt.event.WindowEvent; 8 | import java.lang.reflect.Field; 9 | import java.util.Collection; 10 | 11 | import javax.swing.BorderFactory; 12 | import javax.swing.JComponent; 13 | import javax.swing.JFrame; 14 | import javax.swing.JLabel; 15 | import javax.swing.JScrollPane; 16 | 17 | import org.abego.treelayout.TreeLayout; 18 | import org.abego.treelayout.util.DefaultConfiguration; 19 | 20 | /** 21 | * This class displays an abstract syntax tree. The nodes of the 22 | * tree can be any subclasses of a particular class or interface. 23 | * This class begins at the root object and finds the children by 24 | * reflectively visiting all of the declared attributes in the root class 25 | * (inherited attributes are not visited). The process repeats 26 | * recursively for all the children. 27 | */ 28 | public class ASTVisualizer { 29 | 30 | private Object root; 31 | Class superclass; 32 | 33 | /** Creates an instance of the AST visualizer. 34 | * @param root The object that is the root of the tree that needs to be visualized 35 | * @param superclass The superclass of all of the objects that will be visualized. 36 | * Any object that is not a subclass of superclass will not be displayed in the tree. 37 | * Be careful to not choose classes or interfaces that are too general (e.g. Object), 38 | * since the visualizer may enter an infinite recursion. 39 | */ 40 | public ASTVisualizer(Object root, Class superclass) { 41 | super(); 42 | this.root = root; 43 | this.superclass = superclass; 44 | } 45 | 46 | /** Shows the window that displays the tree 47 | * @param width Width of the window 48 | * @param height Height of the window 49 | */ 50 | public void visualize(int width, int height) { 51 | try { 52 | ASTVNode rootNode = createTree(root, null, ""); 53 | if (rootNode == null) 54 | return; 55 | AbstractTreeForASTLayout tree = new AbstractTreeForASTLayout(rootNode); 56 | 57 | // setup the tree layout configuration 58 | double gapBetweenLevels = 50; 59 | double gapBetweenNodes = 10; 60 | DefaultConfiguration configuration = new DefaultConfiguration(gapBetweenLevels, 61 | gapBetweenNodes); 62 | 63 | Font font = new JLabel().getFont(); 64 | // Create a panel that draws the nodes and edges and show the panel 65 | JFrame f = new JFrame(); 66 | 67 | JComponent container = (JComponent) f.getContentPane(); 68 | container.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); 69 | 70 | // create the NodeExtentProvider for TextInBox nodes 71 | ASTNodeExtentProvider nodeExtentProvider = new ASTNodeExtentProvider(font); 72 | 73 | // create the layout 74 | TreeLayout treeLayout = new TreeLayout(tree, nodeExtentProvider, configuration); 75 | 76 | ASTPane astPane = new ASTPane(treeLayout, font); 77 | JScrollPane scrollPane = new JScrollPane(astPane); 78 | scrollPane.setPreferredSize(new Dimension(width, height)); 79 | scrollPane.setBorder(BorderFactory.createEmptyBorder()); 80 | container.add(scrollPane); 81 | f.pack(); 82 | f.setLocationRelativeTo(null); 83 | f.addWindowListener(new WindowAdapter() { 84 | 85 | @Override 86 | public void windowClosing(WindowEvent e) { 87 | System.exit(0); 88 | } 89 | 90 | }); 91 | 92 | 93 | f.setVisible(true); 94 | 95 | } catch (Exception e) { 96 | e.printStackTrace(); 97 | } 98 | 99 | } 100 | 101 | private ASTVNode createTree(Object obj, ASTVNode parent, String fieldName) throws Exception { 102 | 103 | if (superclass.isAssignableFrom(obj.getClass())) { 104 | ASTVNode node = new ASTVNode(obj, parent, obj.getClass().getSimpleName(), Color.orange, Color.black, 0); 105 | for (Field f : obj.getClass().getDeclaredFields()) { 106 | f.setAccessible(true); 107 | Object child = f.get(obj); 108 | if (f.getType().isPrimitive()) { 109 | node.name += "\n" + f.getName() + " = " + child; 110 | } else { 111 | ASTVNode fieldNode = new ASTVNode(f, node, f.getName(), new Color(0, 0, 0, 0), 112 | new Color(0, 0, 0, 0), 0); 113 | createTree(child, fieldNode, f.getName()); 114 | } 115 | 116 | } 117 | return node; 118 | } else if (Collection.class.isAssignableFrom(obj.getClass())) { 119 | Collection list = (Collection) obj; 120 | for (Object elem : list) { 121 | createTree(elem, parent, ""); 122 | } 123 | return parent; 124 | } 125 | return null; 126 | 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /doc/instalacion.md: -------------------------------------------------------------------------------- 1 | # Instalación y configuración de ANTLR v4 2 | 3 | [Instrucciones antiguas de instalación](instalacion-antiguo.md) 4 | 5 | Existen varias alternativas para [utilizar ANTLR4](http://www.antlr.org/tools.html). En este tutorial nos enfocaremos en utilizar [Eclipse](http://www.eclipse.org/) y [Maven](https://maven.apache.org/). A pesar de ello, este tutorial debería servir con cambios mínimos para cualquiera de las demás herramientas disponibles. 6 | 7 | Se asume que el lector tiene las siguientes competencias: 8 | * JDK 9 | - Instalar JDK 10 | 11 | * Eclipse 12 | - Instalar Eclipse 13 | - Instalar plugins 14 | - Importar proyectos 15 | - Desarrollar en Java con Eclipse 16 | 17 | * Maven 18 | - Crear un proyecto Maven 19 | - Manejo de archivos `pom.xml` 20 | - Configurar repositorios 21 | - Configurar dependencias 22 | - Configurar proceso de construcción (build) 23 | 24 | ## I. Instalación de entorno de desarrollo 25 | Todo el software requiere instalar **JDK 11, ya sea la versión de Oracle u OpenJDK**, el cual debe ser habilitado como el JDK por defecto del sistema operativo. Habrán problemas si se utiliza una versión posterior. 26 | 27 | El repositorio de este tutorial contiene muchos archivos útiles para la instalación. La forma más simple de descargar el repositorio es: 28 | 29 | 1. Descargar el archivo `antlr4-tutorial-master.zip` desde este [enlace](https://github.com/jpavlich/antlr4-tutorial/archive/master.zip). 30 | 2. Descomprimir el archivo `antlr4-tutorial-master.zip` en la carpeta que desee. 31 | 32 | 33 | ### Eclipse 34 | Hay dos formas de configurar Eclipse como ambiente de desarrollo. 35 | 36 | #### Opción automática 37 | 38 | Alternativamente, todos los plugins anteriores (m2e) pueden instalarse en forma automática utilizando el archivo de instalación P2F que se encuentra en `antlr4-tutorial-master/install_files/antlr-maven.p2f`. 39 | 40 | 1. Instalar [Eclipse IDE for Java and DSL Developers (2019-12)](https://www.eclipse.org/downloads/packages/). **Es importante que la versión de Eclipse sea 2019-12. Cualquier otra versión podría no funcionar** 41 | 2. Abrir menú `File->Import->Install->Install Software Items from File` 42 | 3. Hacer click en `Browse` 43 | 4. Buscar y seleccionar el archivo `antlr4-tutorial-master/install_files/antlr-maven.p2f` 44 | 5. Seleccionar todos los plugins que aparezcan en la lista 45 | 6. **Deseleccionar** la opción `Install latest version of selected software`. 46 | 47 | #### Opción manual 48 | 49 | 1. Instalar [Eclipse IDE for Java and DSL Developers (2019-12)](https://www.eclipse.org/downloads/packages/) 50 | 2. Instalar el plugin [ANTLR 4 IDE](https://marketplace.eclipse.org/content/antlr-4-ide) 51 | 52 | #### Después de instalar Eclipse 53 | Es necesario desactivar una opción del plugin ANTLR 4 IDE. 54 | 55 | 1. Abrir las preferencias de Eclipse. 56 | 2. Abrir ANTLR4 -> Tool 57 | 3. Desactivar la opción `Tool is activated`. Las opciones deben quedar como en la siguiente imagen: 58 | ![](antlr-preferences.png) 59 | 60 | ### Maven 61 | 62 | Las instrucciones para instalar maven se encuentran [aquí](https://maven.apache.org/install.html) 63 | 64 | ## II. Configuración de un proyecto en ANTLR 4 65 | 66 | El repositorio también provee un arquetipo de maven, llamado `antlr4-archetype`, para crear proyectos ANTLR4 y una librería, llamada `ast-visualizer` para desplegar árboles semánticos. Los proyectos creados a partir del arquetipo están preconfigurados para comenzar a desarrollar sin mayores inconvenientes (asumiendo que todos los pasos de la instalación hayan sido ejecutados correctamente). 67 | 68 | **Los siguientes pasos sólo hay que ejecutarlos una vez:** 69 | 70 | * Abrir la línea de comandos e ingresar a la carpeta `antlr4-tutorial-master`. 71 | * Instalar el arquetipo `antlr4-archetype` que se encuentra en `install_files/antlr4-archetype`. 72 | ``` 73 | cd install_files/antlr4-archetype 74 | mvn clean install 75 | cd ../.. 76 | ``` 77 | * Instalar la librería `ast-visualizer` que se encuentra en `libs/astvisualizer` 78 | ``` 79 | cd libs/astvisualizer 80 | mvn clean install 81 | ``` 82 | 83 | **El siguiente paso hay que ejecutarlo cada vez que se desee crear un nuevo proyecto:** 84 | 85 | * Crear un nuevo proyecto basado en el arquetipo `antlr4-archetype`. En el siguiente comando, reemplace `my-app` por el nombre del proyecto que desea crear y `com.mycompany.app` por el nombre del paquete donde quedarán todos los archivos fuentes de su aplicación. 86 | 87 | ``` 88 | mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=antlr4-archetype -DinteractiveMode=false 89 | ``` 90 | 91 | Por ejemplo, para crear una aplicación que se llame `MiLenguaje` y que el código fuente quede en el paquete `com.milenguaje`, debe escribir lo siguiente: 92 | 93 | ``` 94 | mvn archetype:generate -DgroupId=com.milenguaje -DartifactId=MiLenguaje -DarchetypeArtifactId=antlr4-archetype -DinteractiveMode=false 95 | ``` 96 | 97 | Luego de ello, podrá importar el proyecto generado en Eclipse, utilizando la opción `File->Import->Existing Maven Projects`. 98 | 99 | 100 | -------------------------------------------------------------------------------- /doc/instalacion-antiguo.md: -------------------------------------------------------------------------------- 1 | # Instalación y configuración de ANTLR v4 2 | 3 | Existen varias alternativas para [utilizar ANTLR4](http://www.antlr.org/tools.html). En este tutorial nos enfocaremos en utilizar [Eclipse](http://www.eclipse.org/) y [Maven](https://maven.apache.org/). A pesar de ello, este tutorial debería servir con cambios mínimos para cualquiera de las demás herramientas disponibles. 4 | 5 | Se asume que el lector tiene las siguientes competencias: 6 | 7 | * Eclipse 8 | - Instalar Eclipse 9 | - Instalar plugins 10 | - Importar proyectos 11 | - Desarrollar en Java con Eclipse 12 | 13 | * Maven 14 | - Crear un proyecto Maven 15 | - Manejo de archivos `pom.xml` 16 | - Configurar repositorios 17 | - Configurar dependencias 18 | - Configurar proceso de construcción (build) 19 | 20 | ## I. Instalación de entorno de desarrollo 21 | 22 | El repositorio de este tutorial contiene muchos archivos útiles para la instalación. La forma más simple de descargar el repositorio es: 23 | 24 | 1. Descargar el archivo `antlr4-tutorial-master.zip` desde este [enlace](https://github.com/jpavlich/antlr4-tutorial/archive/master.zip). 25 | 2. Descomprimir el archivo `antlr4-tutorial-master.zip` en la carpeta que desee. 26 | 27 | 28 | ### Eclipse 29 | Hay dos formas de configurar Eclipse como ambiente de desarrollo. 30 | 31 | #### Opción automática 32 | 33 | Alternativamente, todos los plugins anteriores (m2e) pueden instalarse en forma automática utilizando el archivo de instalación P2F que se encuentra en `antlr4-tutorial-master/install_files/antlr-maven.p2f`. 34 | 35 | 1. Instalar [Eclipse Modeling Tools (Mars)](http://www.eclipse.org/downloads/packages/eclipse-modeling-tools/mars2). **Es importante que la versión de Eclipse sea Mars. Cualquier otra versión no funcionará** 36 | 2. Abrir menú `File->Import->Install->Install Software Items from File` 37 | 3. Hacer click en `Browse` 38 | 4. Buscar y seleccionar el archivo `antlr4-tutorial-master/install_files/antlr-maven.p2f` 39 | 5. Seleccionar todos los plugins que aparezcan en la lista 40 | 6. **Deseleccionar** la opción `Install latest version of selected software`. Esto es porque el plugin ANTLR 4 IDE funciona exclusivamente con la versión 2.7.3 de Xtext y con esto se evita que Eclipse instale una versión posterior. 41 | 42 | #### Opción manual 43 | 44 | 1. Instalar [Eclipse Modeling Tools](http://www.eclipse.org/downloads/packages/eclipse-modeling-tools/mars2) 45 | 2. Instalar el plugin [m2e](http://www.eclipse.org/m2e/) 46 | 3. Instalar el plugin [m2e connector for antlr ]() 47 | 4. Instalar el plugin [m2e connector for the Maven Dependency Plugin]() 48 | Opcional: 49 | 1. Instalar el plugin [Xtext](https://eclipse.org/Xtext/download.html). La versión _debe_ ser la 2.7.3. 50 | 2. Instalar el plugin [ANTLR 4 IDE](https://github.com/jknack/antlr4ide) 51 | 52 | #### Después de instalar Eclipse 53 | Es necesario desactivar una opción del plugin ANTLR 4 IDE. 54 | 55 | 1. Abrir las preferencias de Eclipse. 56 | 2. Abrir ANTLR4 -> Tool 57 | 3. Desactivar la opción `Tool is activated`. Las opciones deben quedar como en la siguiente imagen: 58 | ![](antlr-preferences.png) 59 | 60 | ### Maven 61 | 62 | Las instrucciones para instalar maven se encuentran [aquí](https://maven.apache.org/install.html) 63 | 64 | ## II. Configuración de un proyecto en ANTLR 4 65 | 66 | El repositorio también provee un arquetipo de maven, llamado `antlr4-archetype`, para crear proyectos ANTLR4 y una librería, llamada `ast-visualizer` para desplegar árboles semánticos. Los proyectos creados a partir del arquetipo están preconfigurados para comenzar a desarrollar sin mayores inconvenientes (asumiendo que todos los pasos de la instalación hayan sido ejecutados correctamente). 67 | 68 | **Los siguientes pasos sólo hay que ejecutarlos una vez:** 69 | 70 | * Abrir la línea de comandos e ingresar a la carpeta `antlr4-tutorial-master`. 71 | * Instalar el arquetipo `antlr4-archetype` que se encuentra en `install_files/antlr4-archetype`. 72 | ``` 73 | cd install_files/antlr4-archetype 74 | mvn clean install 75 | cd ../.. 76 | ``` 77 | * Instalar la librería `ast-visualizer` que se encuentra en `libs/astvisualizer` 78 | ``` 79 | cd libs/astvisualizer 80 | mvn clean install 81 | ``` 82 | 83 | **El siguiente paso hay que ejecutarlo cada vez que se desee crear un nuevo proyecto:** 84 | 85 | * Crear un nuevo proyecto basado en el arquetipo `antlr4-archetype`. En el siguiente comando, reemplace `my-app` por el nombre del proyecto que desea crear y `com.mycompany.app` por el nombre del paquete donde quedarán todos los archivos fuentes de su aplicación. 86 | 87 | ``` 88 | mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=antlr4-archetype -DinteractiveMode=false 89 | ``` 90 | 91 | Por ejemplo, para crear una aplicación que se llame `MiLenguaje` y que el código fuente quede en el paquete `com.milenguaje`, debe escribir lo siguiente: 92 | 93 | ``` 94 | mvn archetype:generate -DgroupId=com.milenguaje -DartifactId=MiLenguaje -DarchetypeArtifactId=antlr4-archetype -DinteractiveMode=false 95 | ``` 96 | 97 | Luego de ello, podrá importar el proyecto generado en Eclipse, utilizando la opción `File->Import->Existing Maven Projects`. 98 | 99 | 100 | -------------------------------------------------------------------------------- /libs/astvisualizer/src/main/java/com/jpavlich/astvisualizer/ASTPane.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011, abego Software GmbH, Germany (http://www.abego.org) 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * 1. Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright notice, 12 | * this list of conditions and the following disclaimer in the documentation 13 | * and/or other materials provided with the distribution. 14 | * 3. Neither the name of the abego Software GmbH nor the names of its 15 | * contributors may be used to endorse or promote products derived from this 16 | * software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package com.jpavlich.astvisualizer; 31 | 32 | import java.awt.Color; 33 | import java.awt.Dimension; 34 | import java.awt.Font; 35 | import java.awt.FontMetrics; 36 | import java.awt.Graphics; 37 | import java.awt.Graphics2D; 38 | import java.awt.RenderingHints; 39 | import java.awt.geom.Rectangle2D; 40 | 41 | import javax.swing.JComponent; 42 | 43 | import org.abego.treelayout.TreeForTreeLayout; 44 | import org.abego.treelayout.TreeLayout; 45 | 46 | /** 47 | * A JComponent displaying a tree of TextInBoxes, given by a {@link TreeLayout}. 48 | * 49 | * @author Udo Borkowski (ub@abego.org) 50 | */ 51 | public class ASTPane extends JComponent { 52 | private static final long serialVersionUID = -7172339407066277588L; 53 | private final TreeLayout treeLayout; 54 | private Font nodeFont; 55 | 56 | private TreeForTreeLayout getTree() { 57 | return treeLayout.getTree(); 58 | } 59 | 60 | private Iterable getChildren(ASTVNode parent) { 61 | return getTree().getChildren(parent); 62 | } 63 | 64 | private Rectangle2D.Double getBoundsOfNode(ASTVNode node) { 65 | return treeLayout.getNodeBounds().get(node); 66 | } 67 | 68 | /** 69 | * Specifies the tree to be displayed by passing in a {@link TreeLayout} for 70 | * that tree. 71 | * 72 | * @param treeLayout 73 | * the {@link TreeLayout} to be displayed 74 | */ 75 | public ASTPane(TreeLayout treeLayout, Font nodeFont) { 76 | this.treeLayout = treeLayout; 77 | 78 | Dimension size = treeLayout.getBounds().getBounds().getSize(); 79 | // Dimension size = new Dimension(800, 600); 80 | setPreferredSize(size); 81 | this.nodeFont = nodeFont; 82 | } 83 | 84 | // ------------------------------------------------------------------- 85 | // painting 86 | 87 | private final static int ARC_SIZE = 10; 88 | private final static Color TEXT_COLOR = Color.black; 89 | 90 | private void paintEdges(Graphics g, ASTVNode parent) { 91 | if (!getTree().isLeaf(parent)) { 92 | setAntialias(g); 93 | 94 | Rectangle2D.Double b1 = getBoundsOfNode(parent); 95 | double x1 = b1.getCenterX(); 96 | double y1 = b1.getCenterY(); 97 | for (ASTVNode child : getChildren(parent)) { 98 | Rectangle2D.Double b2 = getBoundsOfNode(child); 99 | g.drawLine((int) x1, (int) y1, (int) b2.getCenterX(), (int) b2.getCenterY()); 100 | 101 | paintEdges(g, child); 102 | } 103 | } 104 | } 105 | 106 | public void setAntialias(Graphics g) { 107 | Graphics2D g2D = (Graphics2D) g; 108 | g2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 109 | g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 110 | } 111 | 112 | private void paintBox(Graphics g, ASTVNode astNode) { 113 | // draw the box in the background 114 | setAntialias(g); 115 | g.setColor(astNode.getBgColor()); 116 | Rectangle2D.Double box = getBoundsOfNode(astNode); 117 | g.fillRoundRect((int) box.x, (int) box.y, (int) box.width - 1, (int) box.height - 1, ARC_SIZE, ARC_SIZE); 118 | g.setColor(astNode.getFgColor()); 119 | g.drawRoundRect((int) box.x, (int) box.y, (int) box.width - 1, (int) box.height - 1, ARC_SIZE, ARC_SIZE); 120 | 121 | // draw the text on top of the box (possibly multiple lines) 122 | g.setColor(TEXT_COLOR); 123 | Font prevFont = g.getFont(); 124 | g.setFont(nodeFont); 125 | String[] lines = astNode.getText().split("\n"); 126 | FontMetrics m = getFontMetrics(); 127 | int x = (int) box.x + ARC_SIZE / 2; 128 | int y = (int) box.y + m.getAscent() + m.getLeading() + 1 + astNode.getyOffset(); 129 | for (int i = 0; i < lines.length; i++) { 130 | g.drawString(lines[i], x, y); 131 | y += m.getHeight(); 132 | } 133 | g.setFont(prevFont); 134 | } 135 | 136 | public FontMetrics getFontMetrics() { 137 | return getFontMetrics(nodeFont); 138 | } 139 | 140 | @Override 141 | public void paint(Graphics g) { 142 | super.paint(g); 143 | 144 | paintEdges(g, getTree().getRoot()); 145 | 146 | // paint the boxes 147 | for (ASTVNode astNode : treeLayout.getNodeBounds().keySet()) { 148 | paintBox(g, astNode); 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------