2010-09-27 6 views
1

J'ai utilisé la grammaire ECMAScript fournie par ANTLR dans le but d'identifier les variables globales JavaScript. Un AST est produit et je me demande maintenant quelle est la manière de filtrer les déclarations de variables globales.Utilisation de ANTLR pour identifier les déclarations de variables globales dans un fichier JavaScript

Je suis intéressé par la recherche de tous les jetons "variableDeclaration" les plus externes dans mon AST; le comment-faire-ceci m'élude bien cependant. Voici mon mis en place un code à ce jour:

String input = "var a, b; var c;"; 
CharStream cs = new ANTLRStringStream(input); 

JavaScriptLexer lexer = new JavaScriptLexer(cs); 

CommonTokenStream tokens = new CommonTokenStream(); 
tokens.setTokenSource(lexer); 

JavaScriptParser parser = new JavaScriptParser(tokens); 

program_return programReturn = parser.program(); 

Étant nouveau ANTLR quelqu'un peut-il offrir des pointeurs?

Répondre

3

Je suppose que vous utilisez this grammar.

Bien que cette grammaire suggère qu'une AST appropriée est créée, ce n'est pas le cas. Il utilise certains opérateurs en ligne pour exclure certains jetons de l'arbre d'analyse, mais il ne crée jamais de racines pour l'arbre, ce qui donne un arbre d'analyse complètement plat. De cela, vous ne pouvez pas obtenir toutes les vars globales d'une manière raisonnable.

Vous devrez ajuster la grammaire légèrement:

Ajoutez les lignes suivantes sous la options { ... } en haut du fichier de grammaire:

tokens 
{ 
    VARIABLE; 
    FUNCTION; 
} 

remplacent maintenant les règles suivantes: functionDeclaration, functionExpression et variableDeclaration avec ceux-ci:

functionDeclaration 
    : 'function' LT* Identifier LT* formalParameterList LT* functionBody 
    -> ^(FUNCTION Identifier formalParameterList functionBody) 
    ; 

functionExpression 
    : 'function' LT* Identifier? LT* formalParameterList LT* functionBody 
    -> ^(FUNCTION Identifier? formalParameterList functionBody) 
    ; 

variableDeclaration 
    : Identifier LT* initialiser? 
    -> ^(VARIABLE Identifier initialiser?) 
    ; 

Maintenant, un arbre plus approprié est généré. Si vous analysez maintenant la source:

var a = 1; function foo() { var b = 2; } var c = 3; 

l'arbre suivant est généré:

alt text

Tout ce que vous avez maintenant à faire est itérer sur les enfants de la racine de votre arbre et quand vous trébuchez sur un jeton VARIABLE, vous savez que c'est un "global" puisque toutes les autres variables seront sous FUNCTION nœuds.

est ici comment faire:

import org.antlr.runtime.*; 
import org.antlr.runtime.tree.*; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     String source = "var a = 1; function foo() { var b = 2; } var c = 3;"; 
     ANTLRStringStream in = new ANTLRStringStream(source); 
     JavaScriptLexer lexer = new JavaScriptLexer(in); 
     CommonTokenStream tokens = new CommonTokenStream(lexer); 
     JavaScriptParser parser = new JavaScriptParser(tokens); 
     JavaScriptParser.program_return returnValue = parser.program(); 
     CommonTree tree = (CommonTree)returnValue.getTree(); 
     for(Object o : tree.getChildren()) { 
      CommonTree child = (CommonTree)o; 
      if(child.getType() == JavaScriptParser.VARIABLE) { 
       System.out.println("Found a global var: "+child.getChild(0)); 
      } 
     } 
    } 
} 

qui produit la sortie suivante:

Found a global var: a 
Found a global var: c 
+0

+1 et une réponse. Merci beaucoup pour la réponse complète. –

+0

@Christopher, de rien. –

Questions connexes