J'essaie d'utiliser Antlr pour certaines fonctions de type IDE de texte - en particulier l'analyse d'un fichier pour identifier les points de pliage du code et pour appliquer la coloration syntaxique.

Première question : Antlr convient-il à cette exigence ou est-il excessif ? Cela pourrait être réalisé à l'aide de regex et/ou d'un analyseur syntaxique à la main... mais il semble qu'Antlr soit là pour faire ce travail pour moi.

J'ai parcouru le ... et l'excellente ressource de didacticiel ici.

J'ai réussi à créer une grammaire Java (en utilisant la grammaire standard) et à tout analyser soigneusement dans un arbre. Cependant, je me serais attendu à voir des éléments imbriqués dans l'arbre. En réalité, tout est enfant de l'élément le plus élevé.

Par exemple. Étant donné:

package com.example
public class Foo {
   String myString = "Hello World"
   // etc
}

Je me serais attendu à ce que le nœud d'arbre pour Foo soit un enfant du nœud pour la déclaration de package. De même, myString serait un enfant de Foo.

Au lieu de cela, je trouve que Foo et myString (et tout le reste d'ailleurs) sont tous des enfants de package.

Voici l'extrait pertinent faisant l'analyse :

public void init() throws Exception {
    CharStream c = new ANTLRFileStream(
            "src/com/inversion/parser/antlr/Test.code");

    Lexer lexer = new JavaLexer(c);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    JavaParser parser = new JavaParser(tokens);
    parser.setTreeAdaptor(adaptor);

    compilationUnit_return result = parser.compilationUnit();
}

static final TreeAdaptor adaptor = new CommonTreeAdaptor() {
    public Object create(Token payload) {
        if (payload != null)
        {
            System.out.println("Create " + JavaParser.tokenNames[payload.getType()] + ":  L" + payload.getLine() + ":C" + payload.getCharPositionInLine() + " " + payload.getText());
        }
        return new CommonTree(payload);
    }
};

L'examen de result.getTree() renvoie une instance CommonTree, dont les enfants sont le résultat de l'analyse.

Valeur attendue (peut-être incorrecte)

package com.example (4 tokens)
   |
   +-- public class Foo (3 tokens)
        |
        +--- String myString = "Hello World" (4 tokens)
        +--- Comment "// etc"

(ou quelque chose de similaire)

Valeur réelle (Toutes les valeurs sont des enfants du nœud racine de result.getTree() )

package
com
.
example
public
class
Foo
String
myString
=
"Hello World"

Ma compréhension de la façon dont cela devrait fonctionner est-elle correcte ?

Je suis un noob complet à Antlr jusqu'à présent, et je trouve la courbe d'apprentissage assez raide.

6
Marty Pitt 24 nov. 2009 à 17:46
Pouvez-vous montrer l'arbre tel que vous le trouvez, et l'arbre tel que vous l'auriez imaginé ?
 – 
Svante
24 nov. 2009 à 18:17
3
Soit dit en passant, l'analyse des langages non réguliers ne peut PAS être réalisée avec des expressions régulières. Chaque fois que vous voyez « tree », « récursif » ou « imbriqué », pensez « pas d'expression régulière ».
 – 
Svante
24 nov. 2009 à 18:20
- Bien sûr - J'ai élargi le rapport attendu par rapport au réel dans le message. J'espère que cela t'aides.
 – 
Marty Pitt
24 nov. 2009 à 19:04
Yo Marty. J'ai utilisé ANTLR pour créer un coloriseur de syntaxe dans un IDE, donc je peux garantir que c'est possible. Si cela peut vous aider, en voici la source : code.google.com/p/pen-ui/source/browse/trunk/slippy/src/org/…. Si vous fouillez dans cet arbre et dans ../olive/, cela pourrait aider. (C'est pour une langue idiote à moi)
 – 
Gabe Johnson
25 nov. 2009 à 00:50

2 réponses

Meilleure réponse

La grammaire Java-6 en haut de la section de partage de fichiers sur antlr.org n'inclut pas la création d'arborescence. Vous devrez faire deux choses. Tout d'abord, dites à ANTLR que vous souhaitez créer un AST :

options {
    output=AST;
}

Deuxièmement, vous devez lui dire à quoi devrait ressembler l'arbre en utilisant les opérateurs d'arbre ou en utilisant les règles de réécriture. Voir la documentation sur la construction d'arbres. Je finis généralement par faire une combinaison des deux.

6
Kaleb Pederson 3 déc. 2009 à 22:13

Pour construire l'arborescence, vous devez définir output=AST. (Arbre de syntaxe abstrait)

Pour autant que je sache, dans un ANTLR, un seul jeton peut être la racine d'un arbre, vous ne pouvez donc pas obtenir exactement ce que vous recherchez, mais vous pouvez vous en approcher.

Vérifier: http://www.antlr.org/wiki/display/ANTLR3/Tree+ chantier

1
rogueg 24 nov. 2009 à 21:15