簡體   English   中英

使用ANTLR識別JavaScript文件中的全局變量聲明

[英]Using ANTLR to identify global variable declarations in a JavaScript file

我一直在使用ANTLR提供的ECMAScript語法,目的是識別JavaScript全局變量。 產生了一個AST,我現在想知道篩選全局變量聲明的基本方法是什么。

我有興趣在AST中尋找所有最外面的“ variableDeclaration”標記; 實際的操作方法使我難以理解。 到目前為止,這是我設置的代碼:

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的人可以提供任何指示嗎?

我猜你在用這種語法

盡管該語法表明創建了正確的AST,但事實並非如此。 它使用一些內聯運算符從分析樹中排除某些令牌,但是它從不為樹創建任何根,從而導致完全平坦的分析樹。 由此,您無法以合理的方式獲得所有全局變量。

您需要稍微調整語法:

在語法文件頂部的options { ... }下添加以下內容:

tokens
{
  VARIABLE;
  FUNCTION;
}

現在,將以下規則替換為: functionDeclarationfunctionExpressionvariableDeclaration

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;

生成以下樹:

替代文字

您現在要做的就是遍歷樹根的子代,當偶然發現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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM