ANTLRv4 Installing ANTLR4 in your Linux PDF - Installing ANTLR4 in your Linux (2026-04-15) Web - Installing ANTLR4 in your Linux (2026-04-15) Java Make sure you have Java installed. Check it with java -version If you don’t have it, install it normally with your distro package manager. ANTLR4 Option 1: Using the package manager Modern Linux distros already include a package for ANTLR, although it is probably too old. sudo apt-get install antlr4 Option 2: Getting the jar file Alternatively, you can go to https://www.antlr.org and follow the instructions there, which mainly consist of: # Download antlr4 jar file to /usr/local/lib cd /usr/local/lib sudo wget http://www.antlr.org/download/antlr-4.13.2-complete.jar IMPORTANT: Do NOT use earlier versions than 4.13, the API is different and it will not work with our code. You will also need to create a command file that will ease the call to Antlr4. Edit a file named antlr4 and write into it: #! /bin/bash export CLASSPATH=".:/usr/local/lib/antlr-4.13.2-complete.jar:$CLASSPATH" java -jar /usr/local/lib/antlr-4.13.2-complete.jar "$@" save the file, and give it execution permission: chmod +x antlr4 finally, move it to a folder in the default PATH sudo mv antlr4 /usr/local/bin C++ Runtime Although Antlr4 is a Java-universe project, it can be instructed to generate C++ code. The resulting code uses some C++ classes included in a shared library (the runtime) that is not installed by default with Antlr4. To install it we can follow the steps below: Option 1: Using the package manager Some linux distributions have this library packaged. Installing the dev package should pull the binaries too. Make sure the version matches the 4.13 ANTLR version installed. sudo apt-get install libantlr4-runtime-dev Option 2: Compiling from source If your distribution does not provide this package, you’ll need to install it from source: First, install required tools and dependencies: sudo apt-get install cmake uuid-dev pkgconf Then, download the source from https://www.antlr.org/download.html and compile it. # download source mkdir antlr-src && cd antlr-src wget http://www.antlr.org/download/antlr4-cpp-runtime-4.13.2-source.zip # unzip file unzip antlr4-cpp-runtime-4.13.2-source.zip # create build directory for cmake mkdir build && cd build # create makefiles cmake .. -DANTLR_JAR_LOCATION=/usr/local/lib/antlr-4.13.2-complete.jar -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_DEMO=True # build and install make sudo make install If you installed Antlr4 from a distribution package, your ANTLR_JAR_LOCATION will be something like /usr/share/java/antlr4-4.13.2.jar. Examine the contents of the package and set the right path in the cmake command. Adapting Makefiles Makefiles provided with the class exercises and lab project expect Antlr4 runtime to be in /assig/$USER/cl/runtime In order to run them in your computer, you need to edit the Makefile and replace line 80 ANTLR_ROOT := /assig/$(USER)/cl/runtime with If you installed from distribution packages: ANTLR_ROOT := /usr If you installed the jarfile directly, set it to the folder where you created the antlr4 command file ANTLR_ROOT := /usr/local Once the Makefile is fixed, you should be able to compile the class examples: cd intro/lab1/Calc make antlr make ./main calc1.txt Setting up Library Paths If you get errors when running your ./main program, it may be that the loader is not finding the runtime. If you installed the runtime in /usr/local/lib you may need to update loader paths: sudo ldconfig If you installed the runtime in some other folder, you need to set the right environment variables so that the loader finds it: export LD_LIBRARY_PATH=/my/runtime/folder You can add this line to your .bashrc to avoid having to do it for every session. MacOS users: in MacOS the variable name is DYLD_LIBRARY_PATH Using grun to visualize trees You can use grun to visualize and debug the trees your grammar is creating. Details on how to do so are given in the Introduction to ANTLR4 page. However, to run it in your computer you’ll need to set up the paths for the java components of ANTLR4. Edit your $HOME/.bashrc file and add the commands: export ANTLR4=/usr/share/java if ( $?CLASSPATH ) then     export CLASSPATH=.:$ANTLR4/antlr-4.13.2-complete.jar:$CLASSPATH else     export CLASSPATH=.:$ANTLR4/antlr-4.13.2-complete.jar fi If you installed antlr4 by getting the jarfile instead of using the package manager, you may need to change the path /usr/share/java to another location (e.g. /usr/local/share/java or wherever you installed it) Once .bashrc has been updated, open a new terminal to get the new configuration loaded. Página nueva Te ayudo a generar el código en C++ para tu gramática de ABB y a entender la diferencia entre Listener y Visitor. 1. Generación del Código C++ con ANTLR Primero, descarga los archivos abbLexer.g4 y abbParser.g4 en el mismo directorio. Luego, ejecuta este comando en la terminal para generar el código C++ : ```bash antlr4 -Dlanguage=Cpp -visitor -listener abbLexer.g4 abbParser.g4 ``` Esto creará una serie de archivos .h y .cpp. Los más importantes son: · abbLexer.h/cpp: El Analizador Léxico. · abbParser.h/cpp: El Analizador Sintáctico. · abbBaseListener.h/cpp y abbBaseVisitor.h/cpp: Clases base para tu propio código. 2. Crear un main.cpp para probar un programa Para probarlo, necesitas un archivo main.cpp que lea un archivo de entrada, lo procese y muestre el árbol sintáctico. Aquí tienes una plantilla que puedes usar : ```cpp #include #include #include "antlr4-runtime.h" #include "abbLexer.h" #include "abbParser.h" using namespace antlr4; int main(int argc, const char* argv[]) {     if (argc < 2) {         std::cerr << "Uso: " << argv[0] << " " << std::endl;         return 1;     }     // 1. Crear el flujo de entrada desde el archivo     std::ifstream stream;     stream.open(argv[1]);     if (!stream) {         std::cerr << "Error: No se pudo abrir el archivo " << argv[1] << std::endl;         return 1;     }     // 2. Crear el lexer y el parser     ANTLRInputStream input(stream);     abbLexer lexer(&input);     CommonTokenStream tokens(&lexer);     abbParser parser(&tokens);     // 3. Obtener el token de errores e iniciar el parsing     parser.removeErrorListeners();     parser.addErrorListener(new ConsoleErrorListener());       tree::ParseTree* tree = parser.module_(); // 'module_' es la regla principal en abbParser.g4     // 4. Imprimir el árbol sintáctico en formato LISP     std::cout << "Árbol Sintáctico: " << tree->toStringTree(&parser) << std::endl;     return 0; } ``` 3. Para qué sirven Listener y Visitor Ambos son patrones de diseño para recorrer el árbol sintáctico y ejecutar tu propia lógica (como calcular valores, comprobar errores o traducir el código), pero su filosofía es distinta . Cuándo usar cada uno: · Visitor (Visitante): Te da el control total. Debes llamar explícitamente a visit() para recorrer los nodos hijos. Es ideal si necesitas retornar valores de los nodos (ej. al evaluar una expresión matemática) y quieres controlar el orden de la visita . · Listener (Oyente): Es automático. El ParseTreeWalker de ANTLR recorre el árbol y va llamando a los métodos enterRegla y exitRegla . Es muy útil cuando necesitas ejecutar acciones antes y después de procesar un bloque, como manejar alcances de variables (entrar/salir de una función) o transformar el formato de salida. Resumen práctico: · Si estás creando un intérprete que calcula valores, te conviene Visitor. · Si estás haciendo un traductor o analizador de alcances, el Listener puede ser más sencillo. Importante: Para compilar, necesitarás la librería de runtime de ANTLR para C++. Si usas CMake, te recomiendo el script de este repositorio de ejemplo, que descarga y compila el runtime por ti automáticamente . Espero que esto te aclare los pasos. Si tienes una duda más concreta sobre qué patrón usar para tu proyecto, puedes decírmelo   Por supuesto. Aquí tienes una versión más divulgativa y estructurada, lista para ser usada como la primera parte de un artículo de blog sobre ANTLR y C++. --- De la Gramática al Código: Tu Primer Compilador con ANTLR y C++ Si alguna vez te has enfrentado a la tarea de leer un archivo de configuración extraño, un lenguaje de juguete o un formato de datos propietario, sabrás lo tedioso que es escribir un analizador (parser) a mano contando paréntesis y comas. Ahí es donde brilla ANTLR (ANother Tool for Language Recognition). En esta primera entrada, vamos a tomar una gramática real de un robot industrial (ABB RAPID) y la vamos a convertir en un programa funcional en C++ que lea y valide archivos .sys. Veremos cómo generar el esqueleto del compilador y, lo más importante, entenderemos para qué demonios sirven el Listener y el Visitor (las dos grandes superestrellas o grandes dolores de cabeza de ANTLR). 1. Paso 1: Las Materias Primas (Lexer y Parser) Partimos de dos archivos que definen el lenguaje: · abbLexer.g4: Define cómo se parten las palabras y símbolos (módulos, :=, PROC, números). · abbParser.g4: Define la gramática, es decir, el orden lógico de esas palabras (un módulo contiene datos, procedimientos, etc.). 2. Paso 2: Invocando al Mago (Generación de Código C++) El primer paso es casi mágico. Con los archivos .g4 en una carpeta, abrimos la terminal y lanzamos el hechizo de ANTLR para C++: ```bash antlr4 -Dlanguage=Cpp -visitor -listener abbLexer.g4 abbParser.g4 ``` ¿Qué hace este comando? · -Dlanguage=Cpp: Le dice a ANTLR que no queremos Java ni Python, queremos clases C++ de alto rendimiento. · -visitor -listener: Le pedimos que nos prepare el terreno para ambas estrategias de recorrido del árbol (luego veremos la diferencia). Tras ejecutar esto, la carpeta se llenará de archivos .h y .cpp. No te asustes, tú solo vas a tocar main.cpp. 3. Paso 3: El Punto de Entrada (main.cpp) Necesitamos un programa que coja un archivo de texto, se lo pase a nuestro recién nacido analizador y nos diga si es válido o no. Aquí tienes el main.cpp mínimo viable para C++: ```cpp #include #include #include "antlr4-runtime.h" #include "abbLexer.h" #include "abbParser.h" using namespace antlr4; int main(int argc, const char* argv[]) {     // 1. Abrir el archivo de ejemplo     std::ifstream stream(argv[1]);     ANTLRInputStream input(stream);       // 2. Fase Léxica: Romper el texto en Tokens     abbLexer lexer(&input);     CommonTokenStream tokens(&lexer);       // 3. Fase Sintáctica: Construir el Árbol     abbParser parser(&tokens);     tree::ParseTree* tree = parser.module_(); // 'module_' es la regla raíz     // 4. Imprimir el resultado     std::cout << "Árbol generado: " << tree->toStringTree(&parser) << std::endl;       return 0; } ``` Si compilas este código (enlazando con la librería de runtime de ANTLR) y le pasas un archivo .sys válido, verás en consola un montón de paréntesis representando la estructura jerárquica del código. ¡Ya tienes un reconocedor sintáctico! 4. El Dilema: ¿Listener o Visitor? Aquí viene la parte filosófica. Ya sabemos leer el archivo, pero ahora queremos hacer algo con esa información (traducirlo a otro lenguaje, calcular posiciones del robot, pintar un diagrama...). ANTLR nos da dos herramientas para recorrer ese árbol que acabas de imprimir. Elegir bien te ahorrará muchas horas de depuración. Característica Listener (El Piloto Automático) Visitor (El Conductor Manual) Recorrido Automático. Un "Andador" (ParseTreeWalker) recorre cada nodo en profundidad. Manual. Tú escribes visit() explícitamente para navegar a los hijos que quieras. Control de Flujo No puedes pararlo. Siempre visita todos los nodos. Tú decides si visitas el hijo izquierdo, el derecho o ninguno. Retorno de Datos No devuelves valores directamente (normalmente usas variables externas o una pila). Sí devuelve valores. Ideal para expresiones matemáticas (visitSuma devuelve un int). Caso de Uso Ideal Traducción de formato (ej. pasar de ABB a Python) o Análisis de alcance (entrar/salir de una función). Evaluación/Interpretación directa o Análisis Semántico que requiere calcular tipos complejos. En resumen para tu blog: · Si tu objetivo es imprimir el código en otro lenguaje o contar cuántas veces aparece la palabra PROC, usa Listener. · Si tu objetivo es ejecutar el programa del robot en un simulador virtual (hacer que el robot se mueva según las coordenadas del archivo), usa Visitor. 5. Próximos Pasos En la siguiente parte de esta serie, implementaremos un Visitor personalizado para extraer todas las declaraciones de variables TOOLDATA del archivo del robot y generar un archivo JSON con la configuración. ¡Nos vemos en el código!