1.“开发编程语言”这样的表述不正确,编程语言是“设计”出来的,设计只需要思考和写文档,而该语言的编译器才是“开发”出来的。
2.编译器也是程序,所以也需要用编程语言来编写,至于用什么语言就随开发者的便了。
很多编程语言是用别的更基础的语言开发的,其中用最多的就是C语言。
3.C语言编译器很多,大部分都是用别的C语言编译器编译出来的,而最早的C语言编译器是用汇编语言写出来的,最早的汇编语言编译器是通过“编译器自举”开发出来的。
(编译原理讲到了“自举编译器”。大意就是先用底层语言(应该是汇编)写一个能运行,但效率极低的C语言编译器(底层语言不好优化),有了C语言的编译器以后,就可以用C语言好好写一个编译器了,用之前那个运行没问题,但效率低得编译器编译一下,就得到了可以使用的编译器了。)
创造一种计算机语言,想的太多了,先精通几种常用的语言吧,比如VB,C,C+等等
追问:
那如何汉化一种语言呢?
追答:
汉化一种语言?
中文的歧义性太强
2.中文的文字存储占有太大,用点阵存储,汉字的存储占的字节数太多
3.汉字的输入也是一个问题,虽然五笔的输入可以达到一个很快的速度,熟悉编程的就知道。(这点是个人意见)
4.汉字的结构性不是很强
语言编写都是用英文的,想要汉化几乎是不可能的,这不是汉化游戏
不要考虑这个了,想学习编程就先去学,你学了自然就懂了,这个是不能汉化的。
算机语言是二进制的,计算机处理的都是0,1,代表电路的两种状态。也就是电信号,用电信号控制实现功能。
基本上语言都是一层一层搭出来的
现代编程,已经变得非常容易,因为有各种IDE(集成开发环境)可用,所谓IDE,说白了就是一个代码编辑器(类似于记事本,比记事本强大)加上一个编译器或者说解释器,你编辑代码保存,然后点一点鼠标就可以完成编译(生成机器语言代码,对于人类没有可读性)。
那编译器怎么制作出来
那是高级语言自带功能,是高级语言的一部分,当然也是编写的程序了。早期的C是汇编写的,以后的版本,基本是用C来写的,包括微软的操作系统,VC等。
C语言的发展历史
C语言的发展颇为有趣。它的原型ALGOL 60语言。(也成为A语言)
1963年,剑桥大学将ALGOL 60语言发展成为CPL(Combined Programming Language)语言。
1967年,剑桥大学的Matin Richards 对CPL语言进行了简化,于是产生了BCPL语言。
1970年,美国贝尔实验室的Ken Thompson将BCPL进行了修改,并为它起了一个有趣的名字“B语言”。意思是将CPL语言煮干,提炼出它的精华。并且他用B语言写了第一个UNIX操作系统。
而在1973年,B语言也给人“煮”了一下,美国贝尔实验室的D.M.RITCHIE在B语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,这就是C语言。
为了使UNIX操作系统推广,1977年Dennis M.Ritchie 发表了不依赖于具体机器系统的C语言编译文本《可移植的C语言编译程序》。
1978年Brian W.Kernighian和Dennis M.Ritchie出版了名著《The C Programming Language》,从而使C语言成为目前世界上流行最广泛的高级程序设计语言。
1988 年,随着微型计算机的日益普及, 出现了许多C语言版本。由于没有统一的标准,使得这些C语言之间出现了一些不一致的地方。为了改变这种情况,美国国家标准研究所(ANSI)为C语言制定 了一套ANSI标准, 成为现行的C语言标准 3.C语言的主要特点 。C语言发展迅速, 而且成为最受欢迎的语言之一, 主要因为它具有强大的功能。许多著名的系统软件, 如DBASE Ⅲ PLUS、DBASE Ⅳ 都是由C 语言编写的。用C语言加上一些汇编语言子程序, 就更能显示C语言的优势了,象PC- DOS 、WORDSTAR等就是用这种方法编写的。
C语言的原型ALGOL 60语言。(也称为A语言) 1963年,剑桥大学将ALGOL 60语言发展成为CPL(Combined Programming Language)语言。 1967年,剑桥大学的Matin Richards 对CPL语言进行了简化,于是产生了BCPL语言。 1970年,美国贝尔实验室的Ken Thompson将BCPL进行了修改,并为它起了一个有趣的名字“B语言”。意思是将CPL语言煮干,提炼出它的精华。并且他用B语言写了第一个UNIX操作系统。 而在1973年,B语言也给人“煮”了一下,美国贝尔实验室的D.M.RITCHIE在B语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,这就是C语言。 。
作者:林建入
链接:http://www.zhihu.com/question/19756886/answer/13080459
来源:知乎
我曾经设计并实现过一门编程语言,作为我的毕业设计。
这非常有趣,尽管存在一些挑战,但事实上并没有想象中那么难。
基本上,你需要解决的第一个问题并非来自技术层面,而是概念层面——为什么你要设计一门新的编程语言?
我当初的动机是因为我对现有编程语言基于的一些编程思想心存疑惑,特别是我对class-based的编程语言持有异议。同样是实现Object-Oriented,prototype-based方式更加符合人的思维,而且更简单。
Javascript就是一个典型的例子。
但是Javascript本身又引入了一大堆的缺陷(语法和实现机制方面)。
于是我想这就是我想做的事情——设计并实现一门新的漂亮的prototype-based的编程语言。
当解决了概念层次上这个最大的,也是最重要的问题后,我便开始着手考虑细节。
这并不简单,问题逐渐浮现出来。
简单来说,定义一门语言,有点像定义一个宇宙。一开始,宇宙空空如也。为了让这个宇宙能够开始运转,并衍生出超越我们想象的复杂世界,我们作为“造物主”,需要准备好两种东西:一是元素——就是提供一些基本的数据类型;二是规则——基本元素之间的运算法则。
以上两种东西合起来,就是这门语言的“类型系统”。数学一点而言,就是定义一个基本集合,并定义在这个集合之上的运算。
这看起来没什么了不起。常常被人们忽略,但事实上,我们复杂的世界本质上也不过是由一些简单的基本单元基于一些基本规则运动的结果。语言设计也遵循这一原则。
可以说,类型系统是一门语言的核心。因为一门编程语言,本质而言,主要做两件事情:一是描述信息;二是处理信息。
描述信息需要使用存储空间,而处理信息需要使用运算。问题是运算本身对存储空间会进行特别的解释和假设,这就导致了我们的存储空间尽管都是字节或之类的看起来别无二致的通用的空间,但从语言角度来看必须对这些空间进行特别的限定和理解,于是便产生了”类型“的概念。
例如C语言有double和long,本质而言两种类型都是使用字节进行存储。但由于运算时采取完全不同的解释(甚至会采用cpu内部不同的运算器件),因此有必要对他们进行区分。
设计类型系统,特别是小而强大的类型系统,非常不容易!实际上我一开始以为这是很简单的一件事情,因为自己编程也有几年了,对编程很熟悉。但是很快我就发现事情不是那么简单。你需要做许多工作,而且一些细微的决策改变会深刻的影响这门语言。
这方面我不太打算给出什么建议,因为有许多论文和专著可供参考。相信如果你有兴趣,可以自己弄明白。
除了基本的类型系统之外,语言还需要有一些流程控制机制。和代码组织机制。这些都需要设计。可以借鉴现有的编程语言,也可以创造独一无二的新方式。随你自由。
至于对象、变量什么的,其实之前设计类型系统的时候就已经涵盖了。函数之类的在类型系统中也会涉及,同时也会影响代码组织机制等等。
我建议你参考这本书《程序设计语言——实践之路》。
我参考了许多编译方面的书籍,包括国外的经典著作。获得了很多帮助,不过看那些书你会发现总是离真正想要的“细节”尚有距离。给你推荐的这本书就弥补了这一细节上的缺失。是一门真正的实践教材。缺点是封面设计得太糟糕,知道的人不多,以及销量太少。但我必须强调这本书给我很大的帮助。(我甚至专门联系过书的作者,向他抱怨书的封面实在设计得太糟糕了,难道出版社不能找一个会设计的人来做这件事吗?他回答说他没有办法,因为出版社打算把这本书和其他基本不同的书一起组成一个系列,所以采用了一致的封面设计。我只能深表遗憾)
另外,《现代编译原理——C语言描述》这本书也很不错,会有一些比较新的和高阶一些的技术。(不过再新也不可能有论文新,只有看论文才能知道业界最新进展)
《编译器构造(英文版)》很棒,适合初学者。我买的是英文版,因为更容易看懂。
希望罗嗦了一大堆,对你有一丁点儿的帮助。
作者:涛吴
链接:http://www.zhihu.com/question/19756886/answer/13078616
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
首先要有爱。纯粹的,不屈的,倾注全心的爱。对于一个语言所塑造,只存在你想象之中的完美世界的爱……
……呃,然后你要决定你想设计的语言应该解决什么问题。虽然阿达•爱蕾丝女士[1]作为世界上第一个程序员,并没有使用任何特定的人造语言来编程,但现如今世风日下、人心不古,人们不再满足于用计算机算个伯努利数列,还要它解决登月、模拟核爆、设计气动外形、乃至用红鸟炸绿猪这样棘手的技术问题。面对不同的领域、不同的需求、不同的抽象层级、不同的思考范式,也就产生了各有特长的编程语言。专注于高效、便捷地解决某特定范畴之内问题的语言,叫做领域专用语言(Domain Specific Language,DSL)[2],而可以跨越若干领域解决问题的语言,叫做泛用语言(General-Purpose Language,GPL)[3]。常见的 DSL 比如 MATLAB、SQL 等等;常见的 GPL 自然就是那些 C 啦 Python 啦什么的。哦还有汇编。当然,两类语言之间的分界并不是很明显,有些语言一开始是作为 DSL 设计的,后来渐渐朝着 GPL 的方向发展,比如 PHP 和 JavaScript;反过来也有大量基于 GPL 开发而来的 DSL。注意也不是所有的计算机语言都可以归入这两类,有些语言被创造出来的理由很简单——“因为我们可以做到”,或者“就是为了好玩”,所以它们唤作“蛋痛编程语言”(Esoteric Programming Language)。
当然你的第一个自制语言也许只是为了尝试一下这件事情是否可行。尝试可行性,其实已经接近于“就是为了好玩”的境界了,所以要有蛋痛的觉悟,因为从头设计一套编程语言是颇为蛋痛的事情,几乎要事必躬亲,花费几天时间来实现微不足道的功能,展示给别人看时却招来“这有什么稀奇?”的茫然一问。如果不能乐在其中,如果爱意不够纯粹、不屈、倾注全心,是没办法做成的。
从最基本的角度看,一种编程语言就是:把一组特定的词汇,按照一组特定的语法规则组合到一起,形成计算机可以通过某种方式“理解”的东西,可以让计算机据此执行特定的动作。
先看看这件事情的最底层。所谓“计算机执行动作”,其实只是“把一个二进制数字传入 CPU,然后等待什么事情发生”的形而上描述。二进制计算机所能理解的唯一东西就是二进制数字,称为“机器码”[5]。比如:
10110 000 01100001
这串数字,对于某颗 CPU 来说,就是“把 01100001 放到 000 号寄存器里”的指令,其中“10110”的部分,就是 CPU 能懂得的“放入”指令。这样的指还有许许多多,比如做加法、求逻辑“与”,跳转,加密等等,全都只是一些二进制数字而已。
对人类来说,这种纯数字的写法太难记忆,就把它转写成:
MOV AL, 97
其中 MOV 代表“10110”,AL 代表 000 号寄存器,97 则是二进制数 01100001 的十进制表示。其他的数字指令也一并用这种简记法来转写,比如[6]。使用这样的一种转写方法来写程序,就是汇编语言(当然,这是一种极度简化的说法)。汇编语言谈不上太多设计,其实几乎就是在直接告诉 CPU 应该做什么。把汇编语言转化为机器码的程序,称为“汇编器(Assembler)“。
汇编语言的优势是很低级,你能直接控制 CPU 的行为;汇编语言的缺点也是它太低级,你必须直接控制 CPU 的行为。看看“把 A 的值放进甲寄存器;B 的值放进乙寄存器;把乙寄存器的值放进 A;把甲寄存器的值放进 B。”这段汇编指令——它想干什么?运行一下之后会看到,A 和 B 的值互换了。那么,能不能直接写“交换变量 A 和 B 的值”,然后由计算机来分解为一串机器码的组合呢?
所谓的“高级”编程语言就是这样的原理。将高级编程语言翻译成机器码(或者其他更接近机器码的形式)的过程,也就是计算机“理解”语言的过程,叫做“编译”,而完成这一工作的程序,叫做“编译器(compiler)”或者“解释器(interpreter)”,两者的区别是,编译器一次性解析所有代码并转换成机器码(但通常不会运行),而解释器则每解析一小部分就运行一小部分。
接下来就要考虑两个问题:高级语言要让人写起来方便;也要让计算机易懂。因为人类是难搞的物种,所以前者通常是语言设计的重点。毕竟,只要懂些编程的基本知识,任何人都可以在三天时间里设计出一门计算机语言,并且让计算机读懂它(也就是写出编译器),但要让一种计算机语言写起来舒服、读起来易懂、管理起来方便,所需耗费的心力和时间则相去不可以道里计。探寻这一问题的种种思潮所引发的范式转换和生产力革命,是计算机历史的永恒主题之一。计算机语言越来越高级,使用起来越来越简单,实现却越来越复杂;许多编程观念比如面向对象(object orientation)、函数编程(functional programming)、事件驱动(event driven)之诞生、沉寂、重现、兴盛和定型,都经由编程语言有所体现。
当然这并不是说编译部分就不重要。可靠、高效、灵活的编译器是一切编程工作的基石。我们日常所用的编译器都是如此千锤百炼的东西,以至于你很少会意识到它们本身也是复杂的软件工程项目,也有可能出问题,也在不断地发展着。十年前和现在的编译器,从架构理念到实现都有不小的差别。好在这种差别算不上天翻地覆,计算机语言编译的大致过程一直都是如下几个步骤:
1.高级语言的源代码经过词法分析(lexical analysis)成为一堆符记(token)
2.符记经过句法分析(syntactic analysis)成为语法树(abstract syntax tree, AST)
3.语法树经过优化,比如去除冗余的部分,最后映射成为机器码(machine code)
第一步,词法分析,根据的是语言设计者所规定的词汇规则。比如 PHP 规定变量前头必须加个 $ 符号,就是这样的规则。通常通过正则表达式(regular expression)给出这些规则。根据规则来分析源代码的编译器组件叫做词法分析器(lexer)或者扫描器(scanner)。扫描器可以自己手写,也可以让叫做 scanner generator 的程序读取一个正则表达式,然后帮你生成一个 scanner,比如 lex [7] 就是这样一个工具。词法分析的目的是判断人类写下的每个词是不是合乎拼写规则,如果不符的话,显然也就无法编译了。
第二步,句法分析,根据的是语言设计者所规定的语法规则。关于形式语言的语法理论,涉及到语言学和数理逻辑,是一个复杂而艰深的领域,好在对于设计一门计算机语言来说,只需要知道,计算机语言的语法通常是上下文无关文法(context-free grammar)[8] 即可:生成一条计算机语句的规则与这一规则所处的环境无关。这样一来,解析一条编程语句的过程就是确定的无二的。根据规则来将上一步骤获得的词汇解析为特定的数据结构——比如语法树——的工具,叫做句法分析器(parser)。同样,句法分析器可以自己写,也可以用特定的方法(最常见的是巴克斯范式(BNF)[9])给出下上下文无关文法的形式语言描述,然后用所谓 parser generator 来生成。可以说,语法树(或者类似的中间产物)代表了从编程语句中提炼出来的意义,这是整个编译过程的核心所在。
第三步,语法树或者其他的语义表示方法经由优化器(optimizer)的修剪,送入负责将特定结构转化为目标机器代码的程序生成可以运行的二进制程序。这一步必须考虑执行效率优化和目标架构的特点,与高级编程语言本身已经并无太大关联了。
了解以上步骤之后,就可以设计编程语言了。相关的指导书籍有很经典的几本,分别是:
龙书(Dragon Book): Compilers: Principles, Techniques, & Tools
虎书(Tiger Book):Compiler Implementation in C
鲸书(Whale Book):Advanced Compiler Design and Implementation
橡书(Ark Book) :Engineering a Compiler
还有魔法书(Wizard Book):Structure and Interpretation of Computer Programs
[1] http://en.wikipedia.org/wiki/Ada_Lovelace
[2] http://en.wikipedia.org/wiki/Domain-specific_language ,注意 DSL 并不一定是编程语言,有些 DSL 只用来描述数据
[3] http://en.wikipedia.org/wiki/General-purpose_programming_language
[4] http://en.wikipedia.org/wiki/Esoteric_programming_languages
[5] http://en.wikipedia.org/wiki/Machine_code
[6] http://en.wikipedia.org/wiki/X86_instruction_listings
[7] http://en.wikipedia.org/wiki/Lex_(software)
[8] http://en.wikipedia.org/wiki/Context-free_grammar
[9] http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form
编程语言是怎么设计出来的?
时间:2015-05-22 09:15来源:网络整理作者:51自学网
编程语言不过是一系列的预定义语法而已。至于说语言设计的原则,就是必须满足图灵完备的这个特征的,只要有图灵完备这个特性,这门语言从理论上来说就能够表达任何一个可计算的问题,因此就能够被我们用于描述问题的解的算法。
但是计算机不能够直接理解我们设计的语法,因此我们需要根据我们(编程语言的设计者)和你(语言使用者)之前约定的语法,将编程语言转换成可直接理解的汇编指令。
所谓转换,实际上就是降低抽象的层次。比如你现在使用*p = 0;这么一个指令,但是他的抽象层次过高,计算机不理解,因此我们需要将它具体化为:mov eax, p mov [eax], 0这么两条具体的指令。这两条指令的语义则处在CPU能够理解的层级,而他们的语义实际上是由CPU内部的门电路提供实现的。
至于说汇编语言,同高级语言一样是被设计出来的。CPU的制造者根据自家CPU能够执行的操作,制定了一套语法用于表示这些操作。这样你就能通过汇编语言指示机器按照你的意图工作了(执行生产商预定义好的操作)。
Lucida——一门函数式程序设计语言的诞生