Herramientas de usuario

Herramientas del sitio


otros:antlr

¡Esta es una revisión vieja del documento!


ANTLR

ANTLR (ANother Tool for Language Recognition, otra herramienta para reconocimiento de lenguajes) es la herramienta más utilizada actualmente para construir parsers, interpretes, compiladores y traductores de lenguajes a partir de gramáticas.

Estructura de un fichero de ANTLR

Un fichero para ANTLR tiene la extensión .g, debe definir en su primera línea el tipo de gramática que va a generar (lexer grammar, parser grammar o grammar) y el nombre de esta (que ha de ser el mismo que el nombre del fichero .g). Luego seguirán las opciones y demás secciones las cuales son opcionales, y al final la definición de la gramática…

grammar test;
r : 'call' ID ';' {System.out.println("invoke "+$ID.text);} ;
ID: 'a'..'z'+ ;
WS: (' '|'\n'|'\r')+   {$channel=HIDDEN;} ; // ignore whitespace

Este código se genera en Java (por defecto), cada vez que encuentre un call algo; será lanzado el System.out.println.

Opciones

Las opciones nos permiten definir la generación del resultado. Por ejemplo podemos definir el código generado, ANTLR permite generar resultados en gran variedad de lenguajes (C, Java, C#, Python…), para definir el lenguaje utilizaremos la “clave” language:

grammar FQL;
options {
     language = Java;
}

Sección @header

En esta sección agregaremos la cabecera para el archivo de código resultado, esta tendrá la definición del paquete, los imports, los using…

@header {
     package bbejeck.antlr.fql;
}

Sección @members

Código que se añadirá al parser generado (aquí podremos poner nuestras funciones dentro de la clase).

Sección @rulecatch

Cada regla de un parser es convertida a una llamada a un método dentro de un bloque try - catch. Podemos definir el bloque catch a partir de esta sección:

@rulecatch{
    catch (RecognitionException e){
            throw e;
      }
}

Notas

Apuntes

Signos de gramática

Signos Significado
. Todo
* Puede existir, no existir o existir varias veces
+ Ha de existir al menos una vez
? Opcional
~ Negación
(x|y|z) Regla x, y o z
EOF Final de línea

Pequeños apuntes

  • Se distinguen los identificadores en mayúsculas (reglas de parser que permiten devolver elementos) de minúsculas (tokens léxicos).
  • AntlrWorks es el IDE diseñado para montar gramáticas.
  • Los tokens 'fragment' no son tokens pero sí que forman parte de otros.

Cuando tengamos varias reglas con las que case lo introducido podremos hacer alias de los tokens (si únicamente fuese uno podríamos hacer $PLAYER.text:

infouser : COMS p1=PLAYER COMS VERB COMS p2=PLAYER COMS WITH COMS GUN COMS (PARENT1 parameter PARENT2)* { print 'oh! > ', $p1.text, $p2.text }

Cuando queremos añadir un atributo:

player returns [ value ]: STRVALUE MAYOR NUMBER MENOR MAYOR STEAMDEF steam=NUMBER MENOR MAYOR (IDENTIFIER)* MENOR {$value = $steam.text};
infouser : COMS p1=player COMS VERB COMS p2=player COMS WITH COMS GUN COMS (PARENT1 parameter PARENT2)* { print 'oh! > ', $p1.value, $p2.value }

Lidiar con un retorno de lista (CSharp):

list returns [ List<string> ValueList ]
    @init { $ValueList = new List<string>(); }
    : '[]'
    | '[' value {$ValueList.Add(value);} (COMMA value {$ValueList.Add(value);})* ']' ;

Lidiar con atributos opcionales:

species	returns [int count] : atom DIGITS? { $count = int($DIGITS.text) if $DIGITS else 0 } ;

Podemos retornar varios valores:

foo returns [a, b, c]
  :  A B C            {a=$A.text; b=$B.text; b=$C.text}
  ;

Podemos inicializar valores dentro de reglas con @init:

calculate_mw returns [float mw]
@init { $mw = 0.0 }
: (species { $mw += $species.species_weight})* EOF ;

Para aprovechar la salida de un parser podremos hacer:

*** Fichero gramática (regla principal '') ****
[...]
calculate_mw returns [float mw]
@init { $mw = 0.0 }
: (species { $mw += $species.species_weight})* EOF ;
[...]
*** Fichero de código *************
[...]
def calculate_mw(formula):
    char_stream = antlr3.ANTLRStringStream(formula)
    lexer = MWGrammarLexer(char_stream)
    tokens = antlr3.CommonTokenStream(lexer)
    parser = MWGrammarParser(tokens)
    return parser.calculate_mw()
[...]

Atributos de tokens:

  • text

Documentos

General

Python

otros/antlr.1359499016.txt.gz · Última modificación: 2020/05/09 09:25 (editor externo)