Wait... what is a "cut"? A minimal sample that show how it help with the error messages?
With this grammar:
expr: expr '+' term | term
And this input: 5 +
It will first consider the first alternative (expr '+' term) but will fail to match that branch because it's missing the "term" after the "+". That's fine because there's another alternative to try (term). That alternative doesn't match either, and you'll get the error message from the last alternative that it tried (probably something like "unexpected +").But with this grammar:
expr: expr '+' <cut> term | term
Then with the same input ("5 +") it will consider the first alternative, fail to match, and then fail immediately with the error message from that first alternative (something like "missing term after +"). expr: expr '+' API_call_here? term | termso
expr : atom (op <cut> expr)*
Would be replaced with expr : atom (op (expr / cut))*
cut : "XXX"?
or perhaps simpler expr : atom (op expr?)*
Either way when you process the expr rule there will be an empty match where the rhs should be, and an appropriate error can be generated