1. 编译器本身是如何进行测试的
编译器最重要的性质就是保证语义的正确。比如,从高级语言翻译到机器指令之后,指令必须正确的表达原来程序的意思。所以一般编译器测试都包含一些源程序,用来覆盖可能出现的各种情况。基本的原则是:原来程序的结果 = 编译后机器指令运行的结果。机器指令运行的结果很容易知道,运行一下就知道了。可是原来程序的结果你怎么知道呢?
为了解决这个“原来程序语义”的问题,最好是写一个解释器,准确无误的表达原来的代码的语义。所以我们的要求就是:
高级语言解释器(源程序) = 机器执行(机器代码)
由于处理器其实就是一个用来执行机器代码的解释器,这里有一个很美好的对称关系:
interp1(L1) = interp2(L2)
另外还有一个问题,就是编译器一般需要经过多个转化步骤(叫做 pass)才能最后编译为机器指令。比如,
L2 = pass1(source)
L3 = pass2(L2)
L4 = pass3(L3)
Ln = passN(Ln-1)
machine_code = codegen(Ln)
由于源程序经过了很多步骤猜得到最后的机器指令,如果你使用上面的公式,就会出现以下一些情况:
1. 知道结果错了,但是却不知道到底是哪一个 pass 错了。
2. 结果没有错,但是中间却有 pass 实际上是错的。但是由于之前的 pass 把输入程序的一些结构给“优化”掉了,所以错的那个 pass 其实没能得到触发错误的那个数据结构。所以测试没能发现错误。如果以后前面的那个 pass 被修改,错误就会暴露出来。这是非常难以发现的潜伏的危险。
为了防止这些情况出现,一些编译器(比如 Chez Scheme 和 Kent Dybvig 的课程编译器)使用了对每一个 pass 进行测试的做法。具体的方法就是为每一个中间语言都写一个解释器,把这语言的语义完全的表示出来。这样我们就需要检查一组等式:
L2 = pass1(source)
高级语言编译器(源程序) = interp2(L2) // 测试 pass1 的正确性
L3 = pass2(L2)
interp2(L2) = interp3(L3) // 测试 pass2 的正确性
这样一来我们就能独立的判断每一个 pass 的正确性了。
这些是基本的语义测试原理。另外除了语义,可能还有一些“表面”一些的测试,它们看代码本身,而不只看它的语义。比如尾递归优化的测试应该确保输出程序的尾递归得到正确的处理,等等。这些是语义测试检查不到的,因为尾递归没有正确处理的程序大部分也能输出正确的结果。
普通的单元测试方法也可以用来测试一些编译器里的辅助函数,但那些不是编译器特有的,所以就不讲了。
另外,就像所有测试的局限性一样,你没法枚举所有可能出现的输入,所以以上的测试方法其实也不能保证编译器的完全正确。
2. c语言改错 怎么通过编译程序检查出语法错误
编译器编译时对你的代码错误自动显示出来,
告诉你错在哪里
你鼠标双击他的错误提示
就可以跳转到代码有错误的那一行了
编译器VC
Build里点击ReBuildAll
就保证可以编译了
3. 8086汇编程序的编译和调试方法
下载个MASM5,建个。ASM文件,在里面写好程序后,在命令行下,进入MASM的目录,比如你放在C盘
就
c:\masm5>
然后编译程序
c:\masm5>masm XX.asm
其中会出现两个文件问你是否要建,可以不用管直接回车两次,生成目标文件,
最后
c:\masm5>link XX
也是可以直接回车两次生成EXE。
然后命令行下
c:\masm5>debug xx.exe
进入调试你的程序。
4. 什么是编译程序
编译程序指将某一种程序设计语言写的程序翻译成等价的另一种语言的程序的程序, 称之为编译程序
编译程序也称为编译器,是指把用高级程序设计语言书写的源程序,翻译成等价的机器语言格式目标程序的翻译程序。编译程序属于采用生成性实现途径实现的翻译程序。
它以高级程序设计语言书写的源程序作为输入,而以汇编语言或机器语言表示的目标程序作为输出。编译出的目标程序通常还要经历运行阶段,以便在运行程序的支持下运行,加工初始数据,算出所需的计算结果。
编译程序的实现算法较为复杂,这是因为它所翻译的语句与目标语言的指令不是一一对应关系,而是一多对应关系,同时也因为它要处理递归调用、动态存储分配、多种数据类型,以及语句间的紧密依赖关系。
由于高级程序设计语言书写的程序具有易读、易移植和表达能力强等特点,编译程序广泛地用于翻译规模较大、复杂性较高、且需要高效运行的高级语言书写的源程序。
(4)程序编译检测方法扩展阅读:
编译流程分为了四个步骤:
1.预处理,生成预编译文件(.文件)
2.编译,生成汇编代码(.s文件)
3.汇编,生成目标文件(.o文件)
4.链接,生成可执行文件
5. 编译的时候能发现哪些错误
词法分析阶段能够检测出输入中不能形成源语言任何记号的错误字符串。语法分析阶段可以确定记号流中违反源语言结构(语法)规则的错误。语义分析阶段试图检测出具有正确语法结构但对操作无意义的部分。例如,我们试图将两个标识符相加,其中一个标识符是数组名,而另一个标识符却是过程名。(编译原理-龙书原话)。其他错误例如算法错误编译程序检测不出。