A. 编译器做什么工作
1. 词法分析 词法分析器根据词法规则识别出源程序中的各个记号(token),每个记号代表一类单词(lexeme)。源程序中常见的记号可以归为几大类:关键字、标识符、字面量和特殊符号。词法分析器的输入是源程序,输出是识别的记号流。词法分析器的任务是把源文件的字符流转换成记号流。本质上它查看连续的字符然后把它们识别为“单词”。 2. 语法分析 语法分析器根据语法规则识别出记号流中的结构(短语、句子),并构造一棵能够正确反映该结构的语法树。 3. 语义分析 语义分析器根据语义规则对语法树中的语法单元进行静态语义检查,如果类型检查和转换等,其目的在于保证语法正确的结构在语义上也是合法的。 4. 中间代码生成 中间代码生成器根据语义分析器的输出生成中间代码。中间代码可以有若干种形式,它们的共同特征是与具体机器无关。最常用的一种中间代码是三地址码,它的一种实现方式是四元式。三地址码的优点是便于阅读、便于优化。 5. 中间代码优化 优化是编译器的一个重要组成部分,由于编译器将源程序翻译成中间代码的工作是机械的、按固定模式进行的,因此,生成的中间代码往往在时间和空间上有很大浪费。当需要生成高效目标代码时,就必须进行优化。 6. 目标代码生成 目标代码生成是编译器的最后一个阶段。在生成目标代码时要考虑以下几个问题:计算机的系统结构、指令系统、寄存器的分配以及内存的组织等。编译器生成的目标程序代码可以有多种形式:汇编语言、可重定位二进制代码、内存形式。 7 符号表管理 符号表的作用是记录源程序中符号的必要信息,并加以合理组织,从而在编译器的各个阶段能对它们进行快速、准确的查找和操作。符号表中的某些内容甚至要保留到程序的运行阶段。 8 出错处理用户编写的源程序中往往会有一些错误,可分为静态错误和动态错误两类。所谓动态错误,是指源程序中的逻辑错误,它们发生在程序运行的时候,也被称作动态语义错误,如变量取值为零时作为除数,数组元素引用时下标出界等。静态错误又可分为语法错误和静态语义错误。语法错误是指有关语言结构上的错误,如单词拼写错、表达式中缺少操作数、begin和end不匹配等。静态语义错误是指分析源程序时可以发现的语言意义上的错误,如加法的两个操作数中一个是整型变量名,而另一个是数组名等。
B. 编译器前端开发
编译器粗略分为词法分析,语法分析,类型检查,中间代码生成,代码优化,目标代码生成,目标代码优化。把中间代码生成及之前阶段划分问编译器的前端,那么后端与前端是独立的。后端只需要一种中间代码表示,可以是三地址代码或四元式等,而这些都与前端生成的方式无关。也就是不论你前端是用fortran还是c/c++,只要生成了中间代码表示就可以了,后端是不管你是用哪种语言生成的。
C. 三地址代码是一般形式为什么的指令序列
3个地址代码的指令就是三地址码。
指令是由操作码和地址码两部分组成,有些指令要有3个操作数,也就是3个地址代码。
代码(code)是程序员用开发工具所支持的语言写出来的源文件,是一组由字符、符号或信号码元以离散形式表示信息的明确的规则体系。
代码设计的原则包括唯一确定性、标准化和通用性、可扩充性与稳定性、便于识别与记忆、力求短小与格式统一以及容易修改等。
源代码是代码的分支,某种意义上来说,源代码相当于代码。现代程序语言中,源代码可以书籍或磁带形式出现,但最为常用格式是文本文件,这种典型格式的目的是为了编译出计算机程序。
计算机源代码最终目的是将人类可读文本翻译成为计算机可执行的二进制指令,这种过程叫编译,它由通过编译器完成。
源代码含义:
源代码(也称源程序),是指一系列人类可读的计算机语言指令。
源代码是相对目标代码和可执行代码而言的。 源代码就是用汇编语言和高级语言写出来的地代码。目标代码是指源代码经过编译程序产生的能被cpu直接识别二进制代码。可执行代码就是将目标代码连接后形成的可执行文件,当然也是二进制的。
D. vb怎么做个vb编译器
如果你要自己做程序编译的话很难,就算调用c2.exe和link.exe也没用,因为VB
在调用之前已经在临时目录下生成了一堆看不懂的东西。
但你可以调用VB主程序的命令行来生成程序,如你要生成的程序在D盘根目录,工程文件为
1.vbp那你可以在CMD里打VB6.exe /make D:\1.vbp
具体的可以参照VB6.exe /?
附:
VB的编译过程大致如下,当我们在编辑环境中编写完代码后,VB调用C2将所有的模块(包括CLASS)编译成OBJ文件(能够为机器语言识别的代码)。一下是C2的一些编译参数说明(E文):
- the the name of the prefixed one used for the names of the rowscontaining ' precompilato', one
risen of intermediate tails (from which name of the switch) temporary; these rows are 5 and finish withi suffissi GL, SY, FORMER, IN and DB; they contained are not documented
- f the name of the rows to compile
- W3 warning level 3, level of ' attenzione' dedicating to i warnings
- Gy it qualifies the connection to level of function (function-level linking)
- G5 optimization for the Pentium
- Gs4096 it allows not to insert the code for the control of stack (stack probe) if a function does not
use more than 4096 byte of stack
- dos not documented
- Z1 it removes the name of the bookcase of default from the rows.OBJ
- Fofileobj the name of rows OBJ to generate (rows output)
- Qifdiv it puts in action the corrections for the bug of the division of the Pentium (FDIV bug)
- MILILITER it creates rows eseguibile single-threaded
- basic it indicates the compiler C2 the fact that the compilation it happens for a plan basic
C2完成编译后,VB会调用LINK.EXE将所有的OBJ文件连接成EXE文件,完成编译过程。下面是一段命令行演示如何调用LINK.EXE:
LINK C:\Test\Form1.obj C:\Test\Molo1.obj C:\Test\Progetto1.obj C:\Programmi\Microsoft Visual Studio\VB98\VBAEXE6.lib /ENTRY:__ vbaS /OUT:C:\Test\Progetto1.exe /BASE:0x400000 /SUBSYSTEM:WINDOWS, 4.0 /VERSION:1.0 /DEBUG /DEBUGTYPE:CV /INCREMENTAL:NOT /OPT:REF/MERGE:.rdata =.text /IGNORE:4078
对于我们来说这些参数没有什么意义,用默认的就行了。这段命令行中并没有包括输出函数,如果我们希望输出函数,可以定义一个.def文件,按照格式加入要输出的函数列表,然后在命令行后面加上 “/DEF: 文件名”(当然也可以直接加/ EXPORTS参数),再调用命令行编译,用的denpendency工具查看你就会发现你要输出的函数了。
Def文件格式的定义:
LIBRARY 程序名称
DESCRIPTION "MyDLL - (C) Antonio Giuliana, 2004"
EXPORTS
函数名= ?函数名@函数所在模块名@@AAGXXZ
…
例:
LIBRARY MyDLL
DESCRIPTION "MyDLL - (C) Antonio Giuliana, 2004"
EXPORTS
DllRegisterServer= ?DllRegisterServer@SymExp@@AAGXXZ
DllUnregisterServer= ?DllUnregisterServer@SymExp@@AAGXXZ
注意:函数名和模块名是区分大小写的
我先用Vb编一个截取C2、LINK命令的程序:
C2:
Private Sub Form_Load()
f = UCase$(Left$(Command$, 256))
Open "E:\C2.txt" For Output As #1
Print #1, f
Close
End
End Sub
LINK:
Private Sub Form_Load()
f = UCase$(Left$(Command$, 256))
Open "E:\C2.txt" For Output As #1
Print #1, f
Close
End
End Sub
生成EXE后把VB98下的c2与LINK剪切到别处,在用这两个程序代替。运行VB6.exe,随意打开一个工程,点文件菜单,生成EXE。
不久我编的两个程序就送给我梦寐以求的文件:
E:\C2.txt
-IL "C:\DOCUME~1\ADMINI~1\LOCALS~1\TEMP\VB381884" -F "E:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VB98\新建文件夹 (2)\FORM1.FRM" -W 3 -GY -G5 -GS4096 -DOS -ZL -FO"E:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\FORM1.OBJ" -QIFDIV -ML -BASIC
E:\LINK.txt
"E:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\FORM1.OBJ" "E:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\LINK.OBJ" "E:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VB98\VBAEXE6.LIB" /ENTRY:__VBAS /OUT:"E:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\LINK.EXE" /BASE:0X400000 /SUBS
这两个TXT就是VB送给c2以及LINK的命令。
详细解读如下:
C2.txt
-IL "C:\DOCUME~1\ADMINI~1\LOCALS~1\TEMP\VB381884" -F "E:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VB98\新建文件夹 (2)\FORM1.FRM"是c2准备处理的两个文件。 -W 3 -GY -G5 -GS4096 -DOS -ZL是c2生成OBJ的格式,后边则是OBJ文件的地址。
LINK.txt
"E:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\FORM1.OBJ" "E:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\LINK.OBJ"是源文件。"E:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\VB98\VBAEXE6.LIB"是转换库。后面是EXE文件地址及格式