自制编程语言 基于C语言

自制编程语言 基于C语言 pdf epub mobi txt 电子书 下载 2026

☆☆☆☆☆
出版者:人民邮电出版社
作者:郑钢
出品人:异步图书
页数:438
译者:
出版时间:2018-9-1
价格:CNY 89.00
装帧:平装
isbn号码:9787115487377
丛书系列:
图书标签:
  • 编译原理
  • 编程语言
  • 编程
  • 计算机
  • 自制系列
  • 编译
  • 计算机科学
  • c
  • 编程
  • 语言
  • 自制
  • C语言
  • 基础
  • 学习
  • 开发
  • 教程
  • 实践
  • 代码
想要找书就要到 小哈图书下载中心
立刻按 ctrl+D收藏本页
你会得到大惊喜!!

具体描述

本书是一本专门介绍自制编程语言的图书,书中深入浅出地讲述了如何开发一门编程语言,以及运行这门编程语言的虚拟机。本书主要内容包括:脚本语言的功能、词法分析器、类、对象、原生方法、自上而下算符优先、语法分析、语义分析、虚拟机、内建类、垃圾回收、命令行及调试等技术。

本书适合程序员阅读,也适合对编程语言原理感兴趣的计算机从业人员学习。

《自制编程语言:基于C语言的深度探索》 这是一本怎样的书? 《自制编程语言:基于C语言的深度探索》并非一本泛泛而谈的编程语言入门指南,而是一次脚踏实地的编程语言构建之旅。如果你对计算机底层运作原理充满好奇,渴望亲手打造属于自己的“语言”,并希望深入理解现代编程语言是如何被设计、实现和优化的,那么这本书将为你提供一份详尽的路线图。 本书将带领你做什么? 本书的核心在于从零开始,利用C语言强大的底层控制能力,一步步构建一个功能完整的、具有一定表达能力的编程语言。 这不是关于学习一门新的现有语言,而是关于理解语言的本质,以及如何将其转化为计算机能够执行的指令。 我们将从最基础的概念入手,循序渐进地展开: 第一部分:语言设计哲学与架构基础 编程语言的本质: 我们将探讨为什么需要编程语言,它们是如何抽象化复杂计算任务的,以及不同类型语言(解释型、编译型、脚本型等)的设计考量。 词法分析(Lexical Analysis): 如何将人类可读的源代码分解成计算机能够理解的、有意义的“标记”(tokens)。我们会学习正则表达式、有限自动机等核心概念,并亲手实现一个简单的词法分析器。 语法分析(Syntax Analysis): 如何根据语言的语法规则,将标记序列组织成结构化的语法树。我们将深入学习上下文无关文法(Context-Free Grammars, CFGs)、BNF(巴科斯范式)等,并实现不同的解析技术,如递归下降解析(Recursive Descent Parsing)和LL(k)解析。 抽象语法树(Abstract Syntax Tree, AST): AST是连接词法分析和后续代码生成的关键桥梁。我们将学习如何构建和遍历AST,理解其在代码表示中的重要性。 语义分析(Semantic Analysis): 在语法正确之后,我们还需要检查代码的含义是否合理,例如类型检查、变量作用域检查等。本书将讲解如何实现这些重要的语义规则。 第二部分:代码生成与执行机制 中间表示(Intermediate Representation, IR): 在生成最终机器码之前,通常会生成一种中间代码,这有助于简化优化过程。我们将探索常见的IR形式,例如三地址码。 代码生成(Code Generation): 如何将AST或IR转化为目标平台的机器码或字节码。我们将重点关注如何生成x86或ARM架构的汇编代码,理解寄存器分配、指令选择等核心问题。 虚拟机(Virtual Machine, VM)与字节码: 对于解释型语言或跨平台需求,虚拟机是关键。本书将指导你构建一个简单的虚拟机,并实现基于字节码的执行模型。 内存管理: 编程语言如何管理内存?我们将探讨栈(Stack)、堆(Heap)、垃圾回收(Garbage Collection)等概念,并尝试在我们的语言中实现基本的内存分配和释放机制。 运行时环境(Runtime Environment): 语言运行时需要提供哪些支持?包括函数调用机制、异常处理、标准库等。我们将讨论如何构建一个基础的运行时系统。 第三部分:语言特性的实践与扩展 变量与作用域: 如何设计和实现变量的声明、赋值以及不同作用域下的访问规则。 控制流语句: 实现条件语句(if-else)、循环语句(while, for)等,是语言表达能力的关键。 函数与过程: 如何定义、调用函数,传递参数,以及处理返回值。 数据结构: 探索如何支持基本数据类型(整数、浮点数、布尔值)以及更复杂的数据结构(数组、字符串、结构体等)。 模块化与导入: 如何组织代码,实现代码的复用和分离。 错误处理与调试: 构建语言的错误报告机制,以及为方便调试提供的支持。 为何选择C语言作为基础? C语言以其接近硬件的特性、高效的内存控制能力以及丰富的库支持,成为构建复杂系统(包括编程语言本身)的绝佳选择。通过C语言,我们可以更深入地理解底层的指令集、内存布局以及操作系统的交互,从而真正掌握编程语言的“脉搏”。 本书适合谁? 计算机科学的探索者: 对编程语言的内部运作机制感到好奇,希望超越“黑箱”的开发者。 系统级编程爱好者: 想要深入理解编译原理、解释器原理和虚拟机实现的读者。 有一定C语言基础的开发者: 能够熟练使用C语言进行编程,并希望将其能力提升到新的层次。 希望提升编程思维的进阶者: 通过亲手构建一门语言,更深刻地理解抽象、设计模式和软件工程的挑战。 这本书能给你带来什么? 透彻理解编程语言的实现原理: 从词法分析到代码生成,每一个环节都将清晰呈现。 掌握构建复杂软件系统的核心技能: 学习如何将高层概念转化为可执行代码。 培养严谨的逻辑思维和问题解决能力: 构建一门语言的过程本身就是一次严谨的逻辑训练。 极大的成就感: 当你能够运行自己编写的、用自己设计的语言编写的程序时,那种满足感是无可比拟的。 为未来更高级的编程语言研究打下坚实基础: 无论是编译器开发、脚本引擎设计,还是领域特定语言(DSL)的创建,本书的知识都将是宝贵的财富。 《自制编程语言:基于C语言的深度探索》将为你打开一扇通往编程语言内部世界的大门,让你不仅成为语言的使用者,更能成为语言的设计者和创造者。准备好迎接这场激动人心的编程语言构建之旅吧!

