Kann ich eine Antlr verwenden erstellt Lexer / Parser Parse PDDL Datei und Rückgabedaten zu einem Java-Programm?

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

  •  26-09-2019
  •  | 
  •  

Frage

Ich bin neu in Antlr, sondern verwenden Flex / Bison vor. Ich möchte wissen, ob das, was ich tun möchte mit Antlr möglich ist.

Ich möchte eine PDDL Datei mit Antlr analysieren und meine eigene Darstellung der in einer Java-Klasse Inhalt der PDDL Datei aufzubauen, dass ich schrieb als die PDDL Datei analysiert wird (in den Aktionen für die Regeln?). Nachdem die Datei Parsen beendet Ich möchte die Objektdarstellung der Inhalt der Datei auf das Java-Programm zurückzukehren auf andere Operationen auszuführen.

So im Wesentlichen, möchte ich ein Geweih produziert auf einer PDDL Datei PDDL Parser aufrufen aus dem Inneren eines Java-Programm und haben es ein Objekt zurückgeben, das die PDDL-Datei in das Haupt Java-Programm beschreibt.

Ist das möglich? Ich habe versucht, in der Dokumentation suchen, haben aber festgestellt keine gute Antwort.

Vielen Dank.

War es hilfreich?

Lösung

  

So im Wesentlichen, möchte ich ein Geweih produziert auf einer PDDL Datei PDDL Parser aufrufen aus dem Inneren eines Java-Programm und haben es ein Objekt zurückgeben, das die PDDL-Datei in das Haupt Java-Programm beschreibt.

     

Ist das möglich?

Klar.

Zuerst müssen Sie Ihre Sprache in einer (ANTLR) Grammatikdatei beschreiben. Am einfachsten ist dies in einer kombinierten Grammatik zu tun. Eine kombinierte Grammatik wird ein Lexer und Parser für Ihre Sprache erstellen. Wenn die Sprache komplexer wird, ist es besser, diese beiden zu trennen, aber zu beginnen, wird es leichter sein, nur eine (kombiniert) Grammatikdatei zu verwenden.

Lassen Sie uns sagen, dass die PDDL Sprache ist nur eine einfache Sprache: es ist eine Folge von einer oder mehreren Nummern entweder in hexadezimal (0x12FD), Oktal (0745) oder dezimal (12345) Notation von weißen Leerzeichen getrennt. Diese Sprache kann in der folgenden ANTLR Grammatikdatei namens PDDL.g beschrieben werden:

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;}
  ;

In dieser Grammatik, die Regeln (Parsing, Anzahl, Hex, ... sind Regeln), die mit einem Kapital Lexer-Regeln beginnen. Die anderen sind Parser-Regeln.

Von dieser Grammatik können Sie einen Lexer und Parser wie folgt erstellen:

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

, die (zumindest) die Dateien PDDLParser.java und PDDLLexer.java produziert.

Erstellen Sie nun eine kleine Testklasse, in dem Sie diese Lexer und Parser-Klassen verwenden können:

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();
    }
}

, wo der Inhalt der source.txt Datei könnte wie folgt aussehen:

0xcAfE 0234
66678 0X12 0777

Sie nun alle .java Dateien kompiliert:

javac -cp antlr-3.2.jar *.java

und die Hauptklasse laufen:

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

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

Wenn alles gut geht, wird nichts auf die Konsole ausgegeben werden.

Jetzt sagen Sie, Sie über den Inhalt der Quelldatei der Parser Rückkehr bestimmte Objekte basierend lassen wollte. Lassen Sie uns sagen, dass wir unsere Grammatik wollen eine List<Integer> zurückzukehren. Dies kann durch die Einbettung von „Aktionen“ in den Grammatikregeln wie dies getan werden:

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;}
  ;

Wie Sie sehen können, können Sie Regeln lassen Objekte zurück (returns [Type t]) und kann schlicht Java-Code einbetten, wenn es in { und } Verpackung. Der @init Teil in der parse Regel wird zu Beginn der parse Methode in der PDDLParser.java Datei gespeichert.

Testen Sie die neuen Parser mit dieser Klasse:

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);
    }
}

und Sie werden sehen, die folgende auf der Konsole ausgegeben werden:

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

Andere Tipps

Dies ist sicherlich möglich, da Antlr ausgelegt ist Parser zu erzeugen, die dann als Teil eines größeren Systems aufgerufen erhalten (zB ein Compiler oder eine statische Code-Analyse).

Starten Sie mit Terence Parr ist The Definitive Antlr Referenz: Gebäude Domain-Specific Languages ??. Er ist der Autor Antlr, und auch ein ungewöhnlich klaren und Jargon freie Lehrer auf der Sprachverarbeitung.

Martin Fowler Domain-Specific Languages ?? Anwendungen Antlr in vielen seiner Beispiele. Zum Beispiel auf Seite 200 zeigt er eine einfache „Hallo Welt“ Beispiel, in dem ein Java-Programm Antlr eine Datei von Menschen greet zu analysieren Anrufe und beim Tun gibt er die Grüße. Hier ist, wo die Arbeit getan wird (Seite 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) ;
    }
  }

Ein drittes gutes Buch ist neu Terence auf DSLs Sprache Implementation Patterns . Er beschreibt verschiedene Möglichkeiten, Antlr zu verwenden, wie zum Beispiel eines abstrakten Syntaxbaum-Generator schreiben in einen Compiler zu setzen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top