OK, found the solution by turning off standard tree construction.
> basicRE : simpleRE ((CONCAT^) simpleRE)*;
Now, instead of expecting a CONCAT operator, a CONC node is inserted
into the AST:
basicRE : a:simpleRE (! b:simpleRE {#basicRE = #([CONC,"conc"], #a, #b); } )* ;