2010-09-27 3 views
1

Я использую ANTLR, предоставленную грамматику ECMAScript, с целью определения глобальных переменных JavaScript. Создается AST, и теперь я задаюсь вопросом, как основан способ фильтрации глобальных объявлений переменных.Использование ANTLR для идентификации объявлений глобальных переменных в файле JavaScript

Я заинтересован в поиске всех самых дальних токенов переменной переменной в моем AST; фактическое практическое занятие - это ускользает от меня. Вот мой настроить код до сих пор:

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

Будучи новым для ANTLR может кто-нибудь предложить какие-либо указатели?

ответ

3

Я думаю, вы используете this grammar.

Хотя эта грамматика предполагает создание собственного АСТ, это не так. Он использует некоторые встроенные операторы для исключения определенных токенов из дерева синтаксического анализа, но он никогда не создает корней для дерева, что приводит к полностью плоскому дереву синтаксического анализа. Из этого вы не можете получить все глобальные варны разумным способом.

Вам нужно настроить грамматику слегка:

Добавьте следующий под options { ... } в верхней части файла грамматики:

tokens 
{ 
    VARIABLE; 
    FUNCTION; 
} 

Теперь замените следующие правила: functionDeclaration, functionExpression и variableDeclaration с этими:

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

Теперь создано более подходящее дерево. Если теперь разобрать источник:

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

следующее дерево генерируется:

alt text

Все, что вам теперь нужно сделать, это итерация над детьми корня дерева, и когда вы наткнетесь на маркете VARIABLE вы знаете, что это «глобальный», поскольку все остальные переменные будут находиться под FUNCTION узлами.

Вот как это сделать:

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

, который производит следующий вывод:

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

+1 и ответил. Большое спасибо за всесторонний ответ. –

+0

@ Кристофер, пожалуйста. –

Смежные вопросы