作者简介

郑钢,网名大刚,毕业于北京大学,前百度运维开发工程师,《操作系统真象还原》作者。

爱父母,爱老婆,爱运动,爱钻研。

目录信息

第0章 一些可能令人迷惑的问题 1
0.0 成功的基石不是坚持,而是“不放弃” 1
0.1 你懂编程语言的“心”吗 2
0.2 编程语言的来历 2
0.3 语言一定要用更底层的语言来编写吗 2
0.4 编译型程序和脚本程序的异同 8
0.5 脚本语言的分类 10
0.6 为什么CPU要用数字而不是字符串作为指令 11
0.7 为什么脚本语言比编译型语言慢 11
0.8 既然脚本语言比较慢,为什么大家还要用 12
0.9 什么是中间代码 12
0.10 什么是编译器的前端、后端 13
0.11 词法分析、语法分析、语义分析和生成代码并不是串行执行 13
0.12 什么是符号表 14
0.13 什么是关系中的闭包 14
0.14 什么是程序中的闭包 15
0.15 什么是字母表 16
0.16 什么是语言 17
0.17 正规式就是正则表达式 17
0.18 什么是正规(表达)式和正规集 17
0.19 什么是有穷自动机 18
0.20 有穷自动机与词法分析的关系 19
0.21 词法分析用有穷自动机(有穷状态自动机)的弊端 19
0.22 什么是文法 20
0.23 BNF和EBNF,非终结符和终结符,开始符号及产生式 21
0.24 什么是句型、句子、短语 23
0.25 什么是语法分析 24
0.26 语法分析中的推导和归约为什么都要最“左” 25
0.27 什么是语义分析 26
0.28 什么是语法制导 27
0.29 词法分析器吃的是lex,挤出来的是token 27
0.30 什么是“遍” 28
0.31 文法为什么可以变换 28
0.32 为什么消除左递归和提取左因子 28
0.33 FIRST集、FOLLOW集、LL(1)文法 29
0.34 最右推导、最左归约、句柄 31
0.35 算符优先分析法 32
0.36 算符优先文法 33
0.37 非终结符中常常定义的因子和项是什么 33
0.38 什么是抽象语法树 33
0.39 编译器如何使用或实现文法中的产生式 34
0.40 程序计数器pc与ip的区别 35
第 1章 设计一种面向对象脚本语言 36
1.1 脚本语言的功能 36
1.2 关键字 37
1.3 脚本的执行方式 38
1.4 “纯手工”的开发环境 38
1.5 定义sparrow语言的文法 38
第2章 实现词法分析器 46
2.1 柔性数组 46
2.2 什么是字节序 47
2.3 一些基础的数据结构(本节源码stepByStep/c2/a) 48
2.4 定义虚拟机结构(本节源码stepByStep/c2/b) 56
2.5 实现源码读取(本节源码stepByStep/c2/c) 57
2.6 unicode与UTF-8 59
2.6.1 什么是unicode 59
2.6.2 什么是UTF-8 59
2.6.3 UTF-8编码规则 60
2.6.4 实现UTF-8编码、解码(本节源码stepByStep/c2/d) 61
2.7 实现词法分析器parser(本节源码stepByStep/c2/e) 66
2.7.1 lex和token 66
2.7.2 字符串和字符串内嵌表达式 66
2.7.3 单词识别流程 67
2.7.4 定义token和parser 68
2.7.5 解析关键字及获取字符 71
2.7.6 解析标识符和unicode码点 73
2.7.7 解析字符串、内嵌表达式、转义字符 75
2.7.8 跳过注释和空行 77
2.7.9 获取token 79
2.7.10 token匹配和初始化parser 84
2.8 构建主程序(本节源码stepByStep/c2/f) 85
2.9 编译、测试(本节源码stepByStep/c2/f) 88
2.9.1 一个简单的makefile 88
2.9.2 测试paser 92
第3章 类与对象 95
3.1 对象在C语言中的概貌 95
3.2 实现对象头(本节源码stepByStep/c3/a) 96
3.3 实现class定义(本节源码stepByStep/c3/a) 99
3.4 实现字符串对象(本节源码stepByStep/c3/a) 101
3.5 模块对象和实例对象(本节源码stepByStep/c3/a) 103
3.6 upvalue、openUpvalue和closedUpvalue 106
3.7 实现函数对象、闭包对象与调用框架(本节源码stepByStep/c3/a) 107
3.8 完善词法分析器之数字解析(本节源码stepByStep/c3/b) 111
3.9 完善词法分析器之字符串解析和获取token(本节源码stepByStep/c3/b) 114
3.10 最终版词法分析器的功能验证(本节源码stepByStep/c3/b) 116
3.11 实现list列表对象(本节源码stepByStep/c3/c) 118
3.12 range对象(本节源码stepByStep/c3/c) 121
3.13 迟到的class.c(本节源码stepByStep/c3/c) 122
3.14 map对象(本节源码stepByStep/c3/c) 124
3.14.1 哈希表 124
3.14.2 map对象头文件及entry 125
3.14.3 冲突探测链与伪删除 126
3.14.4 map对象的实现 128
3.15 线程对象(本节源码stepByStep/c3/c) 134
3.15.1 线程、协程浅述 134
3.15.2 运行时栈 137
3.15.3 用户线程的实现 138
第4章 原生方法及基础实现 142
4.1 解释器流程(本节源码stepBystep/c4/a) 142
4.2 符号表 144
4.2.1 模块的符号表 144
4.2.2 类方法的符号表 144
4.2.3 模块变量符号表 146
4.2.4 局部变量符号表 147
4.2.5 常量符号表 147
4.3 方法在运行时栈中的参数 147
4.4 定义模块变量(本节源码stepByStep/c4/b) 148
4.5 原生方法(本节源码stepByStep/c4/b) 154
4.5.1 定义裸类 154
4.5.2 定义返回值与方法绑定的宏 155
4.5.3 定义原生方法 157
4.5.4 符号表操作 159
4.5.5 定义类、绑定方法、绑定基类 160
4.6 元类及实现(本节源码stepByStep/c4/b) 161
4.6.1 meta-class类、class类、object类 161
4.6.2 创建元类,绑定类方法 163
4.7 加载模块(本节源码stepByStep/c4/c) 164
4.8 虚拟机简介 166
4.8.1 虚拟机分类及优缺点 166
4.8.2 为什么要采用虚拟机 168
4.8.3 虚拟机的简单优化 170
4.9 字节码 171
第5章 自上而下算符优先——TDOP 177
5.1 自上而下算符优先—TDOP 177
5.2 来自Douglas Crockford的教程 177
5.3 TDOP原理 194
5.3.1 一些概念 194
5.3.2 一个小例子 196
5.3.3 expression的思想 197
5.3.4 while(rbp < token.lbp)的意义 200
5.3.5 进入expression时当前token的类别 201
5.3.6 TDOP总结 202
第6章 实现语法分析与语义分析 204
6.1 定义指令(本节源码stepByStep/c6/a) 204
6.2 核心脚本(本节源码stepByStep/c6/a) 206
6.3 写入指令(本节源码stepByStep/c6/a) 212
6.4 编译模块(本节源码stepByStep/c6/a) 216
6.5 语义分析的本质 218
6.6 注册编译函数(本节源码stepByStep/c6/b) 218
6.7 赋值运算的条件 221
6.8 实现expression及其周边(本节源码stepByStep/c6/c) 223
6.9 局部变量作用域管理 228
6.10 变量声明、中缀、前缀及混合运算符方法签名(本节源码stepByStep/c6/d) 229
6.11 解析标识符(本节源码stepByStep/c6/e) 233
6.11.1 处理参数列表及相关 233
6.11.2 实现运算符和标识符的签名函数 235
6.11.3 upvalue的查找与添加 239
6.11.4 变量的加载与存储 242
6.11.5 编译代码块及结束编译单元 243
6.11.6 各种方法调用 246
6.11.7 标识符的编译 249
6.12 编译内嵌表达式(本节源码stepByStep/c6/f) 256
6.13 编译bool及null(本节源码stepByStep/c6/g) 258
6.14 this、继承、基类(本节源码stepByStep/c6/h) 259
6.15 编译小括号、中括号及list列表字面量(本节源码stepByStep/c6/i) 260
6.16 编译方法调用和map字面量(本节源码stepByStep/c6/j) 263
6.17 编译数学运算符(本节源码stepByStep/c6/k) 266
6.18 编译变量定义(本节源码stepByStep/c6/l) 270
6.19 编译语句 274
6.19.1 编译if语句(本节源码stepByStep/c6/m) 274
6.19.2 编译while语句(本节源码stepByStep/c6/n) 275
6.19.3 编译return、break和continue语句(本节源码stepByStep/c6/o) 280
6.19.4 编译for循环语句(本节源码stepByStep/c6/p) 284
6.19.5 编译代码块及单一语句(本节源码stepByStep/c6/q) 288
6.20 编译类定义(本节源码stepByStep/c6/r) 289
6.20.1 方法的声明与定义 289
6.20.2 构造函数与创建对象 291
6.20.3 编译方法 293
6.20.4 编译类定义 296
6.21 编译函数定义(本节源码stepByStep/c6/s) 298
6.22 编译模块导入(本节源码stepByStep/c6/t) 300
第7章 虚拟机 306
7.1 创建类与堆栈框架(本节源码stepByStep/c7/a) 306
7.2 upvalue的创建与关闭(本节源码stepByStep/c7/b) 309
7.3 修正操作数(本节源码stepByStep/c7/c) 312
7.4 执行指令(本节源码stepByStep/c7/d) 314
7.4.1 一些基础工作 314
7.4.2 解码、译码、执行(本节源码stepByStep/c7/d) 316
7.5 运行虚拟机(本节源码stepByStep/c7/e) 334
第8章 内建类及其方法 337
8.1 Bool类及其方法(本节源码stepByStep/c8/a) 337
8.2 线程类及其方法(本节源码stepByStep/c8/b) 338
8.3 函数类及其方法和函数调用重载(本节源码stepByStep/c8/c) 345
8.4 Null类及其方法(本节源码stepByStep/c8/d) 347
8.5 Num类及其方法(本节源码stepByStep/c8/e) 348
8.6 String类及其方法(本节源码stepByStep/c8/f) 355
8.7 List类及其方法(本节源码stepByStep/c8/g) 369
8.8 Map类及其方法(本节源码stepByStep/c8/h) 374
8.9 range类及其方法(本节源码stepByStep/c8/i) 380
8.10 System类及其方法(本节源码stepByStep/c8/j) 383
8.11 收尾与测试(本节源码stepByStep/c8/k) 388
第9章 垃圾回收 393
9.1 垃圾回收浅述 393
9.2 理论基础 395
9.3 标记—清扫回收算法 396
9.4 一些基础结构(本节源码stepByStep/c9/a) 397
9.5 实现GC(本节源码stepByStep/c9/a) 400
9.6 添加临时根对象与触发GC 411
第 10章 命令行及调试 415
10.1 释放虚拟机(本节源码stepByStep/c10/a) 415
10.2 简单的命令行界面(本节源码stepByStep/c10/a) 415
10.3 调试(本节源码stepByStep/c10/b) 417
· · · · · · (收起)

