0

Pour un projet Compilers, je dois trouver un motif dans un fichier Java. Par exemple, si je saisis "@x = 3", le programme doit retourner chaque fois que 3 est attribué à quelque chose.Comment faire pour définir dynamiquement la classe d'un argument de fonction?

Pour cela, j'utilise ASTParser de JDT. Je parser le fichier et obtenir un objet CompilationUnit, comme ceci:

private static CompilationUnit getAST(char[] unit){ 

    ASTParser parser = ASTParser.newParser(AST.JLS8); 
    parser.setKind(ASTParser.K_COMPILATION_UNIT); 
    parser.setSource(unit); // set source 

    parser.setResolveBindings(true); // we need bindings later on 
    parser.setBindingsRecovery(true); 

    Map options = JavaCore.getOptions(); 
    parser.setCompilerOptions(options); 

    CompilationUnit cu = (CompilationUnit) parser.createAST(null); 

    return cu; 

} 

Maintenant, ce que je fais est la construction d'une autre AST en fonction du modèle m'a donné. L'exemple ci-dessus donne quelque chose comme:

AssignementExpression 
LHS 
    Pattern("@x") 
RHS 
    Literal("3") 

Puis-je utiliser cette AST pour rechercher l'CompilationUnit. Le problème est que l'API ASTParser class pour rechercher des nœuds doit connaître la classe du nœud que je visite.

Je dois créer un nouvel objet de visiteur et de définir ce que je veux faire dans la fonction de visite:

ASTVisitor visitor = (new ASTVisitor() { 

     public boolean visit(VariableDeclarationFragment node) { 

      // what I want to do 

      return true; // do not continue 
     } 
} 

Donc ce que je veux faire est, dans l'exécution, AssignementExpression associé avec VariableDeclarationFragment et appelez la visite fonctionne avec VariableDeclarationFragment. Quelque chose comme:

Class nodeType = getTypeFromGrammar("AssignementExpression"); 

ASTVisitor visitor = (new ASTVisitor() { 

     public boolean visit(nodeType node) { // use the class that was returned above 

      // what I want to do 

      return true; // do not continue 
     } 
} 
+0

Je ne suis pas sûr que je comprends. Comment pourrais-je utiliser le casting pour appeler une visite avec la classe que je veux? – jazzchipc

Répondre

1

Une approche consiste à utiliser la réflexion.

Vous voudrez utiliser une sous-classe nommée ASTVisitor plutôt qu'une classe anonyme. Disons que ça s'appelle MyAstVisitor. Il peut remplacer plusieurs des méthodes ASTVisitor.visit(T).

Vous pouvez obtenir la méthode appropriée avec Class.getMethod(). Par exemple:

Method visitMethod = MyASTVistor.class.getMethod("visit", nodeType); 

Ensuite, vous pouvez appeler la méthode avec Method.invoke():

visitMethod.invoke(myAstVisitorInstance, myNode); 
+0

Ok. Je ne pensais pas créer une nouvelle sous-classe que je pourrais contrôler. Je vais essayer de faire comme vous le dites et revenir avec des commentaires. – jazzchipc

+0

Vos exemples montrent la création d'une sous-classe anonyme. Si vous ne voulez pas de sous-classe, vous pouvez utiliser 'ASTVisitor.class.getMethod (...)'. –

+0

Oui, je sais. Mais je ne me souviens pas que créer une sous-classe serait la meilleure façon de le faire. J'ai finalement réussi à le faire fonctionner. Merci! – jazzchipc