halivingston
halivingston

Reputation: 3895

ANTLR 4 TL Grammar seems incorrect

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

Answers (1)

Bart Kiers
Bart Kiers

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.

EDIT

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

Related Questions