只需编程基础。
从零开始自制编程语言。
支持面向对象、异常处理等高级机制。
前桥和弥(Maebasi Kazuya),1969年出生,著有《征服C指针》、《彻底掌握C语言》、《Java之谜和陷阱》等。其一针见血的“毒舌”文风和对编程语言深刻的见地受到广大读者的欢迎。
刘卓,2004年开始从事对日软件开发工作,其间还从事技术及软件工程相关培训工作。自2011年开始从事电力行业产品研发。持续关注企业级应用架构和Web客户端技术。
徐谦,6年技术开发及项目经验,曾以技术工程师身份赴日本工作两年,后归国联合创办互联网公司,现居上海继续创业中。主要从事PHP方向的Web开发。热爱开源,曾向Zend Framework等知名PHP开源项目贡献代码,并于Github自主研发运维EvaThumber等开源项目获得国内社区认可。乐于分享技术心得,个人技术博客avnpc.com在国内PHP圈小有影响。
吴雅明,13年编程经验。其中7年专注于研发基于Java EE和.NET的开发框架以及基于UML 2.0模型的代码生成工具。目前正带领团队开发云计算PaaS平台及云计算自动化配置部署的系统。译著有《征服C指针》等。
第1章 引子
1.1 为什么要制作编程语言
1.2 自制编程语言并不是很难
1.3 本书的构成与面向读者
1.4 用什么语言来制作
1.5 要制作怎样的语言
1.5.1 要设计怎样的语法
1.5.2 要设计怎样的运行方式
补充知识 “用户”指的是谁?
补充知识 解释器并不会进行翻译
1.6 环境搭建
1.6.1 搭建开发环境
补充知识 关于bison与flex的安装
1.6.2 本书涉及的源代码以及编译器
第2章 试做一个计算器
2.1 yacc/lex是什么
补充知识 词法分析器与解析器是各自独立的
2.2 试做一个计算器
2.2.1 lex
2.2.2 简单正则表达式讲座
2.2.3 yacc
2.2.4 生成执行文件
2.2.5 理解冲突所代表的含义
2.2.6 错误处理
2.3 不借助工具编写计算器
2.3.1 自制词法分析器
补充知识 保留字(关键字)
补充知识 避免重复包含
2.3.2 自制语法分析器
补充知识 预读记号的处理
2.4 少许理论知识--LL(1)与LALR(1)
补充知识 Pascal/C 中的语法处理诀窍
2.5 习题:扩展计算器
2.5.1 让计算器支持括号
2.5.2 让计算器支持负数
第3章 制作无类型语言crowbar
3.1 制作crowbar ver.0.1语言的基础部分
3.1.1 crowbar是什么
3.1.2 程序的结构
3.1.3 数据类型
3.1.4 变量
补充知识 初次赋值兼做变量声明的理由
补充说明 各种语言的全局变量处理
3.1.5 语句与结构控制
补充知识 elif、elsif、elseif的选择
3.1.6 语句与运算符
3.1.7 内置函数
3.1.8 让crowbar支持C 语言调用
3.1.9 从crowbar中调用C 语言(内置函数的编写)
3.2 预先准备
3.2.1 模块与命名规则
3.2.2 内存管理模块MEM
补充知识 valgrind
补充知识 富翁式编程
补充知识 符号表与扣留操作
3.2.3 调试模块DBG
3.3 crowbar ver.0.1的实现
3.3.1 crowbar的解释器--CRB_Interpreter
补充知识 不完全类型
3.3.2 词法分析--crowbar.l
补充知识 静态变量的许可范围
3.3.3 分析树的构建--crowbar.y 与create.c
3.3.4 常量折叠
3.3.5 错误信息
补充知识 关于crowbar中使用的枚举型定义
3.3.6 运行--execute.c
3.3.7 表达式评估--eval.c
3.3.8 值--CRB_Value
3.3.9 原生指针型
3.3.10 变量
3.3.11 字符串与垃圾回收机制--string_pool.c
3.3.12 编译与运行
第4章 数组和mark-sweep垃圾回收器
4.1 crowbar ver.0.2
4.1.1 crowbar的数组
4.1.2 访问数组元素
4.1.3 数组是一种引用类型
补充知识 “数组的数组”和多维数组
4.1.4 为数组添加元素
4.1.5 增加( 模拟) 函数调用功能
4.1.6 其他细节
4.2 制作mark-sweep GC
4.2.1 引用数据类型的结构
4.2.2 mark-sweep GC
补充知识 引用和immutable
4.2.3 crowbar栈
4.2.4 其他根
4.2.5 原生函数的形式参数
4.3 实现GC 本身
4.3.1 对象的管理方法
4.3.2 GC 何时启动
4.3.3 sweep阶段
补充知识 GC 现存的问题
补充知识 Coping GC
4.4 其他修改
4.4.1 修改语法
4.4.2 函数的模拟
4.4.3 左值的处理
4.4.4 创建数组和原生函数的书写方法
4.4.5 原生指针类型的修改
第5章 中文支持和Unicode
5.1 中文支持策略和基础知识
5.1.1 现存问题
5.1.2 宽字符(双字节)串和多字节字符串
补充知识 wchar_t 肯定能表示1 个字符吗?
5.1.3 多字节字符/ 宽字符之间的转换函数群
5.2 Unicode
5.2.1 Unicode的历史
5.2.2 Unicode的编码方式
补充知识 Unicode可以固定(字节)长度吗?
5.3 crowbar book_ver.0.3的实现
5.3.1 要实现到什么程度?
5.3.2 发起转换的时机
5.3.3 关于区域设置
5.3.4 解决0x5C问题
补充知识 失败的 #ifdef
5.3.5 应该是什么样子
补充知识 还可以是别的样子--Code Set Independent
第6章 制作静态类型的语言Diksam
6.1 制作Diksam Ver 0.1语言的基本部分
6.1.1 Diksam的运行状态
6.1.2 什么是Diksam
6.1.3 程序结构
6.1.4 数据类型
6.1.5 变量
6.1.6 语句和流程控制
6.1.7 表达式
6.1.8 内建函数
6.1.9 其他
6.2 什么是静态的/ 执行字节码的语言
6.2.1 静态类型的语言
6.2.2 什么是字节码
6.2.3 将表达式转换为字节码
6.2.4 将控制结构转换为字节码
6.2.5 函数的实现
6.3 Diksam ver.0.1的实现--编译篇
6.3.1 目录结构
6.3.2 编译的概要
6.3.3 构建分析树(create.c)
6.3.4 修正分析树(fix_tree.c)
6.3.5 Diksam的运行形式--DVM_Executable
6.3.6 常量池
补充知识 YARV 的情况
6.3.7 全局变量
6.3.8 函数
6.3.9 顶层结构的字节码
6.3.10 行号对应表
6.3.11 栈的需要量
6.3.12 生成字节码(generate.c)
6.3.13 生成实际的编码
6.4 Diksam虚拟机
6.4.1 加载/ 链接DVM_Executable到DVM
6.4.2 执行--巨大的switch case
6.4.3 函数调用
第7章 为Diksam引入数组
7.1 Diksam中数组的设计
7.1.1 声明数组类型的变量
7.1.2 数组常量
补充知识 D 语言的数组
7.2 修改编译器
7.2.1 数组的语法规则
7.2.2 TypeSpecifier结构体
7.3 修改DVM
7.3.1 增加指令
补充知识 创建Java 的数组常量
补充知识 C 语言中数组的初始化
7.3.2 对象
补充知识 ArrayStoreException
7.3.3 增加null
7.3.4 哎!还缺点什么吧?
第8章 将类引入Diksam
8.1 分割源文件
8.1.1 包和分割源代码
补充知识 #include、文件名、行号
8.1.2 DVM_ExecutableList
8.1.3 ExecutableEntry
8.1.4 分开编译源代码
8.1.5 加载和再链接
补充知识 动态加载时的编译器
8.2 设计Diksam中的类
8.2.1 超简单的面向对象入门
8.2.2 类的定义和实例创建
8.2.3 继承
8.2.4 关于接口
8.2.5 编译与接口
8.2.6 Diksam怎么会设计成这样?
8.2.7 数组和字符串的方法
8.2.8 检查类的类型
8.2.9 向下转型
8.3 关于类的实现--继承和多态
8.3.1 字段的内存布局
8.3.2 多态--以单继承为前提
8.3.3 多继承--C++
8.3.4 Diksam的多继承
补充知识 无类型语言中的继承
8.3.5 重写的条件
8.4 关于类的实现
8.4.1 语法规则
8.4.2 编译时的数据结构
8.4.3 DVM_Executable中的数据结构
8.4.4 与类有关的指令
补充知识 方法调用、括号和方法指针
8.4.5 方法调用
8.4.6 super
8.4.7 类的链接
8.4.8 实现数组和字符串的方法
8.4.9 类型检查和向下转型
补充知识 对象终结器(finalizer)和析构函数(destructor)
第9章 应用篇
9.1 为crowbar引入对象和闭包
9.1.1 crowbar的对象
9.1.2 对象实现
9.1.3 闭包
9.1.4 方法
9.1.5 闭包的实现
9.1.6 试着跟踪程序实际执行时的轨迹
9.1.7 闭包的语法规则
9.1.8 普通函数
9.1.9 模拟方法(修改版)
9.1.10 基于原型的面向对象
9.2 异常处理机制
9.2.1 为crowbar引入异常
9.2.2 setjmp()/longjmp()
补充知识 Java 和C# 异常处理的不同
9.2.3 为Diksam引入异常
补充知识 catch 的编写方法
9.2.4 异常的数据结构
9.2.5 异常处理时生成的字节码
9.2.6 受查异常
补充知识 受查异常的是与非
补充知识 异常处理本身的是与非
9.3 构建脚本
9.3.1 基本思路
9.3.2 YY_INPUT
9.3.3 Diksam的构建脚本
9.3.4 三次加载/ 链接
9.4 为crowbar引入鬼车
9.4.1 关于“鬼车”
9.4.2 正则表达式常量
9.4.3 正则表达式的相关函数
9.5 其他
9.5.1 foreach 和迭代器(crowbar)
9.5.2 switch case(Diksam)
9.5.3 enum(Diksam)
9.5.4 delegate(Diksam)
9.5.5 final、const(Diksam)
附录A crowbar语言的设计
附录B Diksam语言的设计
附录C Diksam Virtual Machine 指令集
编程语言实用化指南--写在最后
参考文献
在一些C的入门书中都有这样一句话:为了提高移植性而适当地使用#ifdef。以我的理解,“适当地使用”其实就是“尽量别用”的意思。因此,这次我(在处理器切换时)使用了#ifdef,这对我来说也是一次失败。
根据处理器不同而使用#ifdef选择不同代码片段的话,会使代码变得很难理解。另外,像这样分散的代码通常很难进行充分的测试。在理想状态下,所有#ifdef的组合可以伴随着每日构建进行自动化测试,这感觉还不错,但是我认为这在实际中很难实现。
如果是为了提高移植性,那么也可以不使用#ifdef来处理各种分支,只要写一个尽可能适应各种处理器的代码不是就行了吗?
编程方面的著作《程序设计实践》中有以下记载。
如果我们对于条件编译持否定态度,那么就会由此发生一些问题。先不说最麻烦的。条件编译基本上都不可能进行测试。(中间省略)在对其中一个#ifdef代码块进行测试的同时,如果想测试另外的#ifdef代码块,除非改变环境使另一个#ifdef代码块生效,否则无法进行验证。
(中间省略)
由此我们得知。让我们感兴趣的是。在所有目标环境中都可以运行的共通性功能。
5.3.1节决定了crowbar不处理合成字符和UCS2范围以外的字符。
如果只是为了对应中文的话,这样的设计(指5.3.1节中提到的设计方式)就没问题了。但如果想要完美地实现,恐怕就需要考虑以下几点(以Unicode为前提)。
1.内部表现也要使用UTF.8
如果考虑合成字符的话,就不可能让字符有固定长度。如果想要取得字符串的第n个字符,每次都必须从字符串的开头扫描,所以还是算了吧。
2.不使用mbtowc()系列函数,自己实现全部的转换
如果自己保存转码表,就要根据不同的情况使用不同的转码表。比如,在需要和Java兼容的时候要使用Java的转码表,如果要在Windows对话框中显示一个字符串的时候又要使用Windows的转码表等。
mbtowc()系列函数不仅意味着“在所有的处理器中,总是可以返回所期望结果”,还表示“如果自己保存转码表的话,所有转换都要自己进行”。
作为一个还算现实的做法(只要能处理好中文就可以了),我制作的这个语法处理器,正好解决了所有的问题。如果一味追求结果而不能实现也是没有意义的。
……
这本书是为那些想独立制作一门编程语言的人而写的。
一听到这个话题,有的人会想:太疯狂了,制作编程语言肯定很有难度吧?有人会怀疑:制作编程语言能有什么用呢?其实这些都是误解。
制作编程语言在技术层面上其实并不难,只要掌握一些基础知识即可。而且,制作编程语言对于我们深入理解日常使用的C、Java、JavaScript 等语言都有帮助。在一些应用程序的内置脚本语言中,我们也经常会因为种种限制从而萌生制作替代语言的想法。因此,自制编程语言并不是少数极客的个人癖好,它对大多数程序员都颇具实用价值。
日本关于制作编程语言的书已经很多了,其中一些还被选定为大学教科书。这些书中常出现有限状态机、NFA、LL(1)、LR(1)、SLA 等专业词汇,同时还大量使用∩、∈等数学符号,对于不熟悉这部分理论知识的人(包括我自己在内)来说非常难以读懂。针对这种现状,本书会偏重实践,避免枯燥的理论。
本书将分别制作两种编程语言:crowbar 与Diksam。crowbar 是运行分析树的无类型语言,Diksam 是运行字节码的静态类型语言。无论哪种语言,都具备四则运算、变量、条件分支、循环、函数定义、垃圾回收等功能,最终版则可以支持面向对象、异常处理等高级机制。总之,作为现代编程语言所必须具备的功能都基本覆盖了(唯一可能没实现的就是多线程了吧)。所有源代码都提供下载,读者可以一边对照书中的说明一边调试源代码,这样应该不难理解整个程序的运行机制。
当然,要一次实现如此多功能的编程语言,对于初学者而言可能有点吃力,因此本书会详细介绍crowbar、Diksam 的制作步骤,请放心。
在制作编程语言的过程中,我体会到了一种无法用语言形容的快乐。其实无论在日本或其他地区,世界上还有很多人都在尝试自制编程语言,这正是编程语言不断增加的原因。如果以本书为契机,有朝一日你也向本已混乱的巴比伦之塔再添一门新语言的话,作为本书作者,这将是无上的光荣。
我得说,《图灵程序设计丛书:自制编程语言》这本书带给我的惊喜远超我的预期。它不是那种让你看完之后就能立刻写出“下一个XX语言”的速成手册,而是为你打开了一扇通往“语言设计哲学”的窗户。书中对于各种抽象概念的阐释,比如类型系统、控制流、函数抽象,都显得格外透彻。我之前一直对某些语言特性的设计感到困惑,比如为什么会有某种特定的语法结构,或者为什么会引入某种复杂的类型规则。读了这本书之后,我才恍然大悟,原来这些设计背后都有着深远的考量,都是为了在某些方面实现特定的目标,比如提高表达效率、增强代码安全性,或者简化编译器的实现。书中关于“元编程”和“语言扩展”的探讨,更是让我看到了语言生命力的无限可能,也让我开始思考,未来的编程语言可能会发展成什么样子。这本书让我意识到,编程语言的设计不仅仅是技术活,更是一种艺术,一种在逻辑与表达之间寻求完美平衡的艺术。
评分不得不说,《图灵程序设计丛书:自制编程语言》这本书给我的震撼是巨大的,它彻底颠覆了我过去对编程语言的理解模式。我一直以为编程语言的出现是必然的、是自然而然的,就像进化一样,最终会形成我们现在看到的那些成熟且强大的语言。然而,这本书却让我看到了另一种可能:语言是可以被“设计”出来的,而且其设计过程充满了趣味和挑战。作者并没有直接抛出复杂的理论,而是从最根本的“如何表达”开始,一步步引导读者去思考,去实践。我印象最深刻的是关于语法设计的章节,那些看似简洁的规则背后,隐藏着对人类思维习惯、逻辑表达的深刻洞察。书中所介绍的各种解析技术,比如递归下降和LL(1)解析器,也不是为了炫技,而是为了更有效地将我们脑海中的想法转化为计算机能够理解的指令。读这本书的时候,我常常会停下来,想象如果我来设计一门语言,我会如何处理某些特性,如何平衡表达能力和实现难度。这种思考过程本身就是一种极大的乐趣,让我感觉自己不再是被动接受知识,而是主动参与到语言的创造过程中。
评分《图灵程序设计丛书:自制编程语言》这本书,在我看来,更像是一本关于“思维构建”的指南,而编程语言只是其载体。作者以一种非常哲学的高度,引导我们去审视“沟通”的本质,以及如何将抽象的思维转化为精确的符号系统。我特别欣赏书中对于“上下文”和“作用域”的讲解,这不仅仅是编程语言中的概念,更是我们在现实世界中理解信息、进行交流的关键。通过构建自己的编程语言,我开始更加清晰地认识到,语言的规则是如何影响我们的思考方式,以及如何影响我们解决问题的能力。书中的例子虽然是关于编程语言的,但其背后所蕴含的设计哲学,却可以迁移到任何需要构建系统、规范表达的领域。例如,在团队协作中,清晰的沟通规范和信息传递机制,就如同为团队设计一门“内部语言”,其重要性不言而喻。这本书的价值,已经超越了单纯的技术范畴,它是一种思维的启迪,一种创造力的激发。
评分这本书绝对是为那些真正对编程语言“底层”原理感到好奇的读者量身打造的。它没有回避那些看似晦涩的技术名词,比如抽象语法树、语义分析、代码生成等,但它处理的方式却非常得体。不是直接堆砌概念,而是通过一系列精心设计的例子,将这些概念融入到实际的构建过程中。我个人最喜欢的部分是关于编译器架构的部分,它就像一幅宏伟的蓝图,将整个语言实现的过程清晰地勾勒出来。从前端的解析到后端的代码生成,每一个环节都像齿轮一样紧密协作,最终将人类可读的代码转化为机器可执行的指令。这本书的价值在于,它不仅仅教你“如何做”,更重要的是教你“为什么这样做”,以及“这样做的好处和潜在的坏处”。这种深度和广度的结合,让我在阅读过程中受益匪浅,也让我对那些我日常使用的编程语言有了更深的敬意。它让我明白,每一门语言的背后,都凝结了无数智慧和心血。
评分这本《图灵程序设计丛书:自制编程语言》简直是打开了我对编程世界新认知的一扇大门。在阅读之前,我总觉得编程语言是那些高高在上的、由天才们创造出来的神秘事物,自己顶多只能算是语言的使用者,而绝非创造者。然而,这本书却用一种极其平易近人的方式,将“创造语言”这个曾经遥不可及的概念,一点点地展现在我面前。它不是那种枯燥的技术手册,而是充满了启发性的引导,让我看到了语言设计背后的思考过程、权衡取舍,以及那些精巧的巧思。我尤其喜欢书中通过实例循序渐进的讲解方式,从最基础的词法分析,到语法解析,再到语义分析,每一步都经过细致的拆解,让我能够理解“为什么”要这样做,而不是简单地记忆“怎么”做。书中的一些比喻和类比也十分生动,能够将抽象的概念形象化,这对于我这样的初学者来说,简直是福音。每次读完一章,我都会有一种豁然开朗的感觉,仿佛自己也能像那些语言设计者一样,开始构思自己的小小语言世界。这本书让我对编程语言的理解不再停留在“使用”层面,而是上升到了“创造”和“理解”的层面,这是一种前所未有的体验。
评分买来准备自学的,希望能坚持下去。
评分同事说很好的一本书,所以让我帮他买。说是作者很严谨,写的书很好,值得一读,还推荐我们都要读一下,这样在底层可以提升自己的能力,对于做项目等大型工程是有很大的帮助的,所以等他读完,可以接过来读一下的。这样就可以提高了
评分内容不错,对于理解编译器比较有帮助,感觉这本书和自制编程语言结合起来一起看更好。
评分很好的书,看完后可以弄明白编译原理
评分慕名而来,看了几天,先给5分,不过里面少于内容老了些,如果作者能再出一个更新版,那样会很合适的~~~
评分此用户未填写评价内容
评分很久之前在学校时的老师推荐的这本书。当时下了这本书的电子版,苦于当时不懂汇编所以看了开头几章就看不下去了。现在汇编已经不是问题了,所以又买来这本书准备完整读一遍。
评分以实战为目的的书,理论讲得不算透彻需要自己细细琢磨。
评分代码与内容结合,用的ide可能不太熟练,确实是本入门好书,对整体有个大概了解,慢慢在看吧
本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度,google,bing,sogou 等
© 2025 book.idnshop.cc All Rights Reserved. 静思书屋 版权所有