I am not sure to understand why arguments make a difference. Your example is strictly equivalent to the following one:
e: [ [ l = elist -> (let l = l [] in l) ] ] ;
elist:
[ [ n = INT ; ","; rv = elist -> (fun acc -> let rv = rv (n :: acc) in rv)
| -> (fun acc -> List.rev acc)
] ] ;
and it is trivial to get one from the other in a purely syntactic manner. So, whether the rules take arguments or not is irrelevant.
What matters is how you handle the return values of your rules. For instance, in your original example, you have INT
which returns an integer and e
which returns a list. If you already know how to handle those, then supporting rule arguments will be straightforward and will not require any extra use of Obj.magic
.