用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(1)- 目标和前言
用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(1)- 目标和前言
用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(1)- 目标和前言 用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(2)- 简介和设计 用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(3)- 词法分析 用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(4)- 语法分析1:EBNF和递归下降文法 用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(5)- 语法分析2: tryC的语法分析实现 用c语言手搓一个600行的类c语言解释器: 给编程初学者的解释器教程(6)- 语义分析:符号表和变量、函数
项目github地址及源码: https://github.com/yunwei37/tryC
一个小目标
这一系列教程希望面向初学者,使用c语言手工实现一个简单的解释器来玩,不需要您掌握除了c语言以外的其他前置知识,也不需要您学习过编译原理的相关知识(当然如果能对简单的数据结构有所了解的话会更好,比如树、栈等)。
写一个能执行代码的解释器不仅是一件很有(zhuang)趣(bi)的事情,大概也可以作为刚学习完c语言的一个练手的小项目啦
不同于大部分常见的其他只支持四则运算的所谓”手工解释器“教程,我们希望在代码结构尽量清晰的600行代码中,手工(不借助lex/yacc等工具)完成一个脚本语言“try”,实现以下功能:
- 选择和循环的流程控制语句
- 支持的数据类型:双精度浮点数、字符型、字符串、浮点数数组
- 支持函数和变量的定义、函数的递归调用、嵌套作用域
(如果看不懂下面这段也没关系,可以略过啦)
这个小玩意采用递归下降法进行语法分析,同时不显式构建语法树,不生成中间代码或目标代码,在语法分析的同时进行解释执行;
解释器可运行的代码示例
递归计算文波那契数列 1 - 15,将结果存入数组中,并打印:
# Fibonacci sequence
func fun{
if(x <= 2){
return(1);
}
y = 0;
x = x - 1;
y = fun(x);
x = x - 1;
return(y + fun(x));
};
# save the Fibonacci sequence of 1 to 15 in an array
array arr(15);
x = 1;
while( x <= 15 ){
arr[x - 1] = fun(x);
x = x + 1;
}
puts("Fibonacci sequence:");
# print the Fibonacci sequence of 1 to 15
i = 0;
while(i < 15){
print(arr[i]);
i=i+1;
}
(起名困难x)这个小玩意我们就随便叫它tryC吧,当做是一个小的尝试。
本人水平有限,如有疏漏之处,还请多多指教。
部分语言规则:
注释在一行内,以‘#’开头;
语句以‘;’结尾
赋值语句类型:
x = 123.4;
x = 'c';
x = "hello world!";
循环语句:
while( bool ){
statements
}
选择语句:
if( bool ){
statements
}
if( bool ){
statements
}else{
statements
}
定义函数:函数参数在定义中不出现,在调用中获取;返回值为double
func function_name{
...
return(expression);
}
定义数组:
array array_name(array_length);
输入输出:
puts(string);
print(num);
read(num);
写在前面
关于写这玩意的缘由(写的很乱可以不看系列)
之前大一学c语言的时候,老师要求实现一个四则运算的计算器,于是我想…要是能给计算器加上函数和变量的定义就好啦…那大概能算一个简单的解释器?我应该怎样去实现它呢?就去查了不少资料七拼八凑加上自己脑补搓了一个出来…虽然能跑起来但是代码混乱不堪一塌糊涂,不过也挺好玩的。
这里的部分是过了一年之后大二学编译原理的时候,把当时的代码用相对比较规范完善的方式重写了一遍,也因此希望把它整理成一个简单的教程,让c语言的初学者也可以愉快地搓一个解释器玩;或者让学过编译原理的同学,能够把理论和实践联系起来,(不要像我一样被一大堆的理论迷惑住或吓跑),对于如何构造一个解释器有个直观感性的认识,并且发现它并不像想象的那么困难。
需要了解的前置知识
- c语言的指针、函数指针、结构体等
- 递归的思想
心理准备
- 写一个600行的解释器虽然不算什么大工程,但相关的原理还是稍微有些复杂的,可能需要多花一些时间理解程序的运行过程;
- 代码可能难以调试,尤其在没有生成中间代码的情况下;
参考资料
- 《编译原理及其实践》
- c4 用四个函数和很少的代码就完成了功能相当完善的 C 语言编译器, 并且能够自举;我自己写作的时候也借鉴了c4的许多实现思想;
- 手把手教你构建 C 语言编译器 对c4的一个重写版,附有详细的中文教程
- Let’s Build a Compiler, by Jack Crenshaw 一个英文的初学者教程,讲解如何实现一个编译器
相关文章
- Data Analytics Foundations数据分析基座总览
- java reflections_java 反射工具包reflections
- Capgemini 基于亚马逊云科技打造Trusted Vehicle 解决方案,加快颠覆性CASE汽车技术创新发展
- 方法中段java_Java基础-方法
- 在亚马逊云科技Guardduty上集成第三方威胁情报的两种方法
- python2.7安装MySQL-python
- java volatile_Java volatile原理总结
- 预告:Amazon S3 安全更改将于 2023 年 4 月发布
- 通过Lambda实现URL文件直接上传到S3
- 使用混合云HPC场景加快计算机辅助工程工作负载运行速度
- 亚马逊云科技和恩智浦半导体公司NXP 助力打造软件定义汽车
- 借助Serverless服务实现EMR Instance Fleets集群自定义弹性伸缩
- IAM 托管策略维护经验分享
- Python: python的简单表达式计算器
- Amazon SageMaker Endpoint for built-in TFS模型推理优化
- 使用 Amazon Selling Partner API Guard 来进行安全审计使你的 SP-API 应用更合规
- 宣布推出统一软件开发服务 Amazon CodeCatalyst(预览版)
- 新功能 — 使用 Amazon EventBridge Pipes 在事件产生器和事件使用器之间创建点对点集成
- 新功能 – 使用适用于 IDP 的 Amazon Comprehend 处理 PDF、Word 文档和图像
- 推出 Amazon GameLift Anywhere – 在您自己的基础设施上运行游戏服务器