この文法を使用していると思います。
その文法は適切な AST が作成されることを示唆していますが、そうではありません。いくつかのインライン演算子を使用して特定のトークンを解析ツリーから除外しますが、ツリーのルートを作成しないため、完全にフラットな解析ツリーになります。このことから、合理的な方法ですべてのグローバル変数を取得することはできません。
文法を少し調整する必要があります。
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;
次のツリーが生成されます。

あとは、ツリーのルートの子を反復処理するだけです。トークンに出くわすと、他のすべての変数がノード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