Differences between revisions 1 and 41 (spanning 40 versions)
Revision 1 as of 2021-02-01 18:12:05
Size: 56
Editor: zbjxb
Comment:
Revision 41 as of 2021-02-15 18:04:04
Size: 2726
Editor: zbjxb
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
在这里详述 compiler/Let's build a compiler/ch2。 = Parse和Translate数学表达式 =
希望看到的产出:一系列执行期望动作的汇编语句

== 目标表达式 ==
{{{x = 2*y + 3/(4*z)}}}

=== single digits ===
将expression定义为single digit并输出解析它的汇编语句

||<#00FF00>输入单个数字测试程序通过||

=== binary expressions ===
将expression扩展为二元表达式并输出相应汇编语句.
{{{
                         1+2
     or 4-3
     or, in general, <term> +/- <term>
}}}
||<#00FF00>输入1+2 Pass||
||<#FF0000>输入单个数字 Failed||

=== general expressions ===
{{{
     <expression> ::= <term> [<addop> <term>]*
}}}

=== using the stack ===
{{{
    1+(2-(3+(4-5)))
}}}
由该表达式引出的问题。凡事有记录现场并转而干其他事情的情景,可能都需要Stack。

=== MULTIPLICATION AND DIVISION ===

关于优先级的问题,在这里的处理方式中根本就不存在:通过top-down分解、各个击破的方式,优先级问题被化解于无形。

这里只需要将term扩展一下即可:
{{{
    <term> ::= <factor> [ <mulop> <factor ]*
}}}
而这里的factor目前就是single digit。

=== PARENTHESES ===

表达式里的括号是个特别的东西。它可以重组优先级,更重要的是提供了一种机制:实现任意复杂的(四则运算)数学表达式。

要实现括号的处理,改动其实很小:将factor定义为expression如下:
{{{
    <factor> ::= (<expression>)
}}}
So easy!!!
注意expression用括号包围着。这里也是'''递归'''引入的地方,因expression定义链中的部分构成要素就是factor,而这里factor却又由expression定义。

=== UNARY MINUS ===

这里处理负号的策略是:在进行上面对expression的处理之前,先检测当前token是否为负号:若为是,则将该token当做负号特别处理;反之则进入已有的expression处理。


=== A WORD ABOUT OPTIMIZATION ===

优化就是提高生成的代码质量。有些优化只需要略施小计,在现有的parser中添加一点点代码即可达成。
两种策略:
 * Try to fix up the code after it's generated
  * 号称“peephole”的优化方法:发现可以优化掉的指令序列,用更优的指令序列代替。预置一些可以优化掉的指令序列套路,用“peephole”查看生成的代码,从中找出这些套路并执行替换。通常是编译器的第二遍,second pass。
 * Try to generate better code in the first place
  * 生成代码前进行更多的test,使得特殊情况特殊对待,对应生成更高效的代码。


----
<<FootNote(scheme/call-with-current-continuation)>>

Parse和Translate数学表达式

希望看到的产出:一系列执行期望动作的汇编语句

目标表达式

x = 2*y + 3/(4*z)

single digits

将expression定义为single digit并输出解析它的汇编语句

输入单个数字测试程序通过

binary expressions

将expression扩展为二元表达式并输出相应汇编语句.

                         1+2
     or                  4-3
     or, in general, <term> +/- <term>

输入1+2 Pass

输入单个数字 Failed

general expressions

     <expression> ::= <term> [<addop> <term>]*

using the stack

    1+(2-(3+(4-5)))

由该表达式引出的问题。凡事有记录现场并转而干其他事情的情景,可能都需要Stack。

MULTIPLICATION AND DIVISION

关于优先级的问题,在这里的处理方式中根本就不存在:通过top-down分解、各个击破的方式,优先级问题被化解于无形。

这里只需要将term扩展一下即可:

    <term> ::= <factor>  [ <mulop> <factor ]*

而这里的factor目前就是single digit。

PARENTHESES

表达式里的括号是个特别的东西。它可以重组优先级,更重要的是提供了一种机制:实现任意复杂的(四则运算)数学表达式。

要实现括号的处理,改动其实很小:将factor定义为expression如下:

    <factor> ::= (<expression>)

So easy!!! 注意expression用括号包围着。这里也是递归引入的地方,因expression定义链中的部分构成要素就是factor,而这里factor却又由expression定义。

UNARY MINUS

这里处理负号的策略是:在进行上面对expression的处理之前,先检测当前token是否为负号:若为是,则将该token当做负号特别处理;反之则进入已有的expression处理。

A WORD ABOUT OPTIMIZATION

优化就是提高生成的代码质量。有些优化只需要略施小计,在现有的parser中添加一点点代码即可达成。 两种策略:

  • Try to fix up the code after it's generated
    • 号称“peephole”的优化方法:发现可以优化掉的指令序列,用更优的指令序列代替。预置一些可以优化掉的指令序列套路,用“peephole”查看生成的代码,从中找出这些套路并执行替换。通常是编译器的第二遍,second pass。
  • Try to generate better code in the first place
    • 生成代码前进行更多的test,使得特殊情况特殊对待,对应生成更高效的代码。


1

  1. scheme/call-with-current-continuation (1)

compiler/Let's build a compiler/ch2 (last edited 2021-02-15 18:05:22 by zbjxb)