乘法编译原理
1. 编译是什么意思
问题一:编译和解释的区别是什么? 后来为了方便记忆,就将用0、1序列表示的机器指令都用符号助记,这些与机器指令一一对应的助记符就成了汇编指令,从而诞生了汇编语言。无论是机器指令还是汇编指令都是面向机器的,统称为低级语言。因为是针对特定机器的机器指令的助记符,所以汇编语言是无法独立于机器(特定的CPU体系结构)的。但汇编语言也是要经过翻译成机器指令才能执行的,所以也有将运行在一种机器上的汇编语言翻译成运行在另一种机器上的机器指令的方法,那就是交叉汇编技术。高级语言是从人类的逻辑思维角度出发的计算机语言,抽象程度大大提高,需要经过编译成特定机器上的目标代码才能执行,一条高级语言逗迟的语句往往需要若干条机器指令来完成。高级语言独立于机器的特性是靠编译器为不同机器生成不同的目标代码(或机器指令)来实现的。那具体的说,要将高级语言编译到什么程度呢,这又跟编译的技术有关了,既可以编译成直接可执行的目标代码,也可以编译成一种中间表示,然后拿到不同的机器和系统上去执行,这种情况通常又需要支撑环境,比如解释器或虚拟机的支持,java程序编译成bytecode,再由不同平台上的虚拟机执行就是很好的例子。所以,说高级语言不依赖于机器,是指在不同的机器或平台上高级语言的程序本身不变,而通过编译器编译得到的目标代码去适应不同的机器。从这个意义上来说,通过交叉汇编,一些汇消键编程序也可以获得不同机器之间的可移植性,但这种途径获得的移植性远远不如高级语言来的方便和实用性大。二、编译与解释编译是将源程序翻译成可执行的目标代码,翻译与执行是分开的;而解释是对源程序的翻译与执行一次性完成,不生成可存储的目标代码。这只是表象,二者背后的最大区别是:对解释执行而言,程序运行时的控制权在解释器而不在用户程序;对编译执行而言,运行时的控制权在用户程序。解释具有良好的动态特性和可移植性,比如在解释执行时可以动态改变变量的类型、对程序进行修改以及在程序中插入良好的调试诊断信息等,而将解释器移植到不同的系统上,则程序不用改动就可以在移植了解释器的系统上运行。同时解释器山桥李也有很大的缺点,比如执行效率低,占用空间大,因为不仅要给用户程序分配空间,解释器本身也占用了宝贵的系统资源。编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快;而解释器则是只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以运行速度是不如编译后的程序运行的快的.1、编辑:用编辑软件(EDIT.EXE或记事本)形成源程序(.ASM),如:LX.ASM; 2、汇编:用汇编程序(MASM.EXE)对源程序进行汇编,形成目标文件(.OBJ),格式如下:MASM LX.ASM; 3、连接:用连接程序(LINK.EXE)对目标程序进行连接,形成可执行文件(.EXE),格式如下:LINK LX.OBJ; 4、执行:如果结果在屏幕在显示,则直接执行可执行文件。 5、调试:用调试程序(DEBUG.EXE)对可执行文件进行调试,格式如下:DEBUG LX.EXE1. 在具体计算机上实现一种语言,首先要确定的是表示该语言语义解释的虚拟计算机,一个关键的问题是程序执行时的基本表示是实际计算机上的机器语言还是虚拟机的机器语言。这个问题决定了语言的实现。根据这个问题的回答,可以将程序设计语言划分为两大类:编译型语言和解释型语言。2. 由编译型语言编写的源程序需要经过编译、汇编和链接才能输出目标代码,然后机器执行目标代码,得出运行结果,目标代码由机器指令组成,一般不能独立运行,因为源程序中可能使用了某些......>>
问题二:函数的编译是什么意思??? 你说的这个问题,是把(不仅仅是数学上的函数式子)某个项目内容,进行编程。也就通过设计好了的运算程序,上百上千次进行与或非门运算。你想,电子,也就是通电断电额事。写成数字,就是010100001110000000111101111等等。
这需要专门的【编程员】大费脑筋的。有时候,需要好几年。
问题三:编译程序是什么意思?编译是什么意思? 把用高级程序设计语言书写的源程序,翻译成等价的计算机汇编语言或机器语言书写的目标程序的翻译程序。编译程序属于采用生成性实现途径实现的翻译程序。它以高级程序设计语言书写的源程序作为输入,而以汇编语言或机器语言表示的目标程序作为输出。编译出的目标程序通常还要经历运行阶段,以便在运行程序的支持下运行,加工初始数据,算出所需的计算结果。编译程序的实现算法较为复杂。这是因为它所翻译的语句与目标语言的指令不是一一对应关系,而是一多对应关系;同时也因为它要处理递归调用、动态存储分配、多种数据类型,以及语句间的紧密依赖关系。但是,由于高级程序设计语言书写的程序具有易读、易移植和表达能力强等特点,编译程序广泛地用于翻译规模较大、复杂性较高、且需要高效运行的高级语言书写的源程序。
问题四:编译时间是什么意思? 在ROM发布的时候,会提供这个ROM的一些版本。
编译时间能够告诉用户这个系统的发布时间。
有一些软件会提供类似的编译Revision。功能基本上相同。
问题五:编译错误是什么意思 编译错误,一般指语法上的错误
运行错误,一般指程序上的bug
问题六:什么是编译原理 编译:就是将程序语言进行翻译,生成可供用户直接执行的二进制代码,即可执行文件。
任务是个比较模糊的概念,指的是操作系统中正在进行的工作,既可以指进程,也可以指程序。
程序指的是可以连续执行,并能够完成一定任务的一条条指令的 *** 。
进程是程序在一个数据 *** 上运行的过程,它是传统操作系统进行资源分配和调度的一个独立单位。
线程是一个指令执行序列,是操作系统调度的最小单位。一个或多个线程构成进程,构成一个进激的线程之间共享资源。进程和线程之间的最大区别就是线程不能独立拥有资源,进程拥有自己的资源。
问题七:编译原理中V*是什么意思 V是一个符号 *** ,假设V指的是三个符号a, b, c的 *** ,记为 V = {a, b, c }
V* 读作“V的闭包”,它的数学定义是V自身的任意多次自身连接(乘法)运算的积,也是一个 *** 。
也就是说,用V中的任意符号进行意多次(包括0次)连接,得到的符号串,都是V*这个 *** 中的元素。
0次连接的结果是不含任何符号的空串,记为 ε
1次连接就是只有一个符号的符号串,比如,a,b, c
2次连接是两个符号构成的符号串,比如,aa, ab, ac, ba, bb, bc,等等
……
n次连接是一个长度为n、由a、b、c三个符号构成的符号串,比如abaacbbac……
因此,V*包含一切由a,b,c三个符号连接而成的、任意长度的符号串(以及空串ε)
问题八:编译和预编译有什么区别。 60分 预编译又称为预处理,是做些代码文本的替换工作。
处理#开头的指令,比如拷贝#include包含的文件代码,#define宏定义的替换,条件编译等
就是为编译做的预备工作的阶段
主要处理#开始的预编译指令
编译(pilation , pile) 1、利用编译程序从源语言编写的源程序产生目标程序的过程。 2、用编译程序产生目标程序的动作。 编译就是把高级语言变成计算机可以识别的2进制语言,计算机只认识1和0,编译程序把人们熟悉的语言换成2进制的。
问题九:C语言中程序编译的正确理解及其含义 预处理。首先程序会被送给预处理器了。预处理器执行以#开头的命令(通常称为指令)。预处理器有点类似于编辑器,它可以给程序添加内容,也可以对程序进行修改。
编译。 修改后的程序现在可以进入编译器了。编译器会把程序编译成机器指令(即目标代码)。然而,这样的程序是不可运行的。
链接。 在最后步骤中,链接器把编译器产生的目标代码和所需的其他附加代码整合在一起,这样才最终产生完全可执行的程序。这些附加代码包括程序中用到的库函数(如printf函数)
问题十:编译和解释的区别是什么? 后来为了方便记忆,就将用0、1序列表示的机器指令都用符号助记,这些与机器指令一一对应的助记符就成了汇编指令,从而诞生了汇编语言。无论是机器指令还是汇编指令都是面向机器的,统称为低级语言。因为是针对特定机器的机器指令的助记符,所以汇编语言是无法独立于机器(特定的CPU体系结构)的。但汇编语言也是要经过翻译成机器指令才能执行的,所以也有将运行在一种机器上的汇编语言翻译成运行在另一种机器上的机器指令的方法,那就是交叉汇编技术。高级语言是从人类的逻辑思维角度出发的计算机语言,抽象程度大大提高,需要经过编译成特定机器上的目标代码才能执行,一条高级语言的语句往往需要若干条机器指令来完成。高级语言独立于机器的特性是靠编译器为不同机器生成不同的目标代码(或机器指令)来实现的。那具体的说,要将高级语言编译到什么程度呢,这又跟编译的技术有关了,既可以编译成直接可执行的目标代码,也可以编译成一种中间表示,然后拿到不同的机器和系统上去执行,这种情况通常又需要支撑环境,比如解释器或虚拟机的支持,Java程序编译成bytecode,再由不同平台上的虚拟机执行就是很好的例子。所以,说高级语言不依赖于机器,是指在不同的机器或平台上高级语言的程序本身不变,而通过编译器编译得到的目标代码去适应不同的机器。从这个意义上来说,通过交叉汇编,一些汇编程序也可以获得不同机器之间的可移植性,但这种途径获得的移植性远远不如高级语言来的方便和实用性大。二、编译与解释编译是将源程序翻译成可执行的目标代码,翻译与执行是分开的;而解释是对源程序的翻译与执行一次性完成,不生成可存储的目标代码。这只是表象,二者背后的最大区别是:对解释执行而言,程序运行时的控制权在解释器而不在用户程序;对编译执行而言,运行时的控制权在用户程序。解释具有良好的动态特性和可移植性,比如在解释执行时可以动态改变变量的类型、对程序进行修改以及在程序中插入良好的调试诊断信息等,而将解释器移植到不同的系统上,则程序不用改动就可以在移植了解释器的系统上运行。同时解释器也有很大的缺点,比如执行效率低,占用空间大,因为不仅要给用户程序分配空间,解释器本身也占用了宝贵的系统资源。编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快;而解释器则是只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以运行速度是不如编译后的程序运行的快的.1、编辑:用编辑软件(EDIT.EXE或记事本)形成源程序(.ASM),如:LX.ASM; 2、汇编:用汇编程序(MASM.EXE)对源程序进行汇编,形成目标文件(.OBJ),格式如下:MASM LX.ASM; 3、连接:用连接程序(LINK.EXE)对目标程序进行连接,形成可执行文件(.EXE),格式如下:LINK LX.OBJ; 4、执行:如果结果在屏幕在显示,则直接执行可执行文件。 5、调试:用调试程序(DEBUG.EXE)对可执行文件进行调试,格式如下:DEBUG LX.EXE1. 在具体计算机上实现一种语言,首先要确定的是表示该语言语义解释的虚拟计算机,一个关键的问题是程序执行时的基本表示是实际计算机上的机器语言还是虚拟机的机器语言。这个问题决定了语言的实现。根据这个问题的回答,可以将程序设计语言划分为两大类:编译型语言和解释型语言。2. 由编译型语言编写的源程序需要经过编译、汇编和链接才能输出目标代码,然后机器执行目标代码,得出运行结果,目标代码由机器指令组成,一般不能独立运行,因为源程序中可能使用了某些......>>
2. 编译原理有有符号un-1.u=un吗
编译程序把源程序翻译为目标程序。根据源程序的语言种类,翻译程序可以分为汇编程序与编译程序。与之相对,解释程序是对源程序进行解释执行的程序。相应的可以将高级语言分为
编译型 C/C++, Swift, etc.
解释型 Python, javascript, etc.
混合型 Java, etc.
本文重点放在编译程序的设计上。典型的编译程序具有 7 77 个逻辑部分
对源程序扫描一次被称为一遍 (pass)。典型的一遍扫描编译程序有如下形式
通常将中间代码生成前的分析部分称为编译器的前端,其后的综合部分则被称为后端。这样就把一个编译程序分为了与源语言相关和与目标机有关的两个独立的部分,降低了程序的耦合。假设 llvm 编译器 支持 M MM 种源语言到 N NN 种目标语言的编译
传统的编译器如 gcc 可能需要开发 M × N M \times NM×N 个不同的子模块。而 llvm 使用统一的中间语言 llvm Intermediate Representation 只需要 M MM 个前端与 N NN 个后端,大大降低了开发成本。
文法
设非空有穷集合 Σ \SigmaΣ 为一字母表,则其上的符号串为 ∀ s ∈ Σ ∗ \forall s \in \Sigma^*∀s∈Σ
∗
,其中 ∗ *∗ 表示集合的闭包。特别的记 Σ 0 = ε \Sigma^0 = {\varepsilon}Σ
0
=ε 为空串组成的集合。规则通常写作
U : : = x or U → x , ∣ U ∣ = 1 , ∣ x ∣ ≥ 0 U ::= x\text{ or }U\rightarrow x,\quad |U| = 1, |x| \ge 0U::=x or U→x,∣U∣=1,∣x∣≥0
其中左部 U UU 是符号,右部 x xx 是有穷符号串。规则的集合 P PP 即可确定一个文法 G GG
<程序> ::= <常量说明><变量说明><函数说明>
<常量说明> ::= {const<常量定义>;}
<常量定义> ::= int<标识符>=<整数>{,<标识符>=<整数>}|char<标识符>=<字符>{,<标识符>=<字符>}
<变量说明> ::= {<类型标识符><变量定义>;}
<变量定义> ::= <标识符>[<下标>]{,<标识符>[<下标>]}
<下标> ::= '['<无符号整数>']' // <无符号整数>表示数组元素的个数,其值需大于0
<函数说明> ::= {(<类型标识符>|void)<函数定义>}void<主函数>
<函数定义> ::= <标识符>'('<参数表>')'<复合语句>
<参数表> ::= [<类型标识符><标识符>{,<类型标识符><标识符>}]
<主函数> ::= main'('')'<复合语句>
<复合语句> ::= '{'<常量说明><变量说明>{<语句>}'}'
<语句> ::= <条件语句>|'{'{<语句>}'}'|<函数调用语句>;|<赋值语句>;|<读语句>;|<写语句>;|<返回语句>;|;
<条件语句> ::= <if语句>|<while语句>|<do语句>|<for语句>
<if语句> ::= if'('<条件>')'<语句>[else<语句>]
<while语句> ::= while'('<条件>')'<语句>
<do语句> ::= do<语句>while'('<条件>')'
<for语句> ::= for'('<标识符>=<表达式>;<条件>;<标识符>=<标识符><加法运算符><无符号整数>')'<语句>
<条件> ::= <表达式>[<关系运算符><表达式>] // 表达式为0条件为假,否则为真
<函数调用语句> ::= <标识符>'('[<表达式>{,<表达式>}]')'
<赋值语句> ::= <标识符>['['<表达式>']']=<表达式>
<读语句> ::= scanf'('<标识符>{,<标识符>}')'
<写语句> ::= printf'('<字符串>[,<表达式>]')'|printf'('<表达式>')'
<返回语句> ::= return['('<表达式>')']
<表达式> ::= [<加法运算符>]<项>{<加法运算符><项>} // [+|-]只作用于第一个<项>
<项> ::= <因子>{<乘法运算符><因子>}
<因子> ::= <标识符>['['<表达式>']']|'('<表达式>')'|<整数>|<字符>|<函数调用语句>
<整数> ::= [<加法运算符>]<无符号整数>
<标识符> ::= <字母>{<字母>|<数字>}
<无符号整数> ::= <非零数字>{<数字>}|0
<数字> ::= 0|<非零数字>
<非零数字> ::= 1|...|9
<字符> ::= '<加法运算符>'|'<乘法运算符>'|'<字母>'|'<数字>'
<字符串> ::= "{十进制编码为32,33,35-126的ASCII字符}"
<类型标识符> ::= int|char
<加法运算符> ::= +|-
<乘法运算符> ::= *|/
<关系运算符> ::= <|<=|>|>=|!=|==
<字母> ::= _|a|...|z|A|...|Z
复制
上述文法使用扩充的 BNF 表示法进行描述
符号 定义 说明
∣ \vert∣ 或 作用域由括号限定
{ t } n m \{t\}^m_n{t}
n
m
将 t tt 重复连接 n ∼ m n \sim mn∼m 次 缺省时 m = ∞ , n = 0 m = \infin,\ n = 0m=∞, n=0
[ t ] [t][t] 符号串 t tt 可有可无 等价于 { t } 1 \{t\}^1{t}
1
( t ) (t)(t) 局部作用域 主要用于限定 ∣ \vert∣ 范围
相关概念有
概念 符号 定义 示例
识别符号 Z ZZ 文法中第一条规则的左部符号 <程序>
字汇表 V VV 文法中出现的全部符号 { <程序>, <常量说明>, …, 0, 1, … }
非终结符号集 V n V_nV
n
全部规则的左部组成的集合 { <程序>, <常量说明>, <变量说明>, … }
终结符号集 V t V_tV
t
V − V n V - V_nV−V
n
{ 0, 1, …, _, a, b, … }
设 U : : = u ∈ P U ::= u \in PU::=u∈P 则对于 ∀ x , y ∈ V ∗ \forall x, y \in V^*∀x,y∈V
∗
有直接推导 x U y ⇒ x u y xUy \Rightarrow xuyxUy⇒xuy 。如果 y ∈ V t ∗ y \in V_t^*y∈V
t
∗
则 x U y ⤃ x u y xUy\ ⤃\ xuyxUy ⤃ xuy 称为规范推导。直接推导序列 u 0 ⇒ u 1 ⇒ ⋯ ⇒ u n u_0 \Rightarrow u_1 \Rightarrow \cdots \Rightarrow u_nu
0
⇒u
1
⇒⋯⇒u
n
可简记为
{ u 0 ⇒ + u n n > 0 u 0 ⇒ ∗ u n n ≥ 0 \begin{cases} u_0 \mathop\Rightarrow\limits^+ u_n & n > 0\\ u_0 \mathop\Rightarrow\limits^* u_n & n \ge 0\\ \end{cases}{
u
0
⇒
+
u
n
u
0
⇒
∗
u
n
n
>
0
n
≥
0
进一步定义
句型 V ∗ ∋ x ⇐ ∗ Z V^* \ni x \mathop\Leftarrow\limits^* ZV
∗
∋x
⇐
∗
Z
句子 V t ∗ ∋ x ⇐ + Z V_t^* \ni x \mathop\Leftarrow\limits^+ ZV
t
∗
∋x
⇐
+
Z
语言 L ( G ) = { x ∣ x is sentence } L(G) = \{ x| x\text{ is sentence} \}L(G)={x∣x is sentence}
如果文法 G GG 和 G ′ G'G
′
有 L ( G ) = L ( G ′ ) L(G) = L(G')L(G)=L(G
′
) ,则称这两个文法等价。设 w = x u y w=xuyw=xuy 为一句型,称 u uu 为一个相对于 U ∈ V n U \in V_nU∈V
n
的
w ww 的短语 如果 Z ⇒ ∗ x U y ∧ U ⇒ + u Z \mathop\Rightarrow\limits^* xUy \land U \mathop\Rightarrow\limits^+ uZ
⇒
∗
xUy∧U
⇒
+
u
w ww 的简单短语 如果 u uu 是短语且 U ⇒ u U \mathop\Rightarrow\limits uU⇒u
句型的最左简单短语称为句柄。
二义性
文法 G GG 是二义性的,如果 ∃ x ∈ L ( G ) \exist x \in L(G)∃x∈L(G) 使下列条件之一成立
x xx 可以对应两颗不同的语法树
x xx 有两个不同的规范推导
3. 编译原理中V*是什么意思
V是一个符号集合,假设V指的是三个符号a,
b,
c的集合,记为
V
=
{a,
b,
c
}
V*
读作“V的闭包”,它的数学定义是V自身的任意多次自身连接(乘法)运算的积,也是一个集合。
也就是说,用V中的任意符号进行任意多次(包括0次)连接,得到的符号串,都是V*这个集合中的元素。
0次连接的结果是不含任何符号的空串,记为
ε
1次连接就是只有一个符号的符号串,比如,a,b,
c
2次连接是两个符号构成的符号串,比如,aa,
ab,
ac,
ba,
bb,
bc,等等
……
n次连接是一个长度为n、由a、b、c三个符号构成的符号串,比如abaacbbac……
因此,V*包含一切由a,b,c三个符号连接而成的、任意长度的符号串(以及空串ε)
4. 在编译原理中: 文法S——>SS+|SS*|a能产生什么语言,并验证! 求高人指导!
为了使问题简化,我们考虑文法S->ss+|a,考虑s->ss*时,只要把+换成*即可。
0层递归是,s->a,文法的语言是{a}。是后缀表达式。
1层以内递归时,文法语言是{a,aa+}。是后缀表达式。
2层以内递归时,文法语言是{a,aa+}.{a,aa+}.{+}。其中.表示连接,是后缀表达式。
依此类推,多少层的递归都是后缀表达式。
把表达式的+换成*后依然为后缀表达式。
下面证明文法产生的语言是所有的以a为变量,以+和*为运算符的后缀表达式。
因为每个表达式都对应一个常规的表达式(如1*2+3就是常规表达式),下面只需证明语言能产生的后缀表达式对应所有的常规表达式。当常规表达式只有一个运算符,对应aa+或aa*。当常规表达式有两个运算符,可写成(表达式1).{+|*}.(表达式2),因为表达式1和2都只含一个运算符,所以可以用语言表示,上述常规表达式可用后缀表达式(表达式1).(表达式2).{+l*}表示。所以不管常规表达式有多少个运算符,都可以由语言的后缀表达式对应。
5. C语言x+=什么意思
一句话描述:
a+=1-->等价于 a=a+1; 这是因为编译器再对代码进行语义分析的时候会把 a=a+1 翻译成 a+=1.我们写代码这么写的话就可以适当提高效率。 有关为什么会翻译成这个。楼主可参考《编译原理》相关知识,重点是看看 前缀、中缀、后缀表达式相关知识点。