我正在为我正在从事的项目编写一种小型脚本语言。我为它编写了一个简单的递归下降解析器(类似于 Crafting Interpreters 中的解析器)。我想添加对 lambda(匿名函数)表达式的支持并为其提供以下语法:
let some_func = (param1, param2 = 1) {
return param1 + param2
}
如何区分 lambda 参数列表和分组(带括号)表达式,如下所示:
let some_expr = (var1 = 0) // Assignment is allowed as an expression.
let some_func = (param1, param2 = 0) {
return param1 + param2
}
像这样的 Lambda 语法(即直接以参数列表开头而不是表示 lambda 的某些关键字或符号开头的 lambda 语法)不是 LL(k),这意味着您无法使用有限数量的前瞻来解析它。
换句话说,您不能像 LL(1) 语法那样只打开当前标记,也不能像 LL(k) 语法那样使用
if
形式的 tokens.lookAhead(0).kind == X && tokens.lookAhead(1).kind == Y && ... && tokens.lookAhead(k).kind == Z
条件。
相反,您的选择是使用无限前瞻来查看
{
之后是否有 )
或使用回溯,即尝试解析 lambda,如果解析失败,则继续执行下一个优先级((
仍然是当前标记)。