¿Puedo utilizar un Antlr creado léxico / analizador para analizar PDDL datos del archivo y volver a un programa Java?

StackOverflow https://stackoverflow.com/questions/3818442

  •  26-09-2019
  •  | 
  •  

Pregunta

Soy nuevo en Antlr, pero he utilizado Flex / bisonte antes. Quiero saber si lo que yo quiero hacer uso de Antlr es posible.

Quiero analizar un archivo usando PDDL Antlr y construir mi propia representación de los contenidos del archivo PDDL en una clase Java que escribí que el archivo se analiza PDDL (en las acciones de las reglas?). Después de que el archivo haya terminado el análisis Quiero devolver la representación de objetos de contenido del archivo al programa Java para ejecutar otras operaciones en.

Así que, esencialmente, quiero invocar una cornamenta produjo analizador PDDL en un archivo PDDL desde dentro de un programa Java y tienen que devolver un objeto que describe el archivo PDDL al programa principal de Java.

¿Es esto posible? He intentado buscar en la documentación, pero no he encontrado una buena respuesta.

Muchas gracias.

¿Fue útil?

Solución

  

Así que, esencialmente, quiero invocar una cornamenta produjo analizador PDDL en un archivo PDDL desde dentro de un programa Java y tienen que devolver un objeto que describe el archivo PDDL al programa principal de Java.

     

¿Es esto posible?

Claro.

En primer lugar usted necesita para describir la lengua en un (antlr) archivo de gramática. Lo más fácil es hacer esto en una gramática combinada. Una gramática combinada creará un analizador léxico y analizador para su idioma. Cuando el lenguaje se vuelve más complejo, es mejor separar estos dos, pero para empezar a cabo, será más fácil de usar un solo archivo de gramática (combinado).

Supongamos que el idioma PDDL es sólo un idioma fácil: se trata de una sucesión de uno o más números, ya sea en formato hexadecimal (0x12FD), octal (0745) o decimal (12345) notación separados por espacios en blanco. Este lenguaje puede ser descrito en el siguiente archivo de gramática antlr llamada PDDL.g:

grammar PDDL;

parse
  :  number+ EOF
  ;

number
  :  Hex
  |  Dec
  |  Oct
  ;

Hex
  :  '0' ('x' | 'X') ('0'..'9' | 'a'..'f' | 'A'..'F')+
  ;

Dec
  :  '0'
  |  '1'..'9' ('0'..'9')*
  ;

Oct
  :  '0' '0'..'7'+
  ;

Space
  :  (' ' | '\t' | '\r' | '\n'){$channel=HIDDEN;}
  ;

En esta gramática, las reglas (de análisis, número, Hex, ... son las reglas) que se inicia con un capital son lexer-reglas. Los otros son analizador-reglas.

A partir de esta gramática, se puede crear un analizador léxico y analizador de esta manera:

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

que produce (al menos) el PDDLParser.java archivos y PDDLLexer.java.

Ahora crea un poco de clase de prueba en el que se puede utilizar estas clases analizadoras y analizador:

import org.antlr.runtime.*;
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        File source = new File("source.txt");
        ANTLRInputStream in = new ANTLRInputStream(new FileInputStream(source));
        PDDLLexer lexer = new PDDLLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        PDDLParser parser = new PDDLParser(tokens);
        parser.parse();
    }
}

donde el contenido del archivo source.txt podría tener este aspecto:

0xcAfE 0234
66678 0X12 0777

Ahora compila todos los archivos .java:

javac -cp antlr-3.2.jar *.java

y ejecutar la clase principal:

// Windows
java -cp .;antlr-3.2.jar Main

// *nix/MacOS
java -cp .:antlr-3.2.jar Main

Si todo va bien, nada se imprime en la consola.

Ahora usted dice que quería que las analizador de retorno ciertos objetos basándose en el contenido de su archivo de origen. Digamos que queremos nuestra gramática para devolver una List<Integer>. Esto se puede hacer mediante la incorporación de "acciones" en las reglas de la gramática de esta manera:

grammar PDDL;

parse returns [List<Integer> list]
@init{$list = new ArrayList<Integer>();}
  :  (number {$list.add($number.value);})+ EOF
  ;

number returns [Integer value]
  :  Hex {$value = Integer.parseInt($Hex.text.substring(2), 16);}
  |  Dec {$value = Integer.parseInt($Dec.text);}
  |  Oct {$value = Integer.parseInt($Oct.text, 8);}
  ;

Hex
  :  '0' ('x' | 'X') ('0'..'9' | 'a'..'f' | 'A'..'F')+
  ;

Dec
  :  '0'
  |  '1'..'9' ('0'..'9')*
  ;

Oct
  :  '0' '0'..'7'+
  ;

Space
  :  (' ' | '\t' | '\r' | '\n'){$channel=HIDDEN;}
  ;

Como se puede ver, se puede dejar que las reglas vuelven objetos (returns [Type t]) y puede incrustar código Java normal si envolviéndolo en { y }. La parte @init en la regla parse se coloca al comienzo del método parse en el archivo PDDLParser.java.

Prueba el nuevo analizador con esta clase:

import org.antlr.runtime.*;
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        File source = new File("source.txt");
        ANTLRInputStream in = new ANTLRInputStream(new FileInputStream(source));
        PDDLLexer lexer = new PDDLLexer(in);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        PDDLParser parser = new PDDLParser(tokens);
        List<Integer> numbers = parser.parse();
        System.out.println("After parsing :: "+numbers);
    }
}

y verá lo siguiente que se imprime en la consola:

After parsing :: [51966, 156, 66678, 18, 511]

Otros consejos

Esto es ciertamente posible, ya que Antlr está diseñado para generar programas de análisis que a continuación, obtener invocada como parte de un sistema más grande (por ejemplo, un compilador o un analizador de código estático).

Comenzar con Terence Parr es The Definitive Antlr Referencia: Edificio Específico de dominio Idiomas . Él es el autor Antlr, y también un maestro inusualmente clara y libre de jerga en el procesamiento del lenguaje.

Específico de dominio Idiomas usos Antlr en gran parte de su ejemplos. Por ejemplo, en la página 200 se muestra un simple "Hola Mundo" ejemplo en el que un programa Java llama Antlr a analizar un archivo de personas para saludar, y mientras lo hace emite los saludos. Aquí es donde se realiza el trabajo (página 206):

class GreetingsLoader. ..
  public void run() {
    try {
      GreetingsLexer lexer = new GreetingsLexer(new ANTLRReaderStream(input));
      GreetingsParser parser = new GreetingsParser(new CommonTokenStream(lexer));
      parser.helper = this;
      parser.script() ;
      if (hasErrors() ) throw new RuntimeException("it all went pear-shaped\n" +
 errorReport() ) ;
    } catch (IOException e) {
      throw new RuntimeException( e) ;
    } catch (RecognitionException e) {
      throw new RuntimeException( e) ;
    }
  }

Un libro tercero es buena nueva de Terence en DSL Patrones implementación del lenguaje . Él describe diversas maneras de utilizar Antlr, como por ejemplo escribir un generador de árbol de sintaxis abstracta para poner en un compilador.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top