Me gustaría empezar con ANTLR, pero después de pasar un par de horas revisando los ejemplos en la antlr.org sitio, todavía no puedo obtener una clara comprensión de la gramática para Java proceso.

¿Hay algún ejemplo sencillo, algo así como cuatro de las operaciones de la calculadora implementado con ANTLR pasando por el analizador definición y todo el camino hasta el código fuente de Java?

  • Que precisa ejemplo se utiliza como un tutorial en Antlr del sitio, la última vez que lo comprobé.
  • Petosky: puede que su fuente el enlace ?
  • He publicado las primeras partes de un tutorial de vídeo en ANTLR. Consulte javadude.com/articles/antlr3xtut Espero que les sea útil!
  • Yo también compartir su búsqueda.
  • La mejor respuesta para ANTLR 4 es comprar Parr del libro «La Definitiva ANTLR 4 de Referencia.»
InformationsquelleAutor Eli | 2009-12-18

5 Comentarios

  1. 441

    Nota: esta respuesta es para ANTLR3! Si estás buscando un ANTLR4 ejemplo, entonces este Q&A se muestra cómo crear un simple analizador de la expresión, y el evaluador mediante ANTLR4.


    Crear por primera vez una gramática. A continuación es una pequeña gramática que puede utilizar para evaluar expresiones que se construyen con las 4 operaciones matemáticas básicas de los operadores: +, -, * y /. También se pueden agrupar las expresiones con paréntesis.

    Tenga en cuenta que esta gramática es sólo una muy simple: no controla los operadores unarios (al menos en: -1+9) o los decimales como .99 (sin un líder en número), por citar sólo dos defectos. Este es sólo un ejemplo puede trabajar en ti mismo.

    Aquí está el contenido del archivo de gramática Exp.g:

    grammar Exp;
    
    /* This will be the entry point of our parser. */
    eval
        :    additionExp
        ;
    
    /* Addition and subtraction have the lowest precedence. */
    additionExp
        :    multiplyExp 
             ( '+' multiplyExp 
             | '-' multiplyExp
             )* 
        ;
    
    /* Multiplication and division have a higher precedence. */
    multiplyExp
        :    atomExp
             ( '*' atomExp 
             | '/' atomExp
             )* 
        ;
    
    /* An expression atom is the smallest part of an expression: a number. Or 
       when we encounter parenthesis, we're making a recursive call back to the
       rule 'additionExp'. As you can see, an 'atomExp' has the highest precedence. */
    atomExp
        :    Number
        |    '(' additionExp ')'
        ;
    
    /* A number: can be an integer value, or a decimal value */
    Number
        :    ('0'..'9')+ ('.' ('0'..'9')+)?
        ;
    
    /* We're going to ignore all white space characters */
    WS  
        :   (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;}
        ;

    (Analizador reglas comenzar con una letra minúscula, y el analizador léxico de las reglas de empezar con una letra mayúscula)

    Después de la creación de la gramática, usted querrá generar un analizador y el analizador léxico de ella. Descargar el ANTLR jar y guárdelo en el mismo directorio que el archivo de gramática.

    Ejecutar el siguiente comando en el shell/símbolo del sistema:

    java -cp antlr-3.2.jar org.antlr.Tool Exp.g

    No debe producir ningún mensaje de error, y los archivos ExpLexer.java, ExpParser.java y Exp.fichas ahora debe ser generado.

    A ver si funciona todo correctamente, crear esta clase de prueba:

    import org.antlr.runtime.*;
    
    public class ANTLRDemo {
        public static void main(String[] args) throws Exception {
            ANTLRStringStream in = new ANTLRStringStream("12*(5-6)");
            ExpLexer lexer = new ExpLexer(in);
            CommonTokenStream tokens = new CommonTokenStream(lexer);
            ExpParser parser = new ExpParser(tokens);
            parser.eval();
        }
    }

    y compilarlo:

    //*nix/MacOS
    javac -cp .:antlr-3.2.jar ANTLRDemo.java
    
    //Windows
    javac -cp .;antlr-3.2.jar ANTLRDemo.java

    y, a continuación, ejecute:

    //*nix/MacOS
    java -cp .:antlr-3.2.jar ANTLRDemo
    
    //Windows
    java -cp .;antlr-3.2.jar ANTLRDemo

    Si todo va bien, nada de lo que se imprime en la consola. Esto significa que el analizador no se encontró ningún error. Al cambiar "12*(5-6)" en "12*(5-6" y, a continuación, vuelva a compilar y ejecutar, no debe ser impreso el siguiente:

    line 0:-1 mismatched input '<EOF>' expecting ')'

    Bien, ahora queremos añadir un poco de código Java a la gramática, de modo que el intérprete realmente hace algo útil. La adición de código se puede hacer mediante la colocación de { y } en el interior de su gramática con algunas etiquetas de código Java dentro de ella.

    Pero primero: todos analizador de reglas en el archivo de gramática debe devolver una primitiva de doble valor. Usted puede hacer mediante la adición de returns [double value] después de cada regla:

    grammar Exp;
    
    eval returns [double value]
        :    additionExp
        ;
    
    additionExp returns [double value]
        :    multiplyExp 
             ( '+' multiplyExp 
             | '-' multiplyExp
             )* 
        ;
    
    //...

    que necesita poca explicación: cada regla se espera que devuelva un valor doble. Ahora para «interactuar» con el valor de retorno double value (que NO está dentro de una llanura de Java bloque de código {...}) desde el interior de un bloque de código, tendrás que añadir un signo de dólar en frente de value:

    grammar Exp;
    
    /* This will be the entry point of our parser. */
    eval returns [double value]                                                  
        :    additionExp { /* plain code block! */ System.out.println("value equals: "+$value); }
        ;
    
    //...

    Aquí está la gramática, pero ahora con el código Java añadido:

    grammar Exp;
    
    eval returns [double value]
        :    exp=additionExp {$value = $exp.value;}
        ;
    
    additionExp returns [double value]
        :    m1=multiplyExp       {$value =  $m1.value;} 
             ( '+' m2=multiplyExp {$value += $m2.value;} 
             | '-' m2=multiplyExp {$value -= $m2.value;}
             )* 
        ;
    
    multiplyExp returns [double value]
        :    a1=atomExp       {$value =  $a1.value;}
             ( '*' a2=atomExp {$value *= $a2.value;} 
             | '/' a2=atomExp {$value /= $a2.value;}
             )* 
        ;
    
    atomExp returns [double value]
        :    n=Number                {$value = Double.parseDouble($n.text);}
        |    '(' exp=additionExp ')' {$value = $exp.value;}
        ;
    
    Number
        :    ('0'..'9')+ ('.' ('0'..'9')+)?
        ;
    
    WS  
        :   (' ' | '\t' | '\r'| '\n') {$channel=HIDDEN;}
        ;

    y desde nuestra eval regla ahora devuelve un double, cambiar su ANTLRDemo.java en este:

    import org.antlr.runtime.*;
    
    public class ANTLRDemo {
        public static void main(String[] args) throws Exception {
            ANTLRStringStream in = new ANTLRStringStream("12*(5-6)");
            ExpLexer lexer = new ExpLexer(in);
            CommonTokenStream tokens = new CommonTokenStream(lexer);
            ExpParser parser = new ExpParser(tokens);
            System.out.println(parser.eval()); //print the value
        }
    }

    De nuevo (re) generar un nuevo analizador léxico y el programa de análisis de su gramática (1), compilar todas las clases (2) y ejecutar ANTLRDemo (3):

    //*nix/MacOS
    java -cp antlr-3.2.jar org.antlr.Tool Exp.g   //1
    javac -cp .:antlr-3.2.jar ANTLRDemo.java      //2
    java -cp .:antlr-3.2.jar ANTLRDemo            //3
    
    //Windows
    java -cp antlr-3.2.jar org.antlr.Tool Exp.g   //1
    javac -cp .;antlr-3.2.jar ANTLRDemo.java      //2
    java -cp .;antlr-3.2.jar ANTLRDemo            //3

    y ahora vamos a ver el resultado de la expresión 12*(5-6) impreso para tu consola!

    De nuevo: esta es una explicación muy breve. Os animo a navegar por la ANTLR wiki y leer algunos tutoriales y/o jugar un poco con lo que me acaba de publicar.

    Buena suerte!

    EDICIÓN:

    Este post muestra cómo extender el ejemplo anterior, de modo que un Map<String, Double> puede ser proporcionada que contiene las variables en la expresión.

    Para obtener este código trabajando con una versión actual de Antlr (junio de 2014) tuve que hacer un par de cambios. ANTLRStringStream necesarios para convertirse en ANTLRInputStream, el valor devuelto sea necesario para cambiar de parser.eval() a parser.eval().value, y he tenido que quitar la WS cláusula al final, debido a que los valores de atributo como $channel no aparecen en el analizador léxico de las acciones.

    • ¿De dónde viene el implemenations de parser.eval() suceder? Que no está claro AQUÍ o en la ANTLR3 Wiki!
    • err, lo siento, yo realmente no lo entiendo. eval es un analizador de la regla que devuelve un double. De modo que hay un eval() método puede llamar en una instancia de un ExpParser, tal como he demostrado en el ANTLRDemo.main(...). Después de generar un analizador léxico/parser, simplemente abra el archivo ExpParser.java y vas a ver que hay un eval() método de devolución de un double.
    • He estado investigando esto por una semana, este es el primer ejemplo que en realidad era completa y detallada suficiente para trabajar en el primer tiempo y que creo entender. Casi me había dado por vencido. Gracias!
  2. 11

    ANTLR mega tutorial por Gabriele Tomassetti es muy útil

    Ha gramática ejemplos, ejemplos de los visitantes en diferentes lenguajes (Java, JavaScript, C# y Python) y muchas otras cosas. Muy recomendable.

    EDICIÓN: otros artículos útiles por Gabriele Tomassetti en ANTLR

    • Gran tutorial!
    • Antlr ahora ha cpp también como el idioma de destino. Hay tutoriales con el ejemplo en cpp?
    • El mismo tipo hizo un tutorial para ANTLR en C++ tomassetti.me/getting-started-antlr-cpp supongo que usted va a encontrar lo que estás buscando aquí, o en el mega tutorial
  3. 7

    De Antlr 4 la generación de código java proceso es el siguiente:-

    java -cp antlr-4.5.3-complete.jar org.antlr.v4.Tool Exp.g

    Actualizar el nombre del jar en el classpath en consecuencia.

  4. 1

    A https://github.com/BITPlan/com.bitplan.antlr usted encontrará una biblioteca de java ANTLR con algunos útiles ayudante de clases y un par de ejemplos completos. Está listo para ser utilizado con maven y si te gusta eclipse y maven.

    https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/main/antlr4/com/bitplan/exp/Exp.g4

    es un simple lenguaje de Expresión que puede hacer multiplicar y operaciones de agregar.
    https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/test/java/com/bitplan/antlr/TestExpParser.java dispone de la correspondiente unidad de pruebas para ello.

    https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/main/antlr4/com/bitplan/iri/IRIParser.g4 es un IRI analizador que se ha dividido en tres partes:

    1. analizador gramatical
    2. analizador léxico gramática
    3. importados LexBasic gramática

    https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/test/java/com/bitplan/antlr/TestIRIParser.java
    tiene la unidad de pruebas para ello.

    Personalmente he encontrado este el más complicado de conseguir. Ver http://wiki.bitplan.com/index.php/ANTLR_maven_plugin

    https://github.com/BITPlan/com.bitplan.antlr/tree/master/src/main/antlr4/com/bitplan/expr

    contiene tres ejemplos que se han creado para un problema de rendimiento de ANTLR4 en una versión anterior. En el mientras tanto, este asunto ya ha sido fijada como el testcase https://github.com/BITPlan/com.bitplan.antlr/blob/master/src/test/java/com/bitplan/antlr/TestIssue994.java muestra.

  5. 0

    versión 4.7.1 fue un poco diferente :
    para la importación:

    import org.antlr.v4.runtime.*;

    para el principal segmento de la nota de la CharStreams:

    CharStream in = CharStreams.fromString("12*(5-6)");
    ExpLexer lexer = new ExpLexer(in);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    ExpParser parser = new ExpParser(tokens);

Dejar respuesta

Please enter your comment!
Please enter your name here