精华内容
下载资源
问答
  • 开发自己的编程语言
    万次阅读 多人点赞
    2021-07-29 09:50:22

    最适合人工智能开发的5种编程语言,你知道几种?

    01、Python

    第一名毫无疑问是 Python。尽管 Python 有些特性令人不爽(whitespace、Python 2.x 和 Python 3.x 之间的巨大差异、五种不同的包机制都在不同程度上有缺陷)但如果你正在从事 AI 工作,你几乎肯定会在某些时候用到 Python。

    Python 中可用库的数量是其他语言所无法企及的。NumPy 已经变得如此普遍,以至于几乎成为了张量运算的标准 API,Pandas 将 R 的强大而灵活的数据帧带入 Python。对于自然语言处理(NLP),您可以使用久负盛名的 NLTK 和快如闪电的 SpaCy。对于机器学习,有经过实战检验的 Scikit-learn。当谈到深度学习时,当前所有的库(TensorFlow,PyTorch,Chainer,Apache MXNet,Theano 等)都是在 Python 上首先实现的项目。

    (在LiveEdu上,一位德国的AI开发者教大家如何使用Python开发两个简单的机器学习模型)

    Python 是人工智能研究的前沿语言,这是拥有最多机器学习和深度学习框架的语言,也是 AI 研究者几乎都掌握的语言。由于这些原因,Python 仍然是人工智能编程语言之王,您没法绕过它。

    02、JAVA 和相关语言

    JVM 系列语言(Java,Scala,Kotlin,Clojure 等)也是 AI 应用开发的绝佳选择。无论是自然语言处理(CoreNLP)、张量运算(ND4J)还是完整的 GPU 加速深度学习堆栈(DL4J),您都可以使用大量的库来管理流水线的各个部分。另外,您还可以轻松访问 Apache Spark 和 Apache Hadoop 等大数据平台。

    Java 是大多数企业的通用语言,在 Java 8 和 Java 9 中提供了新的语言结构,这使得编写 Java 代码的体验不再像我们过去所记得的那样糟糕。使用 Java 编写人工智能应用可能会让人觉得无聊,但它确实能完成工作,并且您可以使用所有现成的 Java 基础架构来开发、部署和监视。

    03、C/C++

    在开发 AI 应用时,C / C ++ 不太可能成为您的首选,但如果您在嵌入式环境中工作,并且无法承受 Java 虚拟机或 Python 解释器的开销,那么 C / C ++ 就是最好的解决方案。当你需要榨干系统的每一滴性能时,你就得面对可怕的指针世界。

    幸运的是,现代 C / C ++ 写起来体验还不错(实话实说!)。您可以从下列方法中选择一个最适合的:您可以一头扎进堆栈底部,使用 CUDA 等库来编写自己的代码,这些代码将直接在 GPU 上运行;您也可以使用 TensorFlow 或 Caffe 以访问灵活的高级 API。后者还允许您导入数据科学家用 Python 写的模型,然后以 C / C ++ 级别的速度在生产环境中运行它们。

    在未来一年中,请密切留意 Rust 在 AI 领域的一些动作。结合 C / C ++ 级别的速度与类型和数据安全性,Rust 是实现产品级性能却不会造成安全问题的最佳选择。并且它现在已经可以与 TensorFlow 绑定了。

    04、Java

    Java?我没听错吧?其实,谷歌最近发布了 TensorFlow.js,这是一个 WebGL 加速库,允许您在 Web 浏览器中训练和运行机器学习模型。它还包括 Keras API 以及加载和使用在常规 TensorFlow 中训练过的模型的功能。这可能会吸引大量的 JS 开发者涌入 AI 领域。

    虽然 Java 目前能够访问的机器学习库与其他语言相比有所局限,但在不久的将来,开发者在网页中添加神经网络就和添加 React 组件或 CSS 属性一样简单。这听上去既强大又恐怖。

    TensorFlow.js 仍处于早期阶段。目前它可在浏览器中运行,但不适用于 Node.js。它还没有实现完整的 TensorFlow API。不过,我预计到 2018 年底,这两个问题都将基本得到解决,并且Java 将在不久之后大举进军 AI 界。

    05、R语言

    R 在这份榜单中排名最末,并且看上去将会越来越没落。

    R 是数据科学家喜欢的语言。但是,其他程序员在第一次接触 R 时会感到有些困惑,因为它采用了以数据帧为中心的方法。如果您有一组专门的 R 开发者,那么将 R 与 TensorFlow、Keras 或 H2O 搭配使用,进行研究、原型设计和实验是有意义的。但基于性能和操作方面的考虑,我不愿意推荐将 R 用于生产。

    虽然您可以写出能在生产服务器上部署的高性能 R 代码,但将这种用 R 语言编写的原型重新编码为 Java 或 Python 肯定会更容易。

    人工智能,火的不能再火的词了,想要驾驭他还需要不断的磨练,语言是与人工智能对话的基本条件,以上的五种语言你掌握了几种呢?不想成为未来世界的文盲就快些行动起来吧!

    更多相关内容
  • 本文是《打破国外垄断,开发中国人自己编程语言》系列文章的第1篇。本系列文章的主要目的是教大家学会如何从零开始设计一种编程语言(marvel语言),并使用marvel语言开发一些真实的项目,如移动App、Web应用等。

    下一篇:使用监听器实现计算器

    阅读本系列文章将是“最残酷的头脑风暴,大家做好准备了吗

    本文是《打破国外垄断,开发中国人自己的编程语言》系列文章的第1篇。本系列文章的主要目的是教大家学会如何从零开始设计一种编程语言(marvel语言),并使用marvel语言开发一些真实的项目,如移动App、Web应用等。marvel语言可以通过下面3种方式运行:

    1. 解释执行

    2. 编译成Java Bytecode,利用JVM执行

    3. 编译成二进制文件,本地执行(基于LLVM)

    本系列文章实现的marvel语言并不像很多《自己动手》系列一样,做一个玩具。marvel语言是一个工业级的编程语言,与kotlin、Java等语言是同一个级别,设计之初是为了试验编程语言的新特性。我们团队开发的超平台开发系统UnityMarvel内嵌的Ori语言的部分特性也是来源于Marvel。关于UnityMarvel的细节后面会专门写文章介绍。这里先讨论编译器的问题。

    1.  如果系统软件受到制约,有没有可能突出重围呢?

    我们知道,现在中美贸易战如火如荼,可能以后使用国外很多软件,尤其是系统软件,都会有一些问题。这就需要我们在一些关键领域有自己可以控制的技术和软件,例如,操作系统、编程语言、数据库、科学计算软件等。其实这些种类的软件中,大多都属于基础软件,只有操作系统和编程语言(以及相关的IDE)可以称为是系统软件。

    这里先说说基础软件和系统软件的区别。基础软件是指很多软件都依赖的软件,例如,流行的程序库(如tensorflow、pytorch等)、数据库(如MySQL、Oracle等)。但大多数基础软件的一个共同特点是只服务于特定领域,例如,你不可能用MySQL开发一款游戏,也不可能用tensorflow开发移动App。而在基础软件中有一小类,它们是通用的,几乎适合于各个领域,我们将这类软件称为系统软件。它们是整个IT领域的基础架构。没有它们,整个IT领域将不复存在。例如,目前,只有操作系统和编译器符合这两个特征。大家可以想想,没有了关系型数据库,还有其他类型的数据库可以使用,没有了tensorflow,IT领域也不会停止运转。但没有了Windows、macOS、Linux、C语言、Java语言这些技术,世界将会怎样,将会重新退回到工业文明时代。所以系统软件是基础软件的一个子集,而且必不可少。如果将基础软件和其他软件比作星球,那么系统软件就是星核。

    在系统软件中,编译器是最容易突破的。因为编译器(编程语言)的生态相比操作系统来说,更容易建立。这是因为目前有很多虚拟机可以选择,例如,最常用的是JVM,当然,还有微软的.net core等技术。如果我们的编程语言可以基于JVM,那么就意味着可以利用Java语言的所有生态,如果我们的编程语言可以用更容易的方式调用其他语言(如C++、Go等),在某种程度上,也就可以直接使用这些编程语言的生态。当然,还有更先进的超生态技术(UnityMarvel的Ori语言正是基于超生态技术的),总之,作为一种新的编程语言,利用其他的生态是最廉价的方式,当然,在语言发展的过程中,也可以逐渐建立自己的生态(相当于骑驴找马),这也是一种策略。所以如果想突破,编译器(编程语言)是最容易的一个。当然,如果拥有自己可以控制的编程语言,可以为后期的操作系统提供支援,例如,利用超生态技术,在建立新操作系统之前,就为该操作系统提前建立生态(这一点以后专门撰文阐述)。

    2. 开发编程语言需要哪些知识

    现在进入到最关键的部分了,开发一种编程语言到底需要哪些知识呢?其实需要的知识还是蛮多的。最基础的要求是必须至少会一种编程语言。如C、C++、Java、C#、Go、Python等。当然,推荐会3种以上的编程语言,因为我们是在设计编程语言,不是在设计普通的软件。在设计编程语言时,需要进行横向比较,也就是需要参考其他的编程语言,因为任何新技术都不可能100%完全凭空产生,这些新技术都会或多或少地留下其他同类技术的影子,编程语言也不例外。例如,UnityMarvel内嵌的Ori语言就是参考了数十种编程语言,以及加入了自己的新技术而最终形成的。

    除了要了解大量的编程语言外,还有很多与业务有关的知识需要掌握。主要的知识结构(不仅仅这些,后面用到了再详细讲)如下:

    (1)了解大量的编程语言(推荐3种以上)

    (2)编译原理的基础知识

    (3)算法能力

    (4)编译器前端生成器

    (5)学习能力

    (6)想象力

    尽管开发编程语言并不会像大学学的编译原理一样从0开始构造一个编译器,但编译原理的基础知识还是要掌握的,不了解编译原理的同学,赶紧上B站、西瓜视频、油管去补课,后期我也会结合marvel语言做相关的视频课程,大家可以关注哦!

    算法就不必说了,编译器里面充斥着各种算法,编译器的算法密度几乎超过了绝大多数应用。任何形式的算法都可能涉及到,最基础的数据结构必须掌握,其他的算法,能学多少就学多少,多多益善。这个没有固定的教程,也是需要不断在实践中学习。

    开发编译器的基本步骤如下图所示。

    首先说明一点,并不是所有的编译器都严格按照这些步骤进行,有可能会将多个步骤合成一个步骤(例如,语法分析和语义分析合成一步,最后输出AST),也有可能将一步分成多个步骤,或者再增加一些与业务相关的步骤。

    对于工业级编译器来说,并不会从0开始实现词法和语法分析器,并不是这东西有多难,而是如果完全手工编写代码,要添加或修改一个新语法,那简直就是一场噩梦,因为要修改非常多的地方,而且一旦出错,非常不好找原因(因为代码过于复杂)。由于词法分析和语法分析有规律可循,所以出现了很多通过文法生成词法分析器和语法分析器的工具,由于词法分析与语法分析是编译器前端的重要组成部分,所以这类工具通常称为“编译器前端生成器”。比较著名的包括lex、yacc、javacc、antlr等。其中lex是专门用来生成词法分析器的,yacc用来生成语法分析器的,javacc可以同时生成词法和语法分析器、antlr也同样可以生成词法分析器和语法分析器。不过lex和yacc只支持C语言,javacc只支持Java语言。而antlr支持多种编程语言,例如Java、C++、JavaScript、Go、C#、Swift等。本系列文章也使用了antlr的最新版本antlr4来实现编译器的前端(词法分析器和语法分析器)。

    这几种工具都是依赖于文法生成词法分析器和语法分析器的,例如,在antlr4中,如果要识别加减乘除四则运算,只需要编写下面的文法即可。

    expr:   expr op=('*'|'/') expr     
        |   expr op=('+'|'-') expr
    

    文法是不是很简单呢?但如果要编写完善的代码,可能需要上百行才能实现(我们团队实现的Ori语言,利用antlr4生成的词法和语法分析器,总共6万行Go语言代码,我们自己编写了大概4万行Go代码,整个编译器有超过10万行代码,3/5是自动生成的,2/5是自己编写的)。而且文法还标识了优先级,antlr4规定,写在前面的文法的优先级高于写在后面的文法的优先级。我们知道,对于四则运算来说,是先乘除,后加减,所以expr op=('*'|'/') expr 应该在expr op=('+'|'-') expr 前面,倒过来是不行了。如果要加更复杂的运算,例如,平方、开方、幂等,只需要修改这个文法即可,是不是很简单呢?

    前面说的前4点是硬知识,也有很多教程可以学习,但最后两点:学习能力和想象力,就要完全靠自己的天赋了。因为前面4点能让你做出一个看着还不错的编译器,但最后两点能决定你做的编译器有多强大。

    实现一个编程语言,所涉及到的知识要比实现编译器难度更大。因为如果实现编译器,并且是已经存在的编程语言,由于语法已经确定,所以只需要实现出来即可。但编程语言不同,一切需要重新设计,尤其是在涉及到新语法时,非常困难,需要了解的知识相当多,所以需要拥有快速学习能力,可以在短时间内学会并掌握任何知识和技术。另外,想象力更重要,因为设计一款新的编程语言,有些东西可能不仅仅局限于IT领域,也不仅仅局限于自己所从事的技术领域,例如。在Ori语言中,拥有一些创新的语法,需要同时适应类似JavaScript的单线程模式和Java的多线程模式。因此,拥有多维度的想象力才是最终取得胜利的关键。

    3. 自己设计的编程语言会流行吗

    我经常在网上看到很多同学在问,为什么中国没有自己流行的编程语言(尽管有易语言,但由于是中文编程,所以注定不会全球流行,国内也并不算流行)呢?BAT等大厂为何不开发一个呢?然后有人回答,开发编程语言容易,关键是生态,还有人回答,BAT是因为没有必要,因为编程语言没有和KPI挂钩,也有些人回答,开发一款编程语言,火起来很难。其实这些都可能是原因,但主要原因其实就是需求没有与行动挂钩,或者说,现在的编程语言已经足够满足需求了,没有必要再开发一款新的编程语言,而且这些大厂的盈利压力都很大,当然,还有技术积累的问题。

    其实编程语言有很多种,有一种就是像Java、C#、C++一样的通用编程语言,这类语言什么都能做,是一种图灵完备的编程语言。还有另外一种编程语言,如SQL、VBA、ABAP(SAP的内嵌语言),这类属于领域编程语言,他们也可能是图灵完备的,也可能不是图灵完备的。通常使用这类编程语言完成某些特定的工作,如SQL操作数据库,VBA操作Office、ABAP操作SAP数据等。其实在国内有很多公司内部已经提供了类似的领域语言,只是非常专业,功能单一,绝大多数人不清楚而已。

    至于自己开发出来的编程语言是否会流行,其实你们想太多了。编程语言是为了解决实际问题而存在的,不是为了流行而存在的。就像衣服,最初的用途是为了保暖,而不是时尚,当大多数人都使用自己生产的衣服保暖,那他就是流行款了!所以让编程语言解决实际问题才是优先要考虑,至于以后是否会流行,自己说了不算!

    像我们团队开发的UM系统,其实原来压根就没打算自己开发编程语言,想直接使用JavaScript,不过后来发现,JavaScript太动态了,使用JavaScript根本没有办法做一款完美的IDE,而且功能有限,并且混乱。还有就是JS是动态语言,如果将其转换为静态语言,会以牺牲性能为代价,而且无法有效融合单线程和多线程的特性,并且还无法与UM IDE融为一体,所以没办法,才开发一款自己的编程语言Ori,并且融合了数十种编程语言的优秀特性,而且加入了更先进的特性(如内嵌SQL、虚拟组件、虚拟数据库、支持跨平台的语法、客户端服务端一体化、柔性热更新等),当然,这些特性需要与UM IDE配合才能使用。

    4.  开发编程语言,从这里起航:配置Antlr4环境

    如果一上来就开发编程语言,估计大家就开始晕了,所以我们先从最简单的开始,就是先来编写一个可以解析加减乘除表达式的编译器。我们使用了antlr4来生成词法分析器和语法分析器,所以先要配置一下antlr4的开发环境。

    由于antlr4使用Java开发,所以不管用什么编程语言设计编译器,JDK必须安装,并且还需要一款强大的Java IDE,这里推荐Intellij IDEA。我们只使用Intellij IDEA的最基础功能,所以CE(社区版)版足够了,这个版本是免费的。

    在安装完Intellij IDEA CE后,到下面的页面下载antlr4工具相关的库。

    https://www.antlr.org/download.html

    进入页面,找到下面的部分,点击第1个链接下载即可。

    下载完antlr4的工具包后,找到其中的Java运行时库,并用Intellij IDEA CE创建一个Java工程,然后直接将Antlr4 Java运行时库复制到工程的lib目录中(没有lib目录可以建立一个),如下图所示。

    然后在lib目录的右键菜单中点击“Mark Directory as”>“Sources Root”菜单项,将lib编程源代码目录,这样Intellij IDEA CE就会搜索lib目录中的所有库。当然,可以直接在模块中引用antlr4的库,不过将antlr4 运行时库与工程放到一起,这样如果将工程复制到其他机器上,就不会由于antlr4的运行库没有复制而导致无法运行了。

    然后需要安装Intellij IDEA CE的Antlr插件。进入插件安装页面,如果没有安装antlr插件,选择Marketplace标签页,输入antlr搜索插件,通常第一个就是。点击右侧的install按钮即可安装。如果已经安装,Antlr插件会出现在Installed页面中,如下图所示。

           安装完Antlr插件后,新创建一个文件,将文件扩展名设置为g4,就会看到文件前面的图标变成了红色,里面有一个A字母,这就是Antlr4的标识,如下图所示。

    5. Antlr4的Hello World

    现在我们开始进入激动人心的时刻了,用Antlr4亲手做我们的第一个编译器:解析四则运算表达式的计算器。不过在完成这个编译器之前,一定要了解一下Antlr4。

    下面先给出一个可以识别以hello开头的词组的识别程序的文法。首先创建一个名为Hello.g4的文件,并输入下面的代码:

    grammar Hello;
    r  : 'hello' ID ;
    ID : [a-z]+ ;
    WS : [ \t\r\n]+ -> skip ;
    

    大家先不需要管这些代码是什么意思,只需要照猫画虎输入即可。

    然后在Hello.g4右键菜单点击“Configure ANTLR”菜单项,会弹出如下图的对话框,设置第一个文本输入框,指定生成目录,这里指定与Hello.g4相同的目录。Hello.g4生成的文件都会放在这个目录中。

    然后点击Hello.g4右键菜单的“Generate ANTLR Recognizer”菜单项,会自动生成一堆文件,如下图所示。注意:Java文件都隐藏了扩展名。

    Hello.java和MyHelloVisitor.java是后来创建的,其他文件都是自动生成的。其中HelloLexer.java是词法分析器、HelloParser.java是语法分析器,其他文件后面再说。

    大家可以打开这两个文件,看到每一个文件的内容都有上百行,这要是人工编写,会累死人,而使用Antlr4,只需要4行文法就搞定。如果要添加或修改原来的语法,只需要修改Hello.g4文件,然后再重新生成一遍即可。

    现在有一个问题,怎么用Hello.g4生成的一堆文件呢?或者换种问法,生成的这些文件有什么用呢?

    Hello.g4生成的这些文件的主要目的就是进行词法分析和语法分析,那么如何用呢?使用有如下两种方式:

    1.  用grun工具测试

    2. 用Java代码调用词法分析器和语法分析器,编写完整的编译器

    现在先来说说grun工具。其实并没有grun这个东西,grun是一个别名,真实的工具在是antlr-4.8-complete.jar中的 org.antlr.v4.gui.TestRig类,在macOS或Linux下,可以使用alias命令起一个别名,官方叫grun,所以这里就沿用了官方的叫法。如果在windows下,可以创建一个grun.cmd文件。

    起别名的完整命令如下:

    alias grun='java   -classpath  .:/System/Volumes/Data/sdk/compilers/antlr4-4.8/antlr-4.8-complete.jar org.antlr.v4.gui.TestRig'
    

    现在就可以使用grun测试我们的程序了。

    首先要说明一点,grun测试的是.class文件,不是.java文件,所以在测试之前,要在终端中切换到.class文件所在的目录。Intellij IDEA CE默认的.class目录是out/production目录,如下图所示。在一开始,前面生成的.java文件并没有编译,读者可以随便找个Java程序运行下,这时Intellij IDEA CE会编译所有还没有编译的.java文件,我们会发现,刚才生成的所有.java文件都生成了同名的.class文件。

    读者可以直接在操作系统的终端进入.class所在的目录,或者通过Intellij IDEA CE下方的Terminal也可以输入命令行,如下图所示。

    现在来做我们的第一个测试:

    首先输入下面的命令(先不需要管命令是什么意思):

    grun Hello r -tokens
    

    然后输入下面的内容:

    hello world
    

    如果读者在macOS或Linux下,按Ctrl+D,如果在Windows下,按Ctrl+Z输入结束符号,会输出如下图的内容:

    现在来解释一下grun Hello r -tokens是什么意思。Hello表示Hello.g4中grammar后面的部分,也就是Hello。r是文法产生式等号左侧的符号(非终结符),也就是r  : 'hello' ID ;中的r。-tokens表示列出所有的tokens。

    那么什么是token呢?其实token是词法分析器的输出,同时,token将作为语法分析器的输入,而AST(抽象语法树)则是语法分析器的输出。

    token就是编程语言中不可再分的单元,相当于编程语言的原子。看下面的程序:

    if(i == 10) {
    }
    

    这是一个非常简单的条件语句,那么在这两行代码中,有多少个token呢?根据token不可分割的原则,包含如下的token:

    if,(,i,==,10,),{,}
    

    上面用逗号(,)分隔的符号都是token,例如,if是关键字,将作为一个整体对待,在解析代码时,肯定不会将if拆开,10是一个整数,也将作为一个整体对待,肯定不会将其拆成1和0。

    那么Hello的输出结果意味着什么呢?我们输入了hello world,根据语法规则。任何字符串都需要以hello开头,所以hello将作为一个token(相当于前面条件语句的if关键字,这里hello是一个关键字)。而后面可以是任意字符串,但与hello之间至少要有一个空格。所以hello world符合Hello的语法规则,hello  abc也同样符合,而helloabc就不符合了,因为hello和abc之间没有任何分隔符,根据最长匹配原则,Antlr4会选择最长的字符串进行匹配,所以匹配的是helloabc,而不是hello。

    现在我们的实验也做完了,可能很多读者还是一头雾水,不过不要紧,我们再详细讲一下Antlr4到底是怎么分析的。

    Antlr4采用了自顶向下递归的分析方式。自顶向下就是先将整个编程语言源文件看成一个整体,这就是入口点,也就是Hello.g4中的r。这个入口点起任何名字都可以,只要不和其他的文法标识重名即可。然后从这个入口点开始,就可以用递归的方式写文法了。文法用于从上到下推导,左侧是文法标识,右侧是文法的产生式。例如,要识别下面一组字符串:

    hello world hello abc hello Bill hello 李宁

    很明显,这4行文本都是以hello开头,后面跟着任意的字符串,中间用空格分隔。所以我们的文法应该是以hello开头,后面跟一个标识,用ID表示。文法如下:

    r : 'hello' ID;
    

    在Antlr4中,每一个文法都要用分号(;)结尾,如果是固定的字符串,如关键字,用单引号括起来。如'hello'。

    ID表示任意的标识符,也是终结符。所谓终结符,是指不能再继续往下推导的符号(相当于树的叶子节点)。在Antlr4中,终结符标识用由首字母大写的字符串表示,如ID。而非终结符(可以继续往下推导)用首字母小写的字符串表示,如r。

    现在是自顶向下分析的第1步,第2步是处理ID。文法如下:

    ID : [a-z]+ ;
    

    ID的产生式不包含任何的非终结符,也就是再也无法继续推导了。[a-z]是一种简写,也就是a到z共26个小写字母中的任何一个,后面的加号(+)表示至少要有一个小写字母。

    到现在为止,自顶向下分析的过程已经完成了,分为两步,第一步将整个字符串看做一个整体,并且将其分解为hello和后面的任意字符串。第二部来处理这个任意字符串。这里规定,这个任意字符串只能由小写字母组成。

    不过现在还有一个问题,Antlr4怎么知道hello和world之间需要有空格或其他空白符分隔呢?其实这就涉及到Hello.g4的最后一行代码了:WS : [ \t\r\n]+ -> skip ;   这行代码设置了一个skip通道(通道会在后面的文章中详细讲解),用于忽略指定的字符,这些被忽略的字符,将作为token的分隔符,这里面指定了4个分隔符:空格、制表符(\t)、回车符(\r)、换行符(\n)。也就是说,下面的形式也是可以的:

    hello
    world
    

    ok,现在Hello.g4的语法规则已经讲的差不多了,里面涉及到了一些概念,在后面的文章中会详细讲解。现在来总结一下:

    Antlr4的文法文件是以g4作为扩展名,第一行代码必须以grammar开头,后面跟着语法名,如Hello,该名字必须与g4文件名一致。每一行代码都必须用分号(;)分隔。然后就是若干文法产生式了。例如,Ori语言的最顶端文法是这样的。

    grammar Ori;
    program : sourceElements? EOF
    sourceElement   : statement
    statement
    :
        importStatement
    | sqlStatement
        | dollarMemberStatement        
    |  classDeclarationStatement
        |  interfaceDeclarationStatement
    | functionDeclarationStatement
        | variableStatement     
    | ifStatement                
        | iterationStatement         
    | continueStatement           
        | breakStatement       
    | returnStatement             
        | withStatement             
    | switchStatement           
        | throwStatement           
    | tryStatement                 
        | blockStatement  
    | expressionStatement
        | commentStatement
        ;
    

    program是Ori语言的入口点,然后Ori语言将整个语言分成若干源代码元素(sourceElements?),后面的问号表示可选,也就是说,Ori语言的源代码文件可以是空文件。EOF是文件结束符。这里讲每一个源代码元素对应一条statement(语句),这里之所以不直接使用statement,而是使用sourceElement,是因为以后可能会进行扩展,这时只需要修改sourceElement即可(目前sourceElement等于statement),而一条语句包括多种,如ImportStatement、sqlStatement(内嵌SQL)、classDeclarationStatement(类声明)等。然后就继续往下分,如sqlStatement还会包含sqlInsert、sqlUpdate等。以此类推,直到不可再分为止。这就是自顶向下分析的基本方法,其实这就是分治法的一种表现,尽管编程语言看着很复杂,一个大型系统可能会有上百万甚至更多行代码,但如果将编程语言从顶向下分析,涉及到的语句种类也不过几十种而已。Ori语言的文法文件也就1000多行,包括词法文件部分,也就2000行出头。用2000行代码,就可以完全描述一种图灵完备的编程语言,真是perfect。而这2000行代码,生成的Go语言代码超过了60000行。

    现在再回到grun工具上来。其实grun的功能很强大,除了可以作为测试工具外,还可以显示Antlr4生成的AST,看一下自顶向下分析的流程。

    首先准备一个hello.txt文件,并输入hello world。然后在终端输入下面的命令(读者要将hello.txt文件的路径改成自己机器上的路径):

    grun Hello r -gui < /MyStudio/java/java_knowledge/antlr/test/hello.txt
    

    然后就会弹出如下图的窗口,右侧显示了AST的树状结构。Antlr4制作编译器的过程就是先根据源代码生成AST,然后对AST进行遍历(根据语言的特性,会遍历1到n遍),遍历完后,就会生成中间代码、以及最终的二进制文件。所以AST起到了承前启后的作用。

    6. 如何用程序进行词法和语法分析

    尽管已经了解了Antlr4的基本使用方法,但到现在为止,还没有用Java编写过一行代码呢?现在我就来演示如何用Java调用上一节生成的词法分析器和语法分析器。

    下面先给出实现代码:

    首先创建一个MyHelloVisitor.java文件,并输入下面的代码:

    import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
    
    
    public class MyHelloVisitor extends AbstractParseTreeVisitor<String> implements HelloVisitor<String> {
    
    
    @Override public String visitR(HelloParser.RContext ctx) {
        System.out.println(ctx.getText());
        System.out.println(ctx.ID().getText());
    return visitChildren(ctx);
      }
    }
    然后再创建一个Hello.java文件,并输入下面的代码:
    import org.antlr.v4.runtime.CharStream;
    import org.antlr.v4.runtime.CharStreams;
    import org.antlr.v4.runtime.CommonTokenStream;
    import org.antlr.v4.runtime.tree.ParseTree;
    
    
    public class Hello {
    public static void main(String[] args) throws Exception  {
    // 读取源代码文件,这里选择直接从字符串读取
             CharStream input = CharStreams.fromString("hello world");
    // 创建词法分析器对象 
            HelloLexer lexer = new HelloLexer(input);
    // 获取词法分析器输出的tokens
            CommonTokenStream tokens = new CommonTokenStream(lexer);
    // 创建语法分析器对象,并将词法分析器输出的tokens作为语法分析器的输入
            HelloParser parser = new HelloParser(tokens);
    // 开始分析程序,这也是生成AST的过程
            ParseTree tree = parser.r();    // 文法的入口点r会转换为一个方法,调用该方法,就会自顶向下递归分析源代码
    // 创建Visitor对象
            MyHelloVisitor hello = new MyHelloVisitor();
    // 开始遍历AST
            hello.visit(tree);
        }
    }
    

    现在运行Hello.java,如果在Run窗口输出如下图的内容,说明运行成功了。

    现在来解释一下前面的代码。这里先要知道Antlr4是如何遍历AST的。Antlr4有如下两种方式遍历AST:

    (1)listener

    (2)visitor

    第一种方式更灵活,但不容易使用。visitor不灵活,但容易使用。本例使用了第2种方式来遍历AST,但本系列文章的大多数代码主要使用listener来遍历AST。listener方式会在后面的文章中详细介绍,这里主要介绍visitor。其实这两种遍历AST的方式的原理类似,都是遇到了一个节点,就会调用相应的回调方法,然后将必要的信息作为参数传入回调方法,用户可以在回调方法中完成代码生成、数据处理、中间代码优化等工作。那么这些回调方法放在哪里呢?这就要说到前面创建的MyHelloVisitor类。该类实现了HelloVisitor接口,该接口是根据Hello.g4文件自动生成的,代码如下:

    import org.antlr.v4.runtime.tree.ParseTreeVisitor;
    public interface HelloVisitor<T> extends ParseTreeVisitor<T> {  
    T visitR(HelloParser.RContext ctx);
    }
    

    我们可以看到,该接口中只有一个方法,就是visitR,该方法是遍历到r节点调用的回调方法。

    如果文法文件很大时,会生成相当多的回调方法,例如,Ori语言的文法就生成了数百个回调方法,这些回调方法并不一定都用到,在这种情况下,并不需要实现所有的回调方法,所以Antlr4在生成回调接口文件的同时,还生成了一个默认实现类,如本例的HelloBaseVisitor,默认实现类已经默认实现了所有的回调方法,我们的Visitor类只需要从该类继承,就只需要实现必要的回调方法即可。

    import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
    
    
    public class HelloBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements HelloVisitor<T> {
    
    
    @Override public T visitR(HelloParser.RContext ctx) { return visitChildren(ctx); }
    }
    

    本例的MyHelloVisitor类继承了HelloBaseVisitor类,并覆盖了visitR方法,输出了r节点的文本和ID的文本。

    对于Hello类来说,就是最终的调用代码了。通常一个用Antlr4实现的编译器,需要经过如下几步:

    (1)读取源代码文件(或直接从字符串获取源代码)

    (2)创建词法分析器(输入是单个字符、输出是tokens)

    (3)创建语法分析器(输入是tokens、输出是AST)

    (4)开始遍历AST

    这4步已经在Hello类中做了详细的注释,大家可以自行查看。

    7.  弄一个可以解析表达式的计算器

    前面已经给出了一个完整的Antlr4案例,不过这个案例太简单了,没什么实际的用途,本节会利用Antlr4实现一个有实际价值的计算器程序。该程序可以解析过个表达式,表达式包含加减乘除运算,每一个表达式占一行,用分号(;)结尾。

    先给出文法:Calc.g4

    grammar Calc;
    // 下面是语法
    prog:   stat+ ;
    
    
    stat:   expr ';'                # printExpr
        |   ID '=' expr ';'         # assign
        |   NEWLINE                 # blank
        ;
    
    
    expr:   expr op=('*'|'/') expr      # MulDiv
        |   expr op=('+'|'-') expr      # AddSub
        |   INT                         # int
        |   ID                          # id
        |   '(' expr ')'                # parens
        ;
    // 下面是词法
    MUL :   '*' ;
    DIV :   '/' ;
    ADD :   '+' ;
    SUB :   '-' ;
    ID  :   [a-zA-Z]+ ;      // 匹配标识符
    INT :   [0-9]+ ;         // 匹配整数
    WS  :   [ \t]+ -> skip ; // 忽略空白符
    NEWLINE:'\r'? '\n' ;     // 空行
    

    现在生成Calc.g4 的相关文件。先看一下生成的CalcVisitor.java文件,代码如下:

    import org.antlr.v4.runtime.tree.ParseTreeVisitor;
    public interface CalcVisitor<T> extends ParseTreeVisitor<T> {
      T visitProg(CalcParser.ProgContext ctx);  
      T visitPrintExpr(CalcParser.PrintExprContext ctx);
      T visitAssign(CalcParser.AssignContext ctx);
      T visitBlank(CalcParser.BlankContext ctx);
      T visitParens(CalcParser.ParensContext ctx);
      T visitMulDiv(CalcParser.MulDivContext ctx);
      T visitAddSub(CalcParser.AddSubContext ctx);
      T visitId(CalcParser.IdContext ctx);
      T visitInt(CalcParser.IntContext ctx);
    }
    

    CalcVisitor有9个回调方法,从文法上看,有多少个文法,就应该有多少个回调方法。在Calc.g4中,除了第一个文法(prog:stat+;)外,其他的文法都起了别名,如printExpr,assign等。所以这些文法对应的回调方法都是以别名作为后缀的,然后前面加上visit。其实这9个方法,分别经过了AST的9个非叶子节点后(如果有的话),被分别调用。

    例如,现在测试这个表达式(将表达式放置expr.calc文件中):1+3 * 4 - 12 /5;    

    grun Calc prog  -gui < /MyStudio/java/java_knowledge/antlr/Calc/expr.calc
    

    执行上面的命令,会显示如下图的AST。

    要计算上述表达式,就需要遍历这棵AST。例如,当遍历到prog节点时,就会调用visitProg方法,通过该方法的参数可以获取prog节点的直接子节点的信息(就是左右两个stat节点)。当遇到减法表达式时,就会调用visitAddSub方法,以此类推。

    现在看一下EvalVisitor类的实现。该类的实现原理是当直接计算两个值时,如3 * 5、4 - 1,就分别由visitMulDivhe visitAddSub方法计算,并通过返回值返回计算结果。如果遇到变量(Calc支持变量),需要首先将变量放到一个Map中,然后在获取该变量时,会从Map读取。Map相当于一个符号表。

    import java.util.HashMap;
    import java.util.Map;
    
    
    public class EvalVisitor extends CalcBaseVisitor<Integer> {
    /** "memory" for our calculator; variable/value pairs go here */
    Map<String, Integer> memory = new HashMap<String, Integer>();
        boolean error = false;
    
    
    /** ID '=' expr NEWLINE */
    // 初始化变量的操作(赋值操作)
        @Override
    public Integer visitAssign(CalcParser.AssignContext ctx) {
    String id = ctx.ID().getText();  // id is left-hand side of '='
            int value = visit(ctx.expr());   // compute value of expression on right
            memory.put(id, value);           // store it in our memory
    return value;
        }
    
    
    /** expr NEWLINE */
    // 输出表达式的计算结果
        @Override
    public Integer visitPrintExpr(CalcParser.PrintExprContext ctx) {
    Integer value = visit(ctx.expr()); // evaluate the expr child
    System.out.println(value);         // print the result
    return 0;                          // return dummy value
        }
    
    
    /** INT */
    // 将字符串形式的整数转换为整数类型
        @Override
    public Integer visitInt(CalcParser.IntContext ctx) {
    return Integer.valueOf(ctx.INT().getText());
        }
    
    
    /** ID */
        @Override
    public Integer visitId(CalcParser.IdContext ctx) {
    String id = ctx.ID().getText();
    // 从Map中获取变量的值 
    if ( memory.containsKey(id) ) {
    return memory.get(id);
            } else {
    // 引用了不存在的变量,输出错误信息 
    System.err.println(String.format("变量<%s> 不存在!",id));
                error = true;
    
    
            }
    return 0;
        }
    
    
    /** expr op=('*'|'/') expr */
    // 计算乘法和除法
        @Override
    public Integer visitMulDiv(CalcParser.MulDivContext ctx) {
    
    
            int left = visit(ctx.expr(0));  // get value of left subexpression
            int right = visit(ctx.expr(1)); // get value of right subexpression
    
    
    if ( ctx.op.getType() == CalcParser.MUL ) return left * right;
    return left / right; // must be DIV
        }
    
    
    // 计算加法和减法
    /** expr op=('+'|'-') expr */
        @Override
    public Integer visitAddSub(CalcParser.AddSubContext ctx) {
            int left = visit(ctx.expr(0));  // get value of left subexpression
            int right = visit(ctx.expr(1)); // get value of right subexpression
    if ( ctx.op.getType() == CalcParser.ADD ) return left + right;
    return left - right; // must be SUB
        }
    
    
    /** '(' expr ')' */
    // 处理括号表达式
        @Override
    public Integer visitParens(CalcParser.ParensContext ctx) {
    return visit(ctx.expr()); // return child expr's value
        }
    }
    

    最后看一下主程序(MarvelCalc)的源代码。

    import org.antlr.v4.runtime.ANTLRInputStream;
    import org.antlr.v4.runtime.CharStream;
    import org.antlr.v4.runtime.CharStreams;
    import org.antlr.v4.runtime.CommonTokenStream;
    import org.antlr.v4.runtime.tree.ParseTree;
    import java.io.FileInputStream;
    import java.io.InputStream;
    
    
    public class MarvelCalc {
        public static void main(String[] args) throws Exception  {
            // 从文件读取源代码 
            String inputFile = null;
            if ( args.length>0 ) {
                inputFile = args[0];
            } else {
                System.out.println("语法格式:MarvelCalc inputfile");
                return;
            }
            InputStream is = System.in;
            if ( inputFile!=null ) is = new FileInputStream(inputFile);
    
    
    
    
            CharStream input = CharStreams.fromStream(is);
    
    
            CalcLexer lexer = new CalcLexer(input);
            CommonTokenStream tokens = new CommonTokenStream(lexer);
            CalcParser parser = new CalcParser(tokens);
            ParseTree tree = parser.prog(); // 分析源代码
    
    
            EvalVisitor eval = new EvalVisitor();
    
    
    
    
            eval.visit(tree);
        }
    }
    

    在expr.calc文件中输入下面的内容:

    1+3 * 4 - 12 /6;
    x = 40;
    y = 13;
    x * y + 20 - 42/6;
    z = 12;
    x + 5 * z - y;
    

    并使用下面的命令行执行计算器程序,或在IDE中将expr.calc作为参数允许MarvelCalc。

    java MarvelCalc expr.calc
    

    会得到下面的结果:

    11
    533
    87
    

    我们可以看到,在expr.calc文件中,有3个可以计算的表达式,其中最后两个表达式使用了变量,而输出结果就是这3个表达式的计算结果。从Calc.g4中也可以看出。语句一共有如下3种:

    (1) 输出表达式(包括运算、id和常量)

    (2)赋值表达式(创建变量)

    (3)空行

    从EvalVisitor类的实现可以看出,只有输出表达式才会输出结果,其他的表达式只是在内部计算,生成内部结果,如向Map中存储变量和值。

    OK,到现在为止,我们已经创建了一个非常实用的计算器程序,不过这个程序仍然很简单,在后面的文章中,将会不断利用新学到的知识完成更复杂的编译器程序,直到可以实现Marvel语言为止。

    展开全文
  • 世界著名软件质量评估机构TIOBE推出了2010年10月最新编程语言排名来了!Python成为最大的赢家,力压C、C++和Java三大主力语言,以11.27%的评级跃居到排行榜首位,成为20多年来的新语言霸主!排名前10的一次为:...

           著名评估机构TIOBE推出了2010年10月最新编程语言排行榜!Python成为最大的赢家,力压C、C++和Java三大主力语言,以11.27%的评级跃居到排行榜首位,成为20多年来的新语言霸主!排名前10的依次为:Python、C、Java、C++、C#、Visual Basic、JavaScript、SQL、PHP和Assembly language,这些语言已经广泛地应用到IT行业的各个开发领域中,下面我们就来细说一下这些语言的情况。

    1、Python

           Python诞生于1990年,起初它是一种用来替代 Perl的简单脚本语言,经过30来年的发展,现在已经发展的相当成熟。Python提供了高效的高级数据结构,支持简单有效的面向对象编程,Python的语法及其支持的动态类型,基于其解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言。 Python解释器易于扩展,Python提供了丰富的标准库,提供了适用于各个主要系统平台的源码和机器码。

           Python凭借着其语法的简捷清晰、易学性、庞大的库功能,被各种大中小企业广泛地采用,可以应用到多个软件系统中,俨然成为当今最流行的编程语言。

           几乎到处可以看到Python的身影,在近几年蓬勃发展起来的数据挖掘与人工智能领域,Python独占鳌头。在大数据和数据科学领域,任何集群架构软件都支持Python,Python本身也有很丰富的数据科学库。Python甚至被引入到了处理能力与内存有限的嵌入式领域。

    2、C

           C语言诞生于1972年,是一门面向过程的计算机高级编程语言,它提供一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。C语言描述问题比汇编语言迅速、工作量小、可读性好、易于调试、修改和移植,而代码质量与汇编语言相当。

           C语言兼顾了高级语言和汇编语言的优点,它不需要任何运行环境支持就能运行,广泛地应用于操作系统、系统底层的开发(比如驱动程序)、嵌入式软件的开发中。

    3、Java

           Java语言诞生于1995年,是一门面向对象的高级编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针、内存管理等复杂的概念,允许程序员以优雅的思维方式进行复杂的编程。
           Java几乎封装了所有的功能,与C++语言中复杂的多继承、内存自管理相比,Java更加的易用性,学习者更容易上手。Java中封装了完备的异常处理机制,一旦发生问题就会抛出异常,通过详细的异常信息可以快速定位问题,这点与C++相比,有着很大的优势。Java是基于虚拟机的解释性语言,支持跨平台(需要安装虚拟机)。

           随着近几年移动互联网的发展,Java作为安卓系统APP的开发语言,给Java注入了新的激情与活力。常用hadoop、spark、openstack等大数据与云计算开源框架,都是用Java开发的,Java已经成为大数据开发人员最喜欢的开发语言之一。Java被广泛地应用于PC桌面应用程序开发、大型系统Web后台开发、分布式大数据系统开发等多个领域中。

    4、C++

           C++语言诞生于20世纪80年代,C++是C语言的继承,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。

           一开始C++是作为C语言的增强版出现的,从给C语言增加类开始,不断的增加新特性。虚函数(virtual function)、运算符重载(operator overloading)、多重继承(multiple inheritance)、模板(template)、异常(exception)、RTTI、名字空间(name space)等C++常用特性相继被加入C++标准标准中。C++标准这些年进行了多次更新,又相继引入了匿名函数、lamda表达式等新的特性,现在C++标准已经更新到C++20。

           C++不仅拥有高效的执行效率,同时还致力于提高大规模程序的编程质量与程序设计语言的问题描述能力,C++被广泛地应用于桌面软件开发、嵌入式开发、服务器后台开发、大数据开发、音视频算法开发、游戏开发等多个领域中。

           我们经常使用的多个实时音视频系统,比如B站(bilibili)、抖音和快手,后台需要处理海量音视频的转码压缩等消耗资源的任务,是需要性能更高、处理效率更快的C++服务器程序来做支撑的!

    5、C#

           C#语言诞生于2000年,是微软公司发布的一种由C和C++衍生出来的面向对象的编程语言,它依托于.NET Framework框架的高级编程语言。
           C#在继承C和C++强大功能的同时,去掉了一些它们的复杂特性。C#又综合了VB简单的可视化操作和C++的高运行效率,以其强大的操作能力、创新的语言特性和便捷的面向组件编程的支持成为.NET开发的首选语言。 
           C#是被微软推出来去对抗Java的。C#与Java也有着很多相似的地方,它包括了诸如单一继承、接口、与Java几乎同样的语法和编译成中间代码再运行的过程。但C#与Java也有着明显的不同,它借鉴了Delphi的一个特点,与COM(组件对象模型)是直接集成的。
           C#被广泛地应用于桌面软件开发、ASP.NET web开发、服务器开发、游戏开发等领域中。

    6、Visual Basic

           Visual Basic语言诞生于1991年,它是微软开发的一种通用的基于对象的程序设计语言,为结构化的、模块化的、面向对象的、包含协助开发环境的事件驱动为机制的可视化程序设计语言。
           Visual Basic源自于BASIC编程语言,它拥有GUI图形用户界面和快速应用程序开发系统,可以轻易地使用DAO、RDO、ADO连接数据库,可以轻松地创建ActiveX控件,用于高效生成类型安全和面向对象的应用程序。程序员可以轻松的使用VB提供的组件快速建立一个应用程序。
           Visual Basic提供了用户界面,代码编写,调试运行和编译打包等诸多功能于一体的完备功能,为程序员提供了一整套功能强大的应用程序开发环境,主要用于桌面应用程序的开发。

    7、Javascript

           Javascript语言诞生于1995年,它是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它最开始是作为Web页面开发的脚本语言来使用,但它也被用到了很多非浏览器环境中,JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式、声明式、函数式编程范式。 
           JavaScript是一种应用于页面的高级脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。

    8、SQL(Structured Query Language)

           SQL语言诞生于1974年,它是结构化查询语言,是一种为数据库设计的数据库查询与设计语言,是用于存取数据以及查询、更新和管理数据库系统的。
           结构化查询语言是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统。结构化查询语言语句可以嵌套,这使它具有极大的灵活性和强大的功能。
           现在有多种常用的数据库系统,比如开源的MySQL、甲骨文的oracle、微软的SQL Server、IBM的DB2及Informix,还有诸如sqlite、acccess等小型数据库,还涌现了一批以MongoDB、NOSQL等为代表的非关系行数据库。这些数据库的SQL语句在语法和使用场景上都有一定的差别。
           国内几个大型的IT厂商都基于开源的数据库系统研发出了多个新型的、用于不同场景的大型数据库系统,以阿里、腾讯、华为为代表,这些厂商在数据库领域取得长足的进步,特别是阿里的OceanBase数据库。OceanBase数据库在国际权威机构国际事务处理性能委员会TPC举行的性能测试中,以创纪录的成绩夺魁,打破了国外老牌数据库厂商甲骨文等在数据库领域的垄断。

    9、PHP(Hypertext Preprocessor)

            PHP语言诞生于1974年,它是“超文本预处理器”,是服务器侧执行的脚本语言,尤其适用于Web后台系统的开发。PHP语法学习了C语言,吸纳了Java、Perl等多个语言的特色,发展出自己的特色语法,并根据它们的长项持续改进提升自己,该语言当初创建的主要目标是让开发人员快速编写出优质的web网站。 
           经过多年的发展,随着php-cli相关组件的快速发展和完善,PHP已经可以应用在 TCP/UDP服务、高性能Web、WebSocket服务、物联网、实时通讯、游戏、微服务等领域的系统研发中。

    10、Assembly Language

           Assembly Language是汇编语言,是相对于机器语言的第二代计算机语言。汇编语言用一些容易理解和记忆的字母,单词来代替一个特定的指令,比如:用“ADD”代表数字逻辑上的加减,“ MOV”代表数据传递等等,通过这种方法,人们很容易去阅读已经完成的程序或者理解程序正在执行的功能,对现有程序的bug修复以及运营维护都变得更加简单方便。
           在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。比如Windows平台的汇编语言使用的寄存器名称及指令名称,和Linux平台的有明显的差别。
           汇编语言不像其他大多数的编程语言一样被广泛用于程序设计。在今天的实际应用中,它通常被应用在底层,硬件操作和高要求的程序优化的场合。驱动程序、嵌入式操作系统和实时运行程序都需要汇编语言。比如我们在处理视频编解码的代码中会嵌入汇编语句提高代码的运行效率。

    展开全文
  • 以下是在您的应用程序中使用 Python 编程语言的一些优点和缺点: 优点 用途广泛、开发速度快、易于使用 你可以用更少的代码做更多的事情 种类繁多的图书馆 缺点 不是移动环境的原生 比其他编程语言慢 内存消耗非常高...

    移动应用程序(也称为移动应用程序或简称应用程序)是一种计算机程序或软件应用程序,旨在在手机、平板电脑或手表等移动设备上运行。

    应用程序最初旨在帮助提高生产力,例如电子邮件、日历和联系人数据库,但公众对应用程序的需求导致迅速扩展到其他领域,例如手机游戏、工厂自动化、GPS 和基于位置的服务、订单跟踪和购票。因此,现在有数百万个应用程序可用。

    应用程序通常从移动操作系统所有者运营的应用程序分发平台下载,例如 App Store (iOS) 或 Google Play Store。一些应用程序是免费的,而另一些应用程序是有价格的,利润在应用程序的创建者和分发平台之间分配。

    移动应用程序通常与设计用于在台式计算机上运行的桌面应用程序和在移动网络浏览器中而不是直接在移动设备上运行的网络应用程序形成对比。

    那么,未来会为移动应用带来什么?更重要的是,对于软件开发人员来说,预计 2022 年及以后哪些编程语言将成为最流行的移动应用程序开发?这就是你要发现的!

    最流行的移动应用程序开发语言

    考虑到上述情况,让我们来看看 2022 年移动应用程序开发的最佳编程语言。

    Python

    Python 已在 Web 开发服务中使用了近 30 年。它是 Web 开发中发展最快、最好的编码语言之一。

    Python 是一种高级动态类型编程语言,专注于健壮和快速的开发,其多功能性使其非常适合 Web 开发或数据科学。以下是在您的应用程序中使用 Python 编程语言的一些优点和缺点:

    优点

    • 用途广泛、开发速度快、易于使用
    • 你可以用更少的代码做更多的事情
    • 种类繁多的图书馆

    缺点

    • 不是移动环境的原生
    • 比其他编程语言慢
    • 内存消耗非常高

    迅速

    Swift 是一种适用于 iOS 和 OS X 的新编程语言,它建立在 C 和 Objective-C 的精华之上,但不受 C 兼容性的限制。Swift 是少数采用安全编程模式并添加现代功能以使编程更轻松、更灵活和更有趣的应用程序开发语言之一。

    Swift 的全新状态,以成熟且备受喜爱的 Cocoa 和 Cocoa Touch 框架为后盾,是一个重新构想移动应用程序开发工作方式的机会。

    优点

    • 快速发展过程
    • 提高安全性和性能
    • 应用程序的速度和可扩展性

    缺点

    • 人才库有限
    • 缺乏对早期 iOS 版本的支持
    • 语言还年轻

    JavaScript

    JavaScript 于 1995 年由 Netscape 公司发明,是一种用于 HTML 页面的编程语言。JavaScript 程序由内置在用户 Web 浏览器中的解释器运行。

    对于移动应用程序,应该提到 React Native,这是一种开源 JavaScript 框架,旨在使用相同的代码库在 iOS、Android 和 Web 应用程序等多个平台上构建应用程序。

    React Native 基于 React,它为移动应用程序开发带来了所有荣耀。没有什么比 JavaScript 更适合构建应用程序了。简而言之,JavaScript 是一种解释型的轻量级语言,旨在创建以网络为中心的应用程序。由于它与 HTML 集成,因此很容易实现。此外,建议您按照React Native 上的正确指南开发应用程序,因为它可以帮助您轻松构建跨 Android 和 iOS 平台的应用程序。

    优点

    • 将真实 DOM 变成虚拟 DOM
    • 丰富的接口和扩展功能
    • 能够进行前端和后端开发

    缺点

    • 需要支持 JavaScript 的浏览器
    • 缺乏调试设施
    • 支持单继承,不支持多继承

    SQL

    SQL 是一种标准化的计算机语言,目前被认为是最好的编程语言之一。它最初由 IBM 开发,用于使用声明性语句查询、更改和定义关系数据库。

    开发人员可以成为 SQL 开发的大师。SQL,也称为结构化查询语言,是一种数据库计算机语言,旨在管理关系数据库管理系统 (RDBMS) 中的数据。它可以对数据库执行查询并从数据库中检索数据。

    优点

    • 无需代码即可轻松管理
    • 定义明确的标准和多个数据视图
    • 便携式和交互式语言

    缺点

    • 界面复杂,难以扩展
    • 部分控制,需要专业人员
    • 在快速开发环境中存在问题

    Rust 是一种专注于安全性、速度和并发性的编程语言。它的设计使您可以创建具有低级语言的性能和控制,但具有高级语言的强大抽象的程序。

    这些特性使 Rust 适合那些在 C 等语言方面有经验并正在寻找更安全的替代方案的程序员,也适合那些在 Python 等语言中寻找方法来编写性能更好而又不牺牲表现力的代码的程序员。

    优点

    • 强大的社区支持
    • 强大的仿制药支持,安全有保障
    • 节省测试和调试时间

    缺点

    • 编译速度慢
    • 编程语言很复杂
    • 缺乏高效的垃圾收集

    楼梯

    Scala 流畅地集成了面向对象和函数式编程。它旨在以简洁、优雅和类型安全的方式表达常见的编程模式。

    Scala 引入了几种创新的语言结构,例如灵活的语法和类型系统,可以构建高级库以及新的特定领域语言。此外,Scala 与 Java 兼容,允许使用 Java 库和框架而无需胶水代码或额外的声明。

    优点

    • 内置控制结构
    • 强大的 IDE 支持
    • 可扩展且功能强大

    缺点

    • 有限的开发者池
    • 没有真正的尾递归优化
    • 使类型信息难以理解

    红宝石

    Ruby 是一种动态编程语言,具有复杂但富有表现力的语法和具有丰富强大 API 的核心类库。Ruby 从 Lisp、Smalltalk 和 Perl 中汲取灵感,但使用一种易于 C 和 Java 程序员学习的语法。

    尽管是纯粹的面向对象语言,Ruby 也适用于过程和函数式编程风格。它包括强大的元编程功能,可用于创建特定领域的语言或 DSL。

    优点

    • 开源和 100% 免费
    • 充满活力的 ruby​ on rails 社区
    • 原型制作速度快

    缺点

    • 运行速度较慢
    • 缺乏灵活性
    • 更高的成本

    C++

    无数开发人员基本上在每个应用程序领域都使用 C++。它是从 C 编程语言发展而来的,除了少数例外,它保留了 C 作为一个子集。

    C++ 的最大优势在于它能够有效地用于需要在各种应用领域工作的应用程序。找到一个涉及局域网和广域网、数字、图形、用户交互和数据库访问的应用程序是很常见的。

    优点

    • 平台独立性和可移植性
    • 多范式语言
    • 可扩展且与 C 兼容

    缺点

    • 没有垃圾收集器
    • 不支持内置线程
    • 缺乏安全感

    C#

    C# 是一种通用的、类型安全的编程语言。该语言的目标是程序员的生产力。为此,C# 平衡了简单性、表现力和性能。

    C# 语言与平台无关,可与一系列特定于平台的编译器和框架一起使用,其中最著名的是适用于 Windows 的 Microsoft .NET 框架。它是面向对象范式的丰富实现,包括封装、继承和多态。

    优点

    • 布尔条件和标准库
    • 自动垃圾收集
    • 易于编写代码

    缺点

    • 缺乏独立的编译器
    • 不适合低级的东西
    • 糟糕的平台GUI

    PHP

    PHP 最初是一个小型开源项目,随着越来越多的人发现它的有用性而发展。Rasmus Lerdorf 早在 1994 年就发布了 PHP 的第一个版本。PHP 是“PHP:超文本预处理器”的递归首字母缩写词。它是一种嵌入在 HTML 中的服务器端脚本语言。

    它用于管理动态内容、数据库和会话跟踪,甚至构建整个电子商务网站。PHP 与许多流行的数据库集成,包括 MySQL、PostgreSQL、Oracle、Sybase、Informix 和 Microsoft SQL Server。

    优点

    • 强大的支持库
    • 内置数据库
    • 成本效益

    缺点

    • 难以管理
    • 容易处理错误
    • 不安全

    HTML5

    HTML5 代表超文本标记语言版本 5。它由万维网联盟 (W3C) 于 2014 年 10 月发布,是应用程序开发的最佳编码语言之一。它是解释网页的语言或代码的最新版本。

    创建 HTML5 是为了实现当今网站所需的各种特性。它很容易采用,因为 HTML 的编程版本没有重大改变。调试和调整代码更容易,并且极大地促进了搜索引擎优化 (SEO)。

    优点

    • 完整的 UI 和网格系统
    • 最友好的搜索引擎
    • 易于使用和学习

    缺点

    • 需要不必要的编码
    • 额外的定制
    • 动态页面不够用

    科特林

    Kotlin 是一种现代的、静态类型的、与 Android 兼容的语言,它修复了许多 Java 问题,例如空指针异常或过多的代码冗长。Kotlin通过提高代码质量和安全性,提高开发人员的性能,将应用程序开发提升到一个全新的水平。

    Kotlin 旨在作为一个跨语言项目与 Java 无缝并行工作。现有的 Java 库和框架生态系统可与 Kotlin 一起使用,而不会造成任何性能损失。

    优点

    • 清晰紧凑的代码库
    • 合并过程和函数式编程
    • 最大化生产力

    缺点

    • 编译速度慢
    • 人才库较小
    • 学习资源有限

    Flutter 是使用 Dart 开发的,包含一个独特的技术栈,使其与竞争对手区分开来。Dart 语言是Flutter 应用程序开发的核心。

    像 Flutter 这样的现代框架需要高级现代语言才能为开发人员提供最佳体验,从而可以创建健壮的移动应用程序。Dart 旨在将大多数高级语言的优点与成熟的语言特性相结合,包括高效工具、类型注释和垃圾收集。

    优点

    • 定制小部件
    • 允许即时更新
    • 高性能和热重载

    缺点

    • 没有第三方库
    • 网络浏览器不支持
    • 有限的资源

    Go 由 Google 的 Robert Griesemer、Rob Pike 和 Ken Thompson 构建,并于 2009 年 11 月宣布。该语言及其随附工具的目标是具有表现力、编译和执行效率以及写作效率可靠和强大的程序。

    Go 与 C 有表面相似之处,并且与 C 一样,是专业程序员的工具,以最少的手段实现最大的效果。但它不仅仅是 C 的更新版本,具有独特的数据抽象方法和异常灵活的面向对象编程。

    优点

    • 易于部署
    • 高效优化代码的能力
    • 静态代码分析

    缺点

    • 依赖管理缺陷
    • 自动化引发错误
    • 内部不一致

    目标 C

    Objective-C 语言是一种简单的计算机语言,旨在实现复杂的面向对象编程。这种方法使程序设计更直观、开发更快、更易于修改并且更易于理解。它不仅导致了构建程序的替代方式,而且还导致了构思编程任务的替代方式。

    Cocoa 框架选择 Objective-C 语言是因为它的动态特性。它的语法小巧、明确且易于学习,并为应用程序提供最佳代码。

    优点

    • 可移植的结构化编程语言
    • 可重用性;一次编写,多次使用
    • 数据冗余和继承

    缺点

    • 内存管理不足
    • 运行时检查
    • 缺乏异常处理

    编程语言不断发展

    您需要的软件类型是您选择哪种编程语言时需要考虑的主要考虑因素之一。

    例如,基于 Web 的初创公司更有可能使用 Python 和 JavaScript 进行编程。较大的公司倾向于使用 C# 或 Java 开发其内部软件应用程序,并使用 PHP 开发其 Web 应用程序。嵌入式设备,例如汽车和医疗保健行业的设备,运行用 C、C++ 或 Rust 编写的软件。

    编程语言的所有内容都在不断发展。如果您考虑上面我向您展示的因素、优点和缺点列表,您将能够明智地为您的应用程序开发选择最佳编码语言。

    如果对Python有兴趣,想了解更多的Python以及AIoT知识,解决测试问题,以及入门指导,帮你解决学习Python中遇到的困惑,我们这里有技术高手。如果你正在找工作或者刚刚学校出来,又或者已经工作但是经常觉得难点很多,觉得自己Python方面学的不够精想要继续学习的,想转行怕学不会的, 都可以加入我们,可领取最新Python大厂面试资料和Python爬虫、人工智能、学习资料!微信公众号【Python大本营】等你来玩奥~

    展开全文
  • 之所以说这件事,就是想告诉同学们,努力固然重要,但选择必须要对,一旦选择错了,那很多努力都是白费。这篇文章就是来给同学们提个醒,2022 年最好的编程语言是什么?看完后你就知道该如何地去选择了。 ......
  • 开发自己编程语言

    千次阅读 2013-02-03 22:11:40
    编程是一门艺术,而编程语言则是这门艺术的缔造者。计算机系的很多学生都对编程语言涉及到的编译原理表示畏惧,其实编译原理本身并不复杂,不过由于目前市面上有关编译原理的书籍大部分都是由国外的原著翻译过来的,...
  • 2020年10种最佳移动开发编程语言

    千次阅读 2020-04-19 17:01:07
    总结 因此,我们总结了2020年排名前10位的移动应用程序开发编程语言,您应该考虑学习作为移动应用程序开发人员来为软件行业带来可喜的增长。小伙伴有前端基础的话,又想学移动开发,本人推荐react native或flutter...
  • 游戏开发中常见的10种编程语言

    万次阅读 2019-11-18 20:53:24
    以下是用于游戏开发的十大编程语言的列表。 1、C# C#如今在许多游戏引擎中广泛使用,并且是游戏开发所需的很流行的语言之一。 它具有XNA框架,该框架是Microsoft的一组工具和运行时环境,使其特别适用于Xbox或...
  • 全世界的编程语言有 600 多种,TIOBE 统计的有 100 种,参与排名的有 50 种,前 20 种是常用的,它们目前正在流行,或者曾经非常流行。 图1:2021 年 10 月份编程语言排名 TOP 20 TIOBE 是全球最著名的编程语言排行...
  • 大数据开发需要学习哪些编程语言

    千次阅读 2022-01-26 12:11:50
    大数据开发需要学什么编程语言?随着大数据的持续升温,越来越多的人投身于大数据的浪潮之中,不少完全没基础的小伙伴,难免会有这样的疑问,从事大数据需要学习什么编程语言呢?其实这个问题没有固定的答案,像...
  • 2021编程语言排行榜出炉

    万次阅读 多人点赞 2021-11-08 08:36:04
    今日,IEEE Spectrum 发布了 2021 年度编程语言排行榜,其中 Python 在总榜单以及其他几个分榜单中依然牢牢占据第一名的位置。另外值得关注的是微软 C# 语言,它的排行从 2020 年的第 23 名跃升至了今年的第 6 名,...
  • 对于刚刚进入APP软件开发领域的新手来说,根本就不知晓要选择什么编程语言和需要什么开发环境来开发APP软件,这时的就会面临许多的选择和建议。云之梦APP软件开发公司拥有丰富的APP开发经验,因此开发APP软件需要...
  • 如今互联网+时代,app开发...IOS是基于C语言开发的软件,常用编程语言为Objective-C和Swift。 Objective-C是编写iOS操作系统和iOS应用程序的利器,Objective-C的流行完全归功于iphone的成功。Objective-C是OS系统的开.
  • 人工智能ai用什么编程语言 AI( 人工智能 )为应用程序开发人员开辟了无限的可能性。 通过利用机器学习或深度学习,您可以产生更好的用户配置文件,个性化设置和推荐,或者合并更智能的搜索,语音界面或智能帮助,或...
  • 最全GIS开发编程语言汇总及分类

    千次阅读 2022-01-27 11:36:44
    本文主要介绍常见的流行的编程语言,以及GIS开发中常用的编程语言类型。
  • 编程语言应该如何选择?

    万次阅读 2022-05-19 11:30:31
      关于编程语言的选择,我一直认为你选择了什么样的编程语言,就会在以后大概率走上什么样的道路。如果你一开始就把编程语言选错了,你将会走许多弯路,最后不得不回到“正确的道路”。说到这,可能会有人反驳说:...
  • 软件测试功底技术——编程语言

    千次阅读 2022-04-28 11:56:35
    软件测试功底技术——编程语言 高级的自动化测试工程师都会涉入到编程语言的检查环节。懂编程,不代表你要写出一个网站或者一个小程序,如果要求真那么高的话,你都可以去做开发了。所以做测试要学编程只不过是为了...
  • 2020 年最牛逼的 10 门编程语言

    万次阅读 多人点赞 2020-08-20 14:21:03
    最后,希望同学们能够从这 10 门编程语言中选择一门自己喜欢的,深入研究,无论是哪门语言,我相信,只要你精通了,就一定能够找到自己心仪的工作,如果你只是浅尝辄止,那就不好意思呵呵了。 我是沉默王二,一枚有...
  • 十大编程语言Lots of programming languages to choose from and you don’t know where to start? This listicle is for you! We’re discussing the best programming languages of 2020 today. 许多编程语言可供...
  • 区块链开发主流编程语言居然是Go语言!? 一、区块链与分布式的关系 目前区块链概念正在大面积普及。很多人感觉这个东西好抽象,没有什么落地的东西,今天这里主要介绍一下区块链的一些落地项目和有关区块链技术...
  • Web前端是互联网时代软件产品研发中不可缺少的一种专业研发角色。...从广义上来讲,所有用户终端产品与视觉和交互有关的部分,都是Web前端...就目前Web前端开发可能涉及的语言来讲,有PHP语言、JavaScript、Ruby、HTML...
  • 世界上到底有多少种编程语言

    千次阅读 热门讨论 2021-11-04 15:19:16
    最近,网站上看到一个很有意思的问题:世界上到底有多少种编程语言? 查遍网络之后,仍然没有找到准确答案,只知道几千的数量是有的,但是我们常用的也就几十来个,其中最常见的便是Java、Python、C++、C语言、...
  • 适合人工智能的编程语言有哪些

    千次阅读 2021-12-08 15:26:51
    编程语言是人工智能开发项目的支柱,有了它的帮助,软件开发人员才可以在不用通晓仅用于科学家相互交流的高度专业化语言的情况下而创建出新的 AI 解决方案。 那么,人工智能在全球各行业中的使用率如何? AI 在...
  • 九种编程语言大对比(图文版)

    千次阅读 2021-01-31 00:00:00
    本文9张信息图囊括了九种主流编程语言:Python、Java、C、C++、JavaScript、C#、Ruby、PHP以及Objective-C。对于每种编程语言,大家都能够看到由其打造...
  • 你学的编程语言真的是你想要的吗
  • 第四代编程语言_几代编程语言

    千次阅读 2020-07-20 09:46:05
    第四代编程语言 几代编程语言 (Generations of programming language) Programming languages have been developed over the year in a phased manner. Each phase of developed has made the programming language ...
  • 今天就不发项目了,来和大家分享一下对于刚接触编程培训学习的小白来说,常常会问到一个问题:如何学习一门新的编程语言,关于学习编程语言这个主题,可能每个人都有不同的看法和做法,下面给初次接触编程语言学习...
  • 三足鼎立截止2020年底,后端编程语言中,java依然是市场的王者,C/C++、python和go占据一部分江山,从2021年开始,未来十年,在后端编程语言中,各位觉得哪个编程语言会越来越...
  • 什么是 Python 编程语言

    千次阅读 多人点赞 2021-11-22 14:44:36
    作者主页:海拥 作者简介:CSDN全栈领域优质创作者、HDZ...Python 由 Guido van Rossum 设计,作为“ABC”编程语言的继承者,于 1991 年首次发布。它是一种高级通用语言,其设计理念是通过使用缩进来强调代码的可读性。
  • 用于Web开发的最佳编程语言

    千次阅读 2018-11-05 19:44:19
    用于Web开发的最佳编程语言

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,169,150
精华内容 467,660
关键字:

开发自己的编程语言