Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>Can I perform this rearrangement during tree construction, or should I write a tree grammar?</p> </blockquote> <p>It's possible to do either, but I recommend grouping the nodes during token parsing. </p> <p>I haven't been happy with any tree-rewriting grammars I've written that group nodes because those grammars have to rediscover where each groupable node is at -- hence the need for grouping. The token parser touches all that data during regular processing, and the tree grammar ends up walking the tree for those nodes exactly like the token parser already walked its input for tokens. I don't think the tree parser is worth the hassle if it's <em>just</em> for grouping.</p> <p>Anyway, managing the grouping in the parser boils down to saving off the <code>decl</code> and <code>assign</code> nodes after they're produced then pushing them out again when their grouping level occurs. Here's a quick example.</p> <h3>Declarative.g</h3> <pre><code>grammar Declarative; options { output = AST; } tokens { PROGRAM; DECLARATIONS; ASSIGNMENTS; } @parser::header { import java.util.ArrayList; } @members { private ArrayList&lt;Object&gt; assigns = new ArrayList&lt;Object&gt;(); private ArrayList&lt;Object&gt; decls = new ArrayList&lt;Object&gt;(); private Object createTree(int ttype, ArrayList&lt;Object&gt; children) { Object tree = adaptor.create(ttype, tokenNames[ttype]); for (Object child : children){ adaptor.addChild(tree, child); } return tree; } } compilationUnit : statement* EOF -&gt; ^(PROGRAM {createTree(DECLARATIONS, decls)} {createTree(ASSIGNMENTS, assigns)}); statement : decl {decls.add($decl.tree);} | assign {assigns.add($assign.tree);} ; decl : DECL^ ID; assign : ASSIGN^ ID INT; DECL : 'decl'; ASSIGN : 'assign'; ID : ('a'..'z'|'A'..'Z')('a'..'z'|'A'..'Z')*; INT : ('0'..'9')+; WS : (' '|'\t'|'\f'|'\n'|'\r'){skip();}; </code></pre> <p>Each <code>decl</code> node is saved off by the <code>statement</code> rule in the <code>decls</code> list, and similarly for for each <code>assign</code> node.</p> <p>Method <code>createTree</code> uses the parser's <code>TreeAdaptor</code> to build the group nodes and populate them.</p> <pre><code>CommonTree tree = (CommonTree) adaptor.create(ttype, tokenNames[ttype]); for (Object child : children){ adaptor.addChild(tree, child); } return tree; </code></pre> <p>The production for <code>compilationUnit</code> is <code>^(PROGRAM {createTree(DECLARATIONS, decls)} {createTree(ASSIGNMENTS, assigns)})</code>, which adds the grouping nodes to <code>PROGRAM</code>. Method <code>createTree</code> is used to build the grouping node and its children in one go. </p> <p>There may be a tricky way to get ANTLR to pull it all together for you, but this works and is fairly self-explanatory. </p> <p>So given this input...</p> <pre><code>decl x assign y 2 assign x 1 decl y </code></pre> <p>... the token parser produced for the grammar above produces this tree as output:</p> <pre><code>(PROGRAM (DECLARATIONS (decl x) (decl y)) (ASSIGNMENTS (assign y 2) (assign x 1))) </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

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