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.
2 réponses
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.
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
Questions connexes
De nouvelles questions
java
Java est un langage de programmation de haut niveau. Utilisez cette balise lorsque vous rencontrez des problèmes pour utiliser ou comprendre la langue elle-même. Cette balise est rarement utilisée seule et est le plus souvent utilisée en conjonction avec [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] et [maven].