Parsing 实现无括号的方法调用

Parsing 实现无括号的方法调用,parsing,functional-programming,language-design,lexical-analysis,Parsing,Functional Programming,Language Design,Lexical Analysis,我目前的项目(实际上只是一种玩具语言)是一种功能性脚本语言。我希望允许方法调用,而不需要括号来进行分组 sum 1 2 3 这里有一个陷阱,老实说,我不确定这是否是一件普通的事情。但在我的语言中,一个方法可以定义执行标识符的参数 def (a) plus (b) a + b end 最终会是 1 plus 2 但是如果我对这些参数使用变量/函数呢? 例如,我如何知道“plus”是我正在调用的方法,而不是下面的“getnum” getnum plus 2 此外,我如何知道getnu

我目前的项目(实际上只是一种玩具语言)是一种功能性脚本语言。我希望允许方法调用,而不需要括号来进行分组

sum 1 2 3
这里有一个陷阱,老实说,我不确定这是否是一件普通的事情。但在我的语言中,一个方法可以定义执行标识符的参数

def (a) plus (b)
    a + b
end
最终会是

1 plus 2
但是如果我对这些参数使用变量/函数呢? 例如,我如何知道“plus”是我正在调用的方法,而不是下面的“getnum”

getnum plus 2
此外,我如何知道getnum是plus的一个参数,而不是相反?(只是通过检查参数签名吗?) 编辑:我只是重复了一遍。哎呀


最后,lexer应该为这种事情做些特别的事情吗?如果是这样的话,它怎么知道该将哪个称为“methodtoken”?或者lexer只是将“Identifiertoken”和“literaltoken”之类的东西抽出来,让运行时来判断这是一个方法调用吗?

您要寻找的是和。在括号少的方法调用的情况下,空白空间是函数应用运算符。

这有点复杂,但毕竟你只需要为你的语言制定一些规则,不允许一些模棱两可的表达。在您的示例中,您将
plus
声明为中缀运算符,并赋予所有中缀运算符比前缀运算符更高的优先级


这是解析器的工作,而不是标记器或词法分析器。

您要寻找的是和。在括号少的方法调用的情况下,空白空间是函数应用运算符。

这有点复杂,但毕竟你只需要为你的语言制定一些规则,不允许一些模棱两可的表达。在您的示例中,您将
plus
声明为中缀运算符,并赋予所有中缀运算符比前缀运算符更高的优先级


这是解析器的工作,而不是标记器或词法分析器。

您的问题是解析问题。然而,更大的问题是你的语言不是。这意味着您的语言的语法与其语义不匹配。例如,考虑以下语言中的程序:

fg
这可以通过两种方式之一进行分析,
f
应用于
g
g
应用于
f
。但是,该语言的语法并不能清楚地表明将生成两个解析树中的哪一个。正如正确提到的,“这不仅仅是一个解析问题,而是一个语义反馈问题”

那么,如何使语言语法有针对性呢?让我们从面向对象的语言中得到提示。例如:

1加2
在像JavaScript这样的面向对象语言中,这可以写成:

Number.prototype.plus=函数(n){
返回这个+n;
};
var总和=(1)加上(2);

警报(总和)您的问题是解析问题。然而,更大的问题是你的语言不是。这意味着您的语言的语法与其语义不匹配。例如,考虑以下语言中的程序:

fg
这可以通过两种方式之一进行分析,
f
应用于
g
g
应用于
f
。但是,该语言的语法并不能清楚地表明将生成两个解析树中的哪一个。正如正确提到的,“这不仅仅是一个解析问题,而是一个语义反馈问题”

那么,如何使语言语法有针对性呢?让我们从面向对象的语言中得到提示。例如:

1加2
在像JavaScript这样的面向对象语言中,这可以写成:

Number.prototype.plus=函数(n){
返回这个+n;
};
var总和=(1)加上(2);

警报(总和)
更糟糕的是,如果
getnum
plus
都是函数呢?一般来说,听起来你的语法很模糊。我的意思是,如果你有
def(x)
def(x)g
,那么
f g
应该解析成什么呢?我猜嵌套函数调用必须使用括号(或其他一些分组字符集)除非它可以基于getnum不带参数的事实来确定。我想你必须建立操作符优先级来定义哪个操作符先去。同样的,
1+2*3
在数学中没有论题,这不是一个词汇分析问题。这是一个解析问题。lexer不知道调用哪个标识符“methodtoken”。它只是输出“Identifiertoken”和“literaltoken”之类的东西。解析器必须弄清楚它是否是一个方法调用。更糟糕的是,如果
getnum
plus
都是函数呢?一般来说,听起来你的语法很模糊。我的意思是,如果你有
def(x)
def(x)g
,那么
f g
应该解析成什么呢?我猜嵌套函数调用必须使用括号(或其他一些分组字符集)除非它可以基于getnum不带参数的事实来确定。我想你必须建立操作符优先级来定义哪个操作符先去。同样的,
1+2*3
在数学中没有论题,这不是一个词汇分析问题。这是一个解析问题。lexer不知道调用哪个标识符“methodtoken”。它只是输出“Identifiertoken”和“literaltoken”之类的东西。解析器必须弄清楚它是否是一个方法调用,这样我的lexer就可以继续在这些地方解析标识符/文字标记了吗?到目前为止,这就是我当前实现的方式。但后来我停了下来,想知道我该如何解析一个方法调用(假设括号和逗号是空格),比如“method(method2(123),somevariable)”。我唯一的办法是合作