Advice on how to componentize and later combine source code?

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.