为什么将语法分析与执行分开?

时间:2012-02-06 05:01:56

标签: scheme sicp

在SICP第4章中,通过将语法分析与执行分开来修改元叶评估器,使eval过程看起来像:

(define (eval exp env)
    ((analyze exp) env))

并且书中说这将节省工作,因为analyze将在表达式上调用一次,而执行过程可能会多次调用。

我的问题是,这种优化如何运作?它适用于递归过程调用,但其他情况如何呢?评估者一个接一个地评估表达式,即使它们具有相同的形式,仍然会在每个表达式上调用eval

3 个答案:

答案 0 :(得分:4)

您需要看到以下几点:(a)analyze函数只遍历每个表达式一次,(b)没有analyze之外的代码扫描语法,(c) analyze返回的函数不会调用自身,因此运行该函数永远不会导致语法的任何进一步扫描。(d)这与通常的评估函数不同,其中调用函数两次意味着其语法被扫描两次。

BTW,analyze更好的名称是compile - 它确实将输入语言(sexprs)转换为目标语言(一个函数,在这里充当机器代码)。< / p>

答案 1 :(得分:1)

编译器和解释器之间的区别在于:

编译器只扫描一次源代码并将其更改为执行代码(可能是机器代码)。当您下次执行程序时,直接执行执行代码而不分析源代码,这是有效的。

然而,解释器会在每次执行程序时分析源代码。

此优化仅在您的程序执行多次的情况下才有意义。

正如@Eli Barzilay所说,“analyze更好的名称是compile”,您分析的函数就像执行代码一样。递归函数就像程序一样多次执行。

答案 2 :(得分:0)

analyze只进行一次语法分析,并将转换后的definition等存储在可以在执行相关过程时直接通过lookup-variable-value使用的环境中。

相比之下,原始的metacircular评估器扭曲了语法分析和执行,这使得每个执行也调用语法分析。

此链接可能有用: http://www.cs.brandeis.edu/~mairson/Courses/cs21b/Handouts/feeley-notes.pdf