java - Rule variables in ANTLR4 -


i'm trying convert grammar v3 v4 , having trouble.

in v3 have rules this:

dataspec[datalayout layout] returns [dataextractor extractor]     @init {         dataextractorbuilder builder = new dataextractorbuilder(layout);     }     @after {         extractor = builder.create();     }     : first=expr { builder.addall(first); } (comma next=expr { builder.addall(next); })*      ;  expr returns [list<valueextractor> ext]     ... 

however, rules in v4 returning these custom context objects instead of explicitly told them return, things messed up. what's v4 way this?

there multiple cases here:

  • accessing passed-in variables (layout)
  • accessing current rule's return value (extractor)
  • accessing local variables (first, next)

passed-in variables , current rule's return value

when accessing passed-in variables or return value of current rule need prefix name given in rule definition $.

  • layout becomes $layout
  • extractor becomes $extractor

local variables

evidently needs done reference variables' member named according returns clause of rule returned value.

for example, first capturing result expr rule, , expr names return value ext, meaning that:

  • first becomes $first.ext
  • next becomes $next.ext

when use $ form

unlike in v3 reference variables regular java fields, using $ form necessary in all cases, including in actions, in @init , @after blocks, , when passing variables other rules.

other traps

if you're capturing optional tokens in local variable, may run null pointer exceptions you're referencing attribute of variable.

single_lname returns [string s]     : p=lname_prefix? r=name { $p.text + tonamecase($r.text); } ; 

you'll need check whether $p null, of time result in "missing attribute access" error. antlr4 makes special exception can check this, only applies when used in if condition (refactoring use ternary operator, example, still result in error).

single_lname returns [string s]     : p=lname_prefix? r=name {          if ($p == null) {             $s = tonamecase($r.text);         } else {             $s = $p.text + tonamecase($r.text);         }     } ; 

the updated rule

putting together, dataspec rule becomes:

dataspec[datalayout layout] returns [dataextractor extractor]     @init {         dataextractorbuilder builder = new dataextractorbuilder($layout);     }     @after {         $extractor = builder.create();     }     : first=expr { builder.addall($first.ext); }         (comma next=expr { builder.addall($next.ext); })*      ; 

Comments

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -