首先,我正在用 Python 编写解释器,而不是编译为机器代码的实际编译器。我最近浏览了很多编译器构建指南,我了解为解析器生成标记和构建语法树来评估算术表达式的基础知识,但我不太了解如何解析其中包含函数调用的表达式,像
图。 (一)
1 + pow(1, 1)
或者当用户定义这样的函数时如何解析行
图。 (二)
function newFunction( someArgs ){
... some magic ...
}
在图 (a) 中,我应该如何标记这个表达式?在阅读了保留字“pow”之后,我是否应该捕获右括号之前的所有内容并将其传递给解析器?还是我应该将“pow”、“(”、“1”、“1”和“)”分别作为单独的标记添加到我的解析树中?
纤维。 (b) 在编译函数定义时,我什至不知道从哪里开始。任何能让我朝着正确方向前进的信息都将不胜感激。
编辑:我使用的是 Backus-Naur 形式语法:
S ::= expression
expression ::= term | term ([+-] term)+
term ::= factor | factor ([*/] factor)+
factor ::= number | ( expression )
number ::= [0-9]+
最佳答案
另一位发帖者建议将函数名称添加到语法中。
这适用于玩具语言,但不适用于可能有大量库和大量用户定义函数的实用语言。
您可以通过向 BNF 添加函数调用来处理后者, 以一种将函数名称排除在语法之外的方式:
S ::= expression
expression ::= term | term ([+-] term)+
term ::= factor | factor ([*/] factor)+
factor ::= number | ( expression ) | identifier | functioncall
functioncall ::= identifier [(] arguments [)]
arguments ::= empty | arguments
arguments ::= expression | arguments [,] expression
number ::= [0-9]+
identifier ::= [a-z]+
现在您的解析器可以接收函数调用了。 (语法中遗漏了一种定义函数的方法...但这只是我留给您添加的更多语法)。
这样做的代价是,在解析之后,某些东西已经决定了每个函数名,它准确地代表了代码的哪一部分。您将需要一个符号表来执行此操作。 那是另一个问题。
关于python - 编译器 : How to parse function calls and function definitions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18820624/