当前位置: 首页 > news >正文

程序解释与编译

▶1.程序的解释执行方式

程序语言强写的计策机指令序列称为“源程序”,计算机并不能直接执行用高级语言编写的源程序,源程序必须通过“翻译程序”翻译成机器指令的形式,计算机才能项别和执行。源程序的翻译有两种方式:解释执行和编译执行。不同的程序语言,有不同的翻译程序,这些翻译程序称为程序解释器(也称为虚拟机)或程序编译器(简称为编译器)。

1)程序的解释执行过程

解释程序的工作过程如下:首先,由语言解释器(如Python)进行初始化准备工作。然后语言解释器从源程序中读取一个语句(指令),并对指令进行语法检查,如果程序语法有错,则输出错误信息;否则,将源程序语句翻译成机器执行指令,并执行相应的机器操作。返回后检查解释工作是否完成,如果未完成,语言解释器继续解释下一语句,直至整个程序执行完成。否则,进行必要的善后处理工作。

语言解释器一般包含在开发软件或操作系统内,如IE浏览器带有.Net脚本语言解释功能;也有些语言解释器是独立的,如Python解释器就包含在Python软件包中。

2)解释程序的特点

解释程序的优点是实现简单,交互性较好。动态程序语言(如Python、PHP、JavaScript、R、MATLIB等)一般采用解释执行方式。
解释程序有以下缺点:一是程序运行效率低,如源程序中出现循环语句时,解释程序也要重复地解释并执行这一组语句;二是程序的独立性不强,不能在操作系统下直接运行,因为操作系统不一定提供这个语言的解释器;三是程序代码保密性不强,例如,要发布Python开发项目,实际上就是发布Python源代码。

▶2.程序的编译执行方式

程序员编写好源程序后,由编译器将源程序翻译成计算机可执行的机器代码。程序编译完成后就不再需要再次编译了,生成的机器代码可以反复执行。

源程序编译是一个复杂的过程,这一过程分为以下步骤:源程序→预处理→词法分析→语法分析→语义分析→生成中间代码→代码优化→生成目标程序→程序连接→生成可执行程序。事实上,某些步骤可能组合在一起进行。

在编译过程中,源程序的各种信息被保存在不同表格里,编译工作的各个阶段都涉及构造、查找或更新有关表格。如果编译过程中发现源程序有错误,编译器会报告错误的性质和发生错误的代码行,这些工作称为出错处理。

1)预处理

一个源程序有时可能分成几个模块存放在不同的文件里,预处理的工作之一是将这些源程序汇集到一起;其次,为了加快编译速度,编译器往往需要提前对一些头文件及程序代码进行预处理,以便在源程序正式编译时节省系统资源开销。例如,C语言的预处理包括文件合并、宏定义展开、文件包含、条件编译等内容。

2)词法分析

编译器的功能是解释程序文本的语义,不幸的是计算机很难理解文本,文本文件对计算机来说就是字节序列,为了理解文本的含义,就需要借助词法分析程序。词法分析是将源程序的字符序列转换为标记(Token)序列的过程。词法分析的过程是编译器一个字符一个字符地读取源程序,然后对源程序字符流进行扫描和分解,从而识别出一个个独立的单词或符号(分词)。在词法分析过程中,编译器还会对标记进行分类。
单词是程序语言的基本语法单位,一般有四类单词:一是语言定义的关键字或保留字(如if、for等);二是标识符(如x、i、list等);三是常量(如0、3.14159等);四是运算符和分界符(如十、一、*、/、=、;等)。如何进行“分词”是词法分析的重要工作。

3)语法分析

语法分析过程是把词法分析产生的单词,根据程序语言的语法规则,生成抽象语法树(AST),语法树是程序语句的树形结构表示,编译器将利用语法树进行语法规则分析。语法树的每一个节点都代表着程序代码中的一个语法结构,例如包、类型、标识符、表达式、运算符、返回值等。后续的工作是对抽象语法树进行分析。

符号表是由一组符号地址和符号信息构成的表格。符号表中登记的信息在编译的不同阶段都要用到。在语法分析中,符号表登记的内容将用于语法分析检查;在语义分析中,符号表所登记的内容将用于语义检查和产生中间代码;在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的依据。