读后感

评分☆☆☆☆☆

评分☆☆☆☆☆

评分☆☆☆☆☆

评分☆☆☆☆☆

评分☆☆☆☆☆

用户评价

评分☆☆☆☆☆

收到《自制编程语言 基于C语言》这本书,我立刻被它所提出的“创造”概念所吸引。在熟悉了使用各种高级语言进行开发之后,我开始渴望去了解这些工具背后的原理,特别是编程语言本身的诞生过程。这本书以C语言作为基础,为我提供了一个绝佳的学习平台。我希望这本书能够带领我深入探究编程语言的生命周期,从最初的文本源文件,如何一步步被解析、理解,最终转化为机器能够执行的指令。我特别期待书中能够详细阐述编译器前端(词法分析、语法分析、语义分析)和后端(中间代码生成、优化、目标代码生成)的工作原理。我想了解如何设计一套语法规则,如何将其转化为计算机能够识别和执行的逻辑。C语言的加入,让我对如何进行底层操作、内存管理以及与操作系统进行交互有了更多的期待。如果书中能够提供一些清晰的图表和流程图,将复杂的概念可视化,那将极大地提高我的学习效率。总而言之,我希望这本书能够成为我通往理解编程语言本质的一扇大门,让我不再仅仅是使用者,更能成为一个理解并可能参与创造的开发者。

评分☆☆☆☆☆

这本书的封面设计相当朴实,没有花哨的插图,只有书名和作者姓名,传递出一种脚踏实地的感觉。我拿到这本书的时候,就被它沉甸甸的重量所吸引,这通常意味着内容详实,值得细细品味。我一直对编程语言的底层原理非常好奇,市面上很多教程都直接讲解如何使用某种语言,却很少深入剖析其设计思想和实现机制。这本书的名字——《自制编程语言 基于C语言》——直接击中了我的兴趣点。我希望通过这本书,能够跳出“拿来主义”的学习模式,真正理解一门语言是如何被构建出来的,它的语法解析、语义分析、代码生成等环节是如何运作的。C语言作为基础,也让我感到安心,毕竟C语言是许多底层系统和开发工具的基石,用它来构建一门新语言,本身就是一种深入理解计算机工作原理的绝佳方式。我特别期待书中能有一些图示,能够清晰地展现编译器的工作流程,或者某个语法结构在内存中的表示方式。当然,如果能有一些实际案例,比如用这门自制语言实现一个小型的计算器,或者一个简单的文本编辑器,那将是锦上添花,更能检验学习成果。我希望这本书的难度曲线是平缓的,能够循序渐进地引导我这个初学者进入这个看似复杂却又充满魅力的领域。

评分☆☆☆☆☆

我翻阅《自制编程语言 基于C语言》这本书,最吸引我的地方在于其“基于C语言”这一前提。我一直认为,想要深入理解一门编程语言,最好的方式就是了解它的底层实现,而C语言正是连接高级语言与计算机硬件的桥梁。这本书恰好满足了我对于这种“由内而外”学习编程语言的渴望。我希望这本书能够带领我一步步揭开编程语言编译过程的神秘面纱,从最初的源代码到最终的可执行程序,每一个环节都包含着精妙的设计和巧妙的算法。我特别期待书中能够详细讲解词法分析器(Lexer)和语法分析器(Parser)的构建,了解它们如何将无序的字符流转化为有意义的代码结构,比如如何处理括号匹配、关键字识别以及变量声明等。此外,我也对语义分析和代码生成的部分充满好奇,希望能够理解如何检查代码的逻辑正确性,以及如何将高级语言的抽象概念转化为底层的机器指令。如果书中能够提供一些实际的C语言代码示例,演示如何实现这些编译器组件,那将是对我学习的最大帮助。我相信,通过阅读这本书,我能够更深刻地理解编程语言的设计哲学,以及不同语言之间的优劣之处。

评分☆☆☆☆☆

我购入《自制编程语言 基于C语言》这本书,主要是出于对编程语言底层机制的好奇心。在日常开发中,我们总是习惯于直接使用现有的编程语言,而很少去思考它们是如何被创造出来的。这本书的标题直接点出了核心——“自制编程语言”,并且以C语言为基础,这对我来说是一个非常具有吸引力的组合。我希望这本书能够提供一种系统性的方法,让我能够从零开始,构建一门属于自己的编程语言。从词法分析、语法分析,到语义分析、代码生成,我希望书中能够详细讲解每一个阶段的关键概念和实现方法。尤其是对C语言的应用,我期待能够看到如何利用C语言的强大能力,去实现诸如表达式解析、语句处理、变量作用域管理等复杂的编译器功能。如果书中能够提供一些贯穿全书的示例项目,比如最终能生成一个简单的解释器或者一个基础的编译器,那将是非常宝贵的学习资源。我希望通过这本书,不仅能够掌握编程语言的构建技术,更能培养一种更深层次的计算机科学思维,理解不同编程范式之间的联系和差异,从而在未来的开发工作中做出更明智的技术选择。

