Context
I am parsing vba code where ...
This code outputs the contents of the first dimension of array a to index i :
Debug.Print a(i, 1)
This code displays the result of the function a with the given parameters i and 1 :
Debug.Print a(i, 1)
This code calls the DoSomething procedure when evaluating foo as a value and passes it by value to the procedure (regardless of whether the parameter has a signature "by reference"):
DoSomething (foo)
This code calls the DoSomething procedure without evaluating foo as a value and passing it by reference if the signature accepts the "by reference" parameter:
Call DoSomething(foo)
So, I have this lExpression parser rule, which is problematic because the first alternative ( #indexExpr ) matches both the array and the procedure call:
lExpression : lExpression whiteSpace? LPAREN whiteSpace? argumentList? whiteSpace? RPAREN
Problem
The specific problem I'm trying to fix here is best described by the stack trace that I get from the parsing exception created with this code:
Sub Test() DoSomething (foo), bar End Sub

I can see the callStmt() rule, as it should, but then the expression , which must match DoSomething , matches #lExpr , which fixes what should be a "list of arguments", but instead gets selected as the index of the array.
Everything I tried, from moving #parenthesizedExpr to a higher priority than #lExpr , to the memberExpression rule and using it instead of expression in the callStmt rule, failed (project, but I end up with 1500 failed tests because I don't analyze anything else) .
The reason #lExpr corresponds to DoSomething (foo) , in particular, because itโs quite logical to have indexExpr there - as if I had to somehow ignore the rule in parsing, but only when I know that there callStmt in lines.
Is it also possible to fix the problem a(i, 1) (array call) from a(i, 1) (function call)?
If so ... how?
Additional context
Here's the expression rule from which the lExpression rule is called:
expression : // Literal Expression has to come before lExpression, otherwise it'll be classified as simple name expression instead. literalExpression
And the callStmt rule, which means only receiving procedure calls (which may or may not be preceded by the Call keyword):
callStmt : CALL whiteSpace expression | expression (whiteSpace argumentList)? ;