4)语义分析

语义分析是对源程序的上下文进行检查,审查有无语义错误。语义分析主要任务有静态语义审查、上下文相关性审查、类型匹配审查、数据类型转换、表达式常量折叠等。
源程序中有些语句按照语法规则判断是正确的,但是它不符合语义规则。例如,使用了没有声明的变量;或者对一个过程名赋值;或者调用函数时参数类型不合适;或者参加运算的两个变量类型不匹配等。当源程序不符合语言规范时,编译器会报告出错信息。
表达式常量折叠就是对常量表达式计算求值,并用求得的值来替换表达式,放入常量表。例如,s=1+2折叠之后为常量3,这也是一种编译优化。

5)生成中间代码

语义分析正确后,编译器会生成相应的中间代码。中间代码是一种介于源程序和目标代码之间的中间语言形式,它的目的是:便于后面做优化处理,便于程序的移植。中间代码常见形式有四元式、三元式、逆波兰表达式等。由中间代码很容易生成目标代码。

6)代码优化

代码优化的目的是为了得到高质量的目标程序。

7)生成目标程序

生成目标程序不仅与编译技术有关,而且与机器硬件结构关系密切。例如,充分利用机器的硬件资源,减少对内存的访问次数;根据机器硬件特点(如多核CPU)调整目标代码,提高执行效率。生成目标程序的过程实际上是把中间代码翻译成汇编指令的过程。

8)链接程序

目标程序还不能直接执行,因为程序中可能还有许多没有解决的问题。例如,源程序可能调用了某个库函数等。链接程序的主要工作就是将目标文件和函数库彼此连接,生成一个能够让操作系统执行的机器代码文件(软件)。

9)生成可执行程序(机器代码)

机器代码生成是编译过程的最后阶段。机器代码生成不仅仅需要将前面各个步骤所生成的信息(语法树、符号表、目标程序等)转化成机器代码写入到磁盘中,编译器还会进行少量的代码添加和转换工作。经过上述过程后,源程序最终转换成可执行文件了。

▶3.程序编译失败的主要原因

完美的程序不会一次就写成功,都需要经过反复修改、调试和编译。Google和香港科技大学的研究人员分析了Google工程师的2600万次编译,分析了编译失败的常见原因:一是编译失败率与编译次数、开发者经验无关;二是大约65%的Java编译错误与依赖有关,如编译器无法找到一个符号(占编译错误的43%),或者是包文件不存在;在C++编译中,53%的编译错误是使用了未声明的标识符和不存在的类变量。

相关文章:

程序解释与编译

▶1.程序的解释执行方式 程序语言强写的计策机指令序列称为“源程序”,计算机并不能直接执行用高级语言编写的源程序,源程序必须通过“翻译程序”翻译成机器指令的形式,计算机才能项别和执行。源程序的翻译有两种方式:解释执行和编译执行。不…...

聊聊 Jetpack Compose 的 “状态订阅自动刷新” -- mutableStateListOf

Jekpack Compose “状态订阅&自动刷新” 系列: 【 聊聊 Jetpack Compose 的 “状态订阅&自动刷新” - - MutableState/mutableStateOf 】 【 聊聊 Jetpack Compose 的 “状态订阅&自动刷新” - - remember 和重组作用域 】 【 聊聊 Jetpack Compose 的 …...

Dockerfile详解#如何编写自己的Dockerfile

文章目录 前言编写规则指令详解FROM:基础镜像LABEL:镜像描述信息MAINTAINER:添加作者信息COPY:从宿主机复制文件到镜像中ADD:从宿主机复制文件到镜像中WORKDIR:设置工作目录 前言 Dockerfile是编写docker镜…...

Elasticsearch桶聚合和管道聚合

