Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I guess you're using <a href="http://www.antlr.org/grammar/1206736738015/JavaScript.g" rel="nofollow noreferrer">this grammar</a>.</p> <p>Although that grammar suggests a proper AST is created, this is not the case. It uses some inline operators to exclude certain tokens from the parse-tree, but it never creates any roots for the tree, resulting in a completely flat parse tree. From this, you can't get all global vars in a reasonable way.</p> <p>You'll need to adjust the grammar slightly:</p> <p>Add the following under the <code>options { ... }</code> at the top of the grammar file:</p> <pre><code>tokens { VARIABLE; FUNCTION; } </code></pre> <p>Now replace the following rules: <code>functionDeclaration</code>, <code>functionExpression</code> and <code>variableDeclaration</code> with these:</p> <pre><code>functionDeclaration : 'function' LT* Identifier LT* formalParameterList LT* functionBody -&gt; ^(FUNCTION Identifier formalParameterList functionBody) ; functionExpression : 'function' LT* Identifier? LT* formalParameterList LT* functionBody -&gt; ^(FUNCTION Identifier? formalParameterList functionBody) ; variableDeclaration : Identifier LT* initialiser? -&gt; ^(VARIABLE Identifier initialiser?) ; </code></pre> <p>Now a more suitable tree is generated. If you now parse the source:</p> <pre><code>var a = 1; function foo() { var b = 2; } var c = 3; </code></pre> <p>the following tree is generated:</p> <p><img src="https://i.stack.imgur.com/Opfe5.png" alt="alt text"></p> <p>All you now have to do is iterate over the children of the root of your tree and when you stumble upon a <code>VARIABLE</code> token, you know it's a "global" since all other variables will be under <code>FUNCTION</code> nodes.</p> <p>Here's how to do that:</p> <pre><code>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)); } } } } </code></pre> <p>which produces the following output:</p> <pre><code>Found a global var: a Found a global var: c </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload