Reputation: 3895
I downloaded the TL Grammar from https://raw.githubusercontent.com/bkiers/tiny-language-antlr4/master/src/main/antlr4/tl/antlr4/TL.g4
And after attempting to try it, I realized the grammar is unable to handle user defined function calls at the top-level
For example, if your file contents are:
def s(n)
return n+n;
end
s("5", "6");
And you listen for a FunctionCallExpression, you don't get a callback. However, if your file contents are:
def s(n)
return n+n;
end
s(s("5"))
you do get the call back.
Upvotes: 1
Views: 130
Reputation: 170158
Your input:
s("5", "6");
is matched by the statement (not an expression!):
functionCall
: Identifier '(' exprList? ')' #identifierFunctionCall
| ...
;
and "5", "6"
are two expressions matched by exprList
.
The first s
in your input s(s("5"))
will again match identifierFunctionCall
, and the inner s
will be matched as an expression (a functionCallExpression
to be precise).
Here are the different parse trees:
s("5", "6");
'- parse
|- block
| '- statement
| |- identifierFunctionCall
| | |- s
| | |- (
| | |- exprList
| | | |- stringExpression
| | | | '- "5"
| | | |- ,
| | | '- stringExpression
| | | '- "6"
| | '- )
| '- ;
'- <EOF>
s(s("5"));
'- parse
|- block
| '- statement
| |- identifierFunctionCall
| | |- s
| | |- (
| | |- exprList
| | | '- functionCallExpression
| | | '- identifierFunctionCall
| | | |- s
| | | |- (
| | | |- exprList
| | | | '- stringExpression
| | | | '- "5"
| | | '- )
| | '- )
| '- ;
'- <EOF>
In short: the grammar works as it is supposed to.
A valid TL script is a code block where each code block consists of statements. To simplify the grammar and eliminate some ambiguous rules (which was needed for the older ANTLRv3), it was easiest to not allow a statement to be a simple expression. For example, the following code is not a valid TL script:
1 + 2;
I.e. 1 + 2
is not a statement, but an expression.
However a function call might be a statement, but, when placed at the right hand side of an assignment statement, it could also be an expression:
foo(); // this is a statement
i = foo(); // now foo is an expression
That is why you observed one s(...)
to trigger a certain enter...()
method, while the other did not.
Upvotes: 1