1. 根据名称统计数量 GET order/_search {"_source": false,"aggs": {"aggs_name": { // 自定义查询结果名称"terms": { // 使用的函数"field": "name.keyword"}}} }查询结果例子: "aggregat…...

联想范建平:联想混合AI架构具备两大明显优势

12月7日,首届AI PC创新论坛在北京联想集团总部举办。联想集团副总裁、联想研究院人工智能实验室负责人范建平表示,为提供真正可信、个性化的AI专属服务,联想提出了混合智能(Hybrid AI)概念,并已经显现出更强…...

探索Spring事件监听机制的奇妙世界

文章目录 什么是Spring事件监听机制主要组件内置的事件监听类自定义事件监听类总结 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 什么是Spring事件监听机制 Spring事件监听机制是Spr…...

什么是散列函数

散列函数是一种公开的数学函数。散列函数运算的输入信息也可叫作报文。散列函数运算后所得到的结果叫作散列码或者叫作消息摘要。散列函数具有如下一些特点: (1)不同内容的报文具有不同的散列码,而一旦原始报文有任何改变&#xf…...

tomcat反序列化

漏洞介绍: 漏洞名称: Apache Tomcat反序列化漏洞影响范围: Apache Tomcat服务器中使用了自带session同步功能的配置,且没有使用Encrypt Interceptor加密拦截器的情况下。漏洞描述: Apache Tomcat是一个基于Java的Web应用软件容器,用于运行servlet和JSP Web应用。当Tomc…...

flask 请求勾子实现 request_auth认证

from flask import g,request from comment.utils.tokens_pyjwt import verify_tokensdef jwt_request_auth():从请求(request)中获取token,并且验证token,验证成功之后把用户id保存到全局变量g中g.user_idNone #定义变量#前端代码是是把token携带请求头…...

【STM32入门】3.OLED屏幕

1.OLED引脚 OLED屏幕的接线按图所示,本例中用的是4管脚OLED屏幕 2.驱动程序 配套的驱动程序是“OLED.c",主要由以下函数构成:1、初始化;2、清屏;3、显示字符;4、显示字符串;5、显示数字…...

python圣诞树代码编程

以下是一个简单的Python圣诞树代码: def draw_tree(height): for i in range(height): print( * (height - i - 1) * * (2 * i 1)) print( * (height - 1) |)draw_tree(10) 这个函数会绘制一个等腰三角形,其中每一行的星号数量从1开…...

js数组删除某个元素

...

hbuilder + uniapp +vue3 开发微信云小程序

1、创建项目: 2、创建项目完成的默认目录结构: 3、在根目录新建一个文件夹cloudFns(文件名字随便),存放云函数源码: 4、修改manifest.json文件:添加 小程序 appid和cloudfunctionRoot&#xff0…...

服务器配置免密SSH

在当今互联网时代,远程工作和网络安全已成为信息技术领域的热点话题。无论是管理远程服务器、维护网络设备还是简单地从家中连接到办公室,安全始终是首要考虑的因素。这就是为什么 SSH(Secure Shell)成为了网络专业人士的首选工具…...

2023 开发人员生态系统现状信息图:《开发者生态系统现状报告》

本心、输入输出、结果 文章目录 2023 开发人员生态系统现状信息图:《开发者生态系统现状报告》前言目录细节软件开发者薪资趋势过去 3 年科技行业的性别分布 生成式 AI 服务的复杂格局开发者社区的心理健康花有重开日,人无再少年实践是检验真理的唯一标准…...

TCP协议实现一对一聊天

服务端代码: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; /** * 发送消息线程 */ class…...

python使用conda管理多个环境

一、Anaconda简介 Anaconda 是专门为了方便使用 Python 进行数据科学研究而建立的一组软件包,涵盖了数据科学领域常见的 Python 库,并且自带了专门用来解决软件环境依赖问题的 conda 包管理系统。主要是提供了包管理与环境管理的功能,可以很方…...

实现个微机器人的二次开发

请求URL: http://域名地址/scanJoinRoom 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选类型说明wId是string登录实例标识url是string…...

Android 记录一些Framework开发的命令

源码编译流程 1. "source build/envsetup.sh" (source可以用 . 代替,即". build/envsetup.sh") 2. "lunch",并选择要编译的项目或者"choosecombo" 3. "make idegen -j4" (这里的 -j4 表示用4线程来…...

Ant Design Vue 年选择器

文章目录 参考文档效果展示实现过程 参考文档 提示:这里可以添加本文要记录的大概内容: DatePicker 日期选择框 大佬:搬砖小匠(Ant Design vue 只选择年) 提示:以下是本篇文章正文内容,下面案…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...