我从https://raw.githubusercontent.com/bkiers/tiny-language-antlr4/master/src/main/antlr4/tl/antlr4/TL.g4
下载了TL语法在尝试尝试之后,我意识到语法无法在顶层处理用户定义的函数调用
例如,如果您的文件内容是:
def s(n)
return n+n;
end
s("5", "6");
你听一个FunctionCallExpression,你不会得到一个回调。但是,如果您的文件内容是:
def s(n)
return n+n;
end
s(s("5"))
你确实收到了回电。
答案 0 :(得分:1)
您的意见:
s("5", "6");
与语句匹配(不是表达式!):
functionCall
: Identifier '(' exprList? ')' #identifierFunctionCall
| ...
;
和"5", "6"
是由exprList
匹配的两个表达式。
输入s
中的第一个s(s("5"))
将再次与identifierFunctionCall
匹配,内部s
将与表达式匹配(functionCallExpression
为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>
1 + 2;
简而言之:语法按预期工作。
有效的TL脚本是一个代码块,每个代码块由语句组成。为了简化语法并消除一些模糊规则(旧的ANTLRv3需要这些规则),最简单的做法是不允许语句成为简单的表达式。例如,以下代码不是有效的TL脚本:
1 + 2
即。 foo(); // this is a statement
i = foo(); // now foo is an expression
不是陈述,而是表达。
然而,函数调用可能是一个语句,但是,当放在赋值语句的右侧时,它也可能是一个表达式:
s(...)
这就是为什么你观察到一个enter...()
触发某个{{1}}方法,而另一个没有。