Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I faced the same perplexment when I first took a crack at it. It's a pretty obvious question/issue, which makes it more weird that it doesn't seem to be explicitly and straightforwardly addressed in tutorials.</p> <p>The way out of the perplexment that I found is the 'returns' keyword:</p> <pre><code>token returns [TreeNode value] : WORD { $value = new TreeNode( "word", $WORD.Text ); } | INT { $value = new TreeNode( "int", $INT.Text ); } ; WORD: ('a'..'z'|'A'..'Z')+; INT : ('0'..'9')+; </code></pre> <p>TreeNode is a class that I made. Where it got tricky was how to do this with a sequence of say, multiple tokens. The solution I came up with was recursion:</p> <pre><code>expr returns [Accumulator value] : a=token (WS+ b=expr)? { if( b != null ) { $value = new Accumulator( "expr", a.value, b.value ); } else { $value = new Accumulator( "expr", a.value ); } } ; </code></pre> <p>Accumulator is a class that I made that has two different constructors. One constructor encapsulates a single token, and the other encapsulates a single token and another Accumulator instance. Notice the rule itself is defined recursively, and that <code>b.value</code> is an Accumulator instance. Why? Because b is an expr, and the definition of expr has <code>returns [Accumulator value]</code>.</p> <p>The final resulting tree is a single Accumulator instance that has grouped up all the tokens. To actually use that tree, you do some setup and then call the method that has the same name as the rule with respect to which you're parsing your content:</p> <pre><code>Antlr.Runtime.ANTLRStringStream stringstream = new Antlr.Runtime.ANTLRStringStream( script ); TokenLexer lexer = new TokenLexer( stringstream ); Antlr.Runtime.CommonTokenStream tokenstream = new Antlr.Runtime.CommonTokenStream( lexer ); TokenParser parser = new TokenParser( tokenstream ); Accumulator grandtree = parser.expr().value; </code></pre> <p>Hope this helps people who encounter this perplexion.</p> <hr> <h2>Update</h2> <p>There's a more straightforward way to collect items into lists, due to how the system allows you to intersperse target-language code at what appears to be arbitrary pattern locations. The idiom is:</p> <pre><code>sequence returns [String k] : (e=atom { $k = $e.k; }) (e=atom { $k += ", " + $e.k; })* { $k = "sequence (" + $k + ")"; } ; </code></pre> <p>A string <code>k</code> gets initialized to the k value of the first atom, and subsequent atoms get <code>+=</code> to <code>k</code>. The snippet <code>$e.k</code> is referring to a <code>atom returns [String k]</code> rule defined elsewhere. If there isn't such a rule, you can use the <code>text</code> property (i.e. <code>$e.text</code>, which tokens have. I'm not sure if non-tokens have this property. If not, you can just do:</p> <pre><code>nonToken returns [String whatever] : e=TOKEN { $whatever = $e.text; } ; </code></pre> <p>Which you would then use in higher rules by e.g.</p> <pre><code>e=nonToken { System.out.println($e.whatever); } </code></pre>
    singulars
    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.
    3. VO
      singulars
      1. This table or related slice is empty.
    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