type
status
date
slug
summary
tags
category
icon
password
编译概论
一点点计算机小知识(编译器和解释器是同级的,都是用来将高级语言翻译成机器语言的)
编译器和解释器的区别:
- 编译器只是负责翻译程序,执行需要的数据是在之后提供的
- 解释器同时处理了源程序和程序需要的数据
常见的编译(解释语言),c语言也是编译的,但是java是有编译也有解释的
先通过javac将java程序编译为虚拟机能识别的程序,然后再通过虚拟机解释生成本地运行程序
编译器的全过程:
- 词法分析(识别tok单词,并且处理tok如何分类的问题关键字运算符等一字一码,此时tok的属性值就是当前符号或关键字或者直接没有属性值字段,其他的如变量整形数浮点数等一类一码,这个时候tok的属性值就是具体的数值,比如变量的tok的属性值就是变量名)
如这里面的while关键字tok还有变量y的tok
- 语法分析(生成语法树,此时会忽略一些无意义的符号,比如分号括号等)
- 语义分析(理解这段代码是在做什么,但是通常因为程序分析的时候是有歧义的,很难做到完全理解程序在做什么事,所以语义分析一般就是做类型检查)
- 中间代码生成(三地址代码等,是编译器前端的最后一个步骤,中间代码的生成代表前端的结束,前端的主要任务是分析程序,前面的步骤都是在分析源程序)
- 中间代码优化(循环优化等,代表后端开始,后端主要是负责优化程序并且合成最后的机器代码)
- 目标代码生成(机器代码)
- 目标代码优化
具体的编译器结构(注意符号表这个东西,符号表是用来存储已经收集到的信息的一种数据结构,存储信息包括但不限于词法分析生成的tok,程序中的数据类型等。从源程序的分析开始就需要同时构建符号表,后面的步骤也会需要符号表中的信息,甚至到最终的机器代码生成也需要符号表,比如长整型和整形的汇编指令是不一样的,所以符号表什么时候都需要,是贯穿编译全过程的)符号表就是用来存储编译过程中识别的信息以便后续调用的
这么看符号表很像是tok表,但是注意这两个表存储信息的含义不一样,下面举一个例子:
- 在tok表中变量的存储,key存储的是tok的类型,而属性信息存储的是变量名
- 在符号表中,key存储的是变量名,而属性信息存储的是变量在某个时间实际代表的值(或存储的值)
符号表名字的两种存储方式:
- 直接存储:相当于是在名字域上开了一个数组(所以是定长的,不好扩展)
- 间接表:相当于是在名字域上创建了一个链表(此时名字域上存储的是一个链表的头指针,也就是这里说的名字域存放指针),然后需要扩展名字域的时候就进行扩展
小知识:微软的名字域有最大限制2048,所以说此时在程序中变量的名字最大不能超过2048
符号表的属性域存储的内容包括但不限于记录名字(也就是名字域的内容)的存储分配,类型,作用域,参数数量和类型还有参数传递方法以及返回值类型等(对函数而言),详见下面的图片。
关于出错处理,出错处理主要报告错误的性质(是否严重,有多严重)还有位置(是在编译的哪个阶段中的哪些操作,要尽可能缩小范围,找出更多错误)
- 作者:Noah
- 链接:https://imnoah.top/article/Compiler/Chapter1
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。