评分☆☆☆☆☆

我拿到《自制编程语言 基于C语言》这本书,是被它提出的“自制”这个概念深深吸引。在如今这个充斥着各种成熟框架和高级语言的时代,自己从头开始构建一门编程语言,听起来像是一项极具挑战性但又无比 rewarding 的任务。我一直以来都对计算机科学的核心概念有着浓厚的兴趣,而编程语言的设计与实现无疑是其中的重中之重。我希望这本书能够提供一个清晰的路线图,从最基础的词法分析、语法分析开始,一步步构建起一门能够执行代码的语言。C语言作为实现的基础,对于理解内存管理、指针操作以及底层汇编的转换至关重要,这正是我希望能够加深理解的部分。我特别期待书中能够详细讲解编译器的工作流程,比如抽象语法树(AST)的构建、中间代码的生成,以及最终的代码优化和目标代码的产生。如果书中能够包含一些实际的代码示例,展示如何用C语言实现这些关键组件,那就更好了。我希望这本书不仅仅是理论的堆砌,更能提供实践的指导,让我能够亲手去构建、去调试,从而真正掌握编程语言的设计艺术。我希望这本书能够帮助我理解为什么某些语言设计成那样,它们的优缺点在哪里,以及如何在不同的场景下做出取舍。

评分☆☆☆☆☆

啰啰嗦嗦,借鉴lua,还好路子是对的

评分☆☆☆☆☆

- 不足7100行代码, 极其愉快的阅读体验 - 章节设计非常合理, 尤其是第 0 章, 特意补充了「足够的」基础知识, 用作者的话来说就是「这些足够了, 我们继续」

评分☆☆☆☆☆

我在读的郑钢的两本书都不错,知识全面,通俗易懂。部分小瑕疵可以在异步社区找到更正。另外一本书是《操作系统真相还原》

评分☆☆☆☆☆

啰啰嗦嗦,借鉴lua,还好路子是对的

评分☆☆☆☆☆

没有读完,记录几个印象比较深的问题吧。一,1.4节说书中介绍的语言使用C89实现,说不用比较新的C99,诚意满满。不明白用非常古老的语言标准(目前的C标准是ISO C2011)为何能显示诚意。二、然而到了2.1突然又开始大谈C99柔性数组,有点摸不着头脑。三、第二章把parser翻译成词法分析器,但是parser通常的翻译是解析器或者语法分析器,lexer或者tokenizer才会翻译成词法分析器。

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度,google,bing,sogou 等

© 2026 qciss.net All Rights Reserved. 小哈图书下载中心 版权所有