Puis-je utiliser un Antlr créé lexer / analyseur pour analyser PDDL des données de fichier et de retour à un programme Java?

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

  •  26-09-2019
  •  | 
  •  

Question

Je suis nouveau à Antlr, mais ont utilisé Flex / Bison avant. Je veux savoir si ce que je veux faire en utilisant Antlr est possible.

Je veux analyser un fichier PDDL en utilisant Antlr et construire ma propre représentation du contenu du fichier PDDL dans une classe Java que j'ai écrit que le fichier PDDL est analysé (dans les actions pour les règles?). Une fois le fichier terminé l'analyse syntaxique je veux revenir à la représentation de l'objet du contenu du fichier au programme Java pour exécuter d'autres opérations sur.

Donc, essentiellement, je veux invoquer un produit Antler analyseur PDDL sur un fichier PDDL à l'intérieur d'un programme Java et avoir retourner un objet qui décrit le fichier PDDL du principal programme Java.

Est-ce possible? Je l'ai essayé de regarder la documentation, mais ne l'ai pas trouvé une bonne réponse.

Merci beaucoup.

Était-ce utile?

La solution

  

Donc, essentiellement, je veux invoquer un produit Antler analyseur PDDL sur un fichier PDDL à l'intérieur d'un programme Java et avoir retourner un objet qui décrit le fichier PDDL du principal programme Java.

     

Est-ce possible?

Bien sûr.

D'abord, vous devez décrire votre langue dans un fichier de grammaire (ANTLR). Le plus simple est de le faire dans une grammaire combinée. Une grammaire combinée va créer un analyseur et pour lexer votre langue. Lorsque la langue devient plus complexe, il est préférable de séparer ces deux, mais pour commencer, il sera plus facile d'utiliser un seul (combiné) fichier de grammaire.

Disons que la langue de PDDL est juste une langue facile: il est une succession d'un ou plusieurs numéros soit en hexadécimal (0x12FD), octal (0745) ou décimal (12345) notation séparés par des espaces blancs. Ce langage peut être décrit dans le fichier de grammaire ANTLR suivante appelée 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;}
  ;

Dans cette grammaire, les règles (analyse syntaxique, nombre, Hex, ... sont des règles) qui commencent par un capital sont Lexer règles. Les autres sont l'analyseur règles.

A partir de cette grammaire, vous pouvez créer un analyseur et lexer comme ceci:

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

qui produit (au moins) les fichiers PDDLParser.java et PDDLLexer.java.

Maintenant, créez une petite classe de test dans lequel vous pouvez utiliser ces classes d'analyseurs lexicaux et syntaxiques:

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

où le contenu du fichier source.txt pourrait ressembler à ceci:

0xcAfE 0234
66678 0X12 0777

compiler tous les fichiers .java:

javac -cp antlr-3.2.jar *.java

et exécutez la classe principale:

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

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

Si tout va bien, rien n'est imprimé à la console.

Maintenant, vous dites que vous vouliez laisser le retour d'analyseur certains objets en fonction du contenu de votre fichier source. Disons que nous voulons que notre grammaire pour revenir un List<Integer>. Cela peut se faire en intégrant des « actions » dans vos règles de grammaire comme ceci:

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

Comme vous pouvez le voir, vous pouvez laisser des règles de retour des objets (returns [Type t]) et peut intégrer du code Java si simple emballage en { et }. La partie @init dans la règle de parse est placé au début de la méthode de parse dans le fichier PDDLParser.java.

Tester le nouvel analyseur avec cette classe:

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

et vous verrez les éléments suivants en cours d'impression à la console:

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

Autres conseils

Il est certainement possible, car Antlr est conçu pour générer des parseurs qui alors s'invoquaient dans le cadre d'un système plus large (par exemple, un compilateur ou un analyseur de code statique).

Commencez par Terence Parr est Le Antlr définitif Référence: Bâtiment de domaine spécifique Langues . Il est l'auteur Antlr, et aussi un enseignant exceptionnellement clair et sans jargon sur le traitement du langage.

Martin Fowler de domaine spécifiques Langues Les utilisations Antlr dans beaucoup de ses exemples. Par exemple à la page 200, il montre un simple « Bonjour tout le monde » par exemple où un programme Java appelle Antlr pour analyser un fichier de personnes à accueillir et en le faisant émet les salutations. Voilà où le travail se fait (page 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 troisième bon livre est nouveau sur DSLs modèles de mise en œuvre de Terence Langue . Il décrit les différentes façons d'utiliser Antlr, comme par exemple pour écrire un générateur d'arbre de syntaxe abstraite à mettre en un compilateur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top