面对需求人员不断提出的变态需求,软件开发人员的主要工作就是将需求人员口中或文档中的自然语言翻译成计算机能够理解的形式语言。自然语言指的是人类的语言,比如汉语、英语等,它具有多义性(在不同的上下文中,意义是不同的),冗余性(语法错了一点 并不会让人引起误解)。而形式语言是用精确的数学或机器可处理的公式定义的语言,例如计算机编程语言,它的特点就是语法非常严格,并不具有多义性和冗余性。
计算机编程语言可以分为高级语言和低级语言。高级语言编程更加容易、维护容易,具备可移植性(一份代码可以运行在多个平台上),典型代表 :Java、Python、C、C++、Ruby、C#等。低级语言只能在某个平台上运行,不具备可移植性,比如说我们在Intel x86编写的代码,无法在PowerPC或ARM上运行,它的典型代表有机器语言和汇编语言。
高级语言中又可以分为解释型语言(interpreting)和编译型语言(compiling)。解释型语言通过解释器读入高级语言写的指令,然后解释执行,Ruby、Python、PHP都是解释型语言。编译型语言使用编译器把高级语言变成目标代码。下面举个例子来介绍解释型语言和编译型语言的区别。
sum = x*4 - y
针对上面这行代码,计算机首先要做词法分析,将代码变成一个个token。下图中的每一行表示一个token。
再获得token之后,进行语法分析 构建抽象语法树(AST)。
解释型语言会对抽象语法树进行解释执行,而编译型语言会继续进行语义分析、中间代码生成 、代码优化、目标代码生成。
目前很多语言都是混合了解释和编译,例如Java,如下图所示,Java编译器先把Java编译成Class文件,然后在各个JVM上解释执行,由于每个平台对应一个JVM,因此Java是跨平台的。由于2-8原则的存在,JVM发现一段代码经常执行,那么,JVM将这段代码编译成本地代码,即如果有热点代码,就编译成本地代码(Native Code)。
image.png计算机高级语言还可以分为静态语言和动态语言。静态语言是代码经过编译之后,类型就确定了,典型代表就是Java。静态语言可以通过IDE来进行类型错误检查。而动态语言类型错误无法在编译期检查出来,会在运行期出现。为了帮助大家更好的理解,直接上代码。当执行test(new Women())
,IDEA会报告编译出错。为了消除这个错误,我们可以抽象出一个对象Person
,然后让Man
和Women
都继承于这个Person
,而且void test(Person p)
,这样一来既消除了错误,又维护了原有的功能。
class Man {
public void eat(){
System.out.println(" man eat!");
}
}
class Women {
public void eat(){
System.out.println(" Women eat!");
}
}
void test(Man m){
m.eat();
}
如何定义一门语言
通过上述内容的介绍,我们知道了计算机语言的分类,那么,我们该如何
定义一门语言呢?首选我们需要定义BNF。通过BNF来判定源代码是否符合该规范。下面,以Java的Class的BNF为例。
-
修饰符(modifier)是“public、private、protected、static等”关键字(keyword)之一;
-
修饰符之后是class关键字,class之后是标识符(identifier),标识符是有“a...z $..”组成
-
可选的extends
-
可选的implements
具体实例
public class Employee extend Person{
...
略
...
}
编译器首先读取public这个token,同时,由于编译器事先知道BNF,那么 它知道public是modifier是符合语法的。
然后,编译器读入class,同BNF进行比较,符合语法的。直到编译器读入extend,发现和BNF规定的不相符,提示错误。
如果源代码符合BNF规则,则继续进行词法分析、语法分析、语义分析等等,这里就不做过多介绍了,我会在后续文章中详细介绍的。
所有语言的基本逻辑
-
顺序
-
分支(if else,switch)
-
循环(while 、for)
image
欢迎关注微信公众号:木可大大,所有文章都将同步在公众号上。
网友评论