<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path> </svg> <p></p>
讯享网
https://lotabout.me/2015/write-a-C-interpreter-1/
https://github.com/archeryue/cpc
https://www.bilibili.com/video/BV1Kf4y1V783/?vd_source=a1be939cc77b8a6a36c14a6e
工业级别编译器分前端和后端
前端(parser):源代码->中间代码(IR或者虚拟机指令)
- 词法分析(tokenize):告诉计算机每个词是啥意思,分出很多token词
- 语法分析:解析语句,然后生成中间代码或者抽象语法树
后端: 中间代码->目标代码
- optimizer(优化器 最难最核心) :中间代码->中间
- codegenerate:中间->最终目标代码(如果是物理架构 就会翻译为对应的X86架构等 虚拟机的话就会翻译为字节码 ) LLVM就是根据目标平台将IR字节码翻译到最终的目标代码
- 前后端合一,无中间优化,直接生成中间代码来通过解释器(自定义VM)执行
- 边词法分析边语法分析同时生成字节码 (变量声明必须在开头)
计算基于register和stack顶
- register:pc/sp/bp/ax
- memory: code/data(静态变量/字面量)/stack
- 指令集:save&load(mem<->register)/ 计算指令(算术 位 逻辑)/跳转(无条件 有条件 比较)/native call(IO: printf orw / 动态内存分配: malloc/free/memset )
PC 程序计数器,它存放的是一个内存地址,该地址中存放着 下一条 要执行的计算机指令。
SP 指针寄存器,永远指向当前的栈顶。注意的是由于栈是位于高地址并向低地址增长的,所以入栈时 SP 的值减小。
BP 基址指针。也是用于指向栈的某些位置,在调用函数时会使用到它。
AX 通用寄存器,我们的虚拟机中,它用于存放一条指令执行后的结果。
- save/load: imm / lea / lc / li /sc / si /push
- 运算:add /sub / mul /div /mod /or /xor /and / shc /shr
- 分支跳转: jmp/jz / jnz /call /nvar /darg / re
- native call: orw / close / printf / malloc /free / memset /exit /memcmp
讯享网
首先读文件到分配的空间里
然后分配代码段 数据段 栈段 符号表
词法分析函数就是根据扫描到的字符来确定类型
symbol_ptr是符号表指针
- 数字或者字符组成就会放到符号表里,这里会遍历符号表,查看是否有相同的符号,有就直接返回这个符号,没有就会导入,返回token是ID类型
讯享网
- 纯数字会根据进制解析,返回token是数字类型
- 字符和字符串, 这里char是当作num类型的,另外字符串中可能包含转义字符,这里也要处理
- 注释符和除法
讯享网
- 运算符号,除了部分符号是直接返回的,大部分符号都是需要返回对应的操作类型
讯享网
- 首先会讲一些关键字放进符号表里面,这些符号的Token会被设置为对应的关键字中枚举值对应的值,也就是哪个关键字类型
OPEN开始的关键字放入符号表后还会设置Class(类型)和type(返回值)和value(对应的关键字枚举值),这里的Token为ID类型枚举值
讯享网
语法:词->句子
语义:就是表达的意思
文法:语法的合集
通过递归下降的方法逐层分解,直到表达式,表达式通过优先级爬上
这里语法分析和词法分析其实是一起的,先词法分析,然后再语法分析
- 这里praser先分解析声明语句也就是这三种,通过先解析token来知道类型(Enum 还是Char 和Int)
- Enum是
讯享网
- INT /Char ID ;或者 INT /Char ID ( ) { }
- 解析函数体。先解析变量声明,然后有开辟栈帧的语句,然后解析语句,最后加个ret,然后将是loc的符号表恢复 (因为解析函数)
讯享网
- 解析语句,有if while return {} ;赋值表达式语句,然后转换为对应的字节码
- if 语句是()里面的条件表达式满足为0则跳转到else部分, 否则就执行为true的部分
手把手教你构建 C 语言编译器(4)- 递归下降

讯享网
上面是解析表达式的递归下降的方法
- statement : 做什么 if while return
- expression:求值 2+3 4*5
一元
讯享网
一元大于二元
二元
就是分别压操作数和符号,但出现比当前栈顶的符号的优先级低的时候,就运算此时栈顶的符号和对应的操作数
讯享网

此时压入符号栈的是-号,但优先级别小于*,所以此时会计算 34的结果再压入数据栈,然后再将-号压入符号栈
这里先解析++a然后解析++a,然后解析a++…………不具体演示了,按照对应的优先级来爬上就行
- 解析表达式,代表当前解析的最大优先级,按照优先级顺序来解析,一元还是正常解析(出来a++),但二元只会解析比当前precd大的(a++算到仅仅小于()的优先级别了)
讯享网

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/201679.html