和记娱乐


网站导航

联系我们

和记娱乐

联系人: 

电 话:021-64057486

公司网址:http://www.happy123456789.com

   址:成都市松江区漕河泾松江新兴产业园区研展路丰产支路55号B座803室

邮编:201165


通信科技

您的当前位置: 和记娱乐主页 > 通信科技 >

程序编译原理简介

发布日期:2019-08-04 08:16 来源:和记h88 发布人:和记娱乐 点击:

  编译原理,就是经过对普通编译原理分析,形成了以词典为核心,结合词的数据结构完成编译过程的自成体系技术理论。通过分析词法生成词典(词典发生器),分析语法生成局部代码,并建立数据指针(翻译机),组装局部代码生成目标机器语言流并建立程序调用过的对象、指针等数据流空间,最终完成可执行程序(装配器)三个模糊过程(因为这些过程都离不开词典,编译中间会发生相互影响),把高级计算机语言加工成为计算机机器语言代码流,这就是编译过程。

  编译器是将汇编或高级计算机语言翻译为二进制机器语言代码的计算机程序。编译器将源程序编写的程序作为输入,翻译产生目言机器代码的等价程序。通常地,源程序为高级语言,像C或C++、汉语语言程序等,而目标则是机器语言的目标代码(也称作机器代码),也就是可以在计算机硬件中运行的机器代码软件程序。这一过程可以表示为:

  编译器内部包括了许多步骤或称为阶段源代码,它们执行不同的逻辑操作。将这些阶段设想为编译器中一个个单独的片断是很有用的, 尽管在应用中它们是经常组合在一起的,但它们扫描程序确实是作为单独的代码操作来编写的。

  扫描程序(scanner):在这个阶段编译器实际阅读源程序(通常以分析程序字符流的形式表示)。扫描程序执行词法分析注释树符号表:它将字符序列收集到称作记号错误处的有意义单元中,记号同自然语言,如英源代码理器语中的字词相似。因此可以认为扫描程序执行与优化程序拼写相似的任务。中间代码例如在下面的代码行(它可以是C程序的一部分)中:代码生成器 a [index] = 4 + 2 这个代码包括了12个非空字符,但只有 8个目标代码记号:a 标识符目标代码优化程序 [ 左括号index 标识符 ] 右括号 = 赋值目标代码 4 数字编译器的阶段 + 加号 2 数字 每一个记号均由一个或多个字符组成,在进一步处理之前它已被收集在一个单元中。扫描程序还可完成与识别记号一起执行的其他操作。例如,它可将标识符输入到符号表中, 将文字输入到文字表中(文字包括诸如3 . 1415926535的数字常量,以及诸如“Hello,world ! ”的引用字符串)。

  语法分析(parser ):语法分析程序从扫描程序中获取记号形式的源代码,并完成定义程序结构的语法分析,这与自然语言中句子的语法分析类似。语法分析定义了程序的结构元素及其关系。通常将语法分析的结果表示为分析树或语法树。例如,还是那行C代码,它表示一个称为表达式的结构元素,该表达式是一个由左边为下标表达式、右边为整型表达式的赋值表达式组成。这个结构可按下面的形式表示为一个分析树:请注意,分析树的内部节点均由其表示的结构名标示出,而分析树的叶子则表示输入中的记号序列(结构名以不同字体表示以示与记号的区别)。分析树对于显示程序的语法或程序元素很有帮助,但是对于表示该结构却显得力不从心了。分析程序更趋向于生成语法树,语法树是分析树中所含信息的浓缩(有时因为语法树表示从分析树中的进一步抽取,所以也被称为抽象的语法树。下面是一个C赋值语句的抽象语法树的例子:请注意,在语法树中,许多节点(包括记号节点在内)已经消失。例如,如果知道表达式是一个下标运算,则不再需要用括号“[”和“]”来表示该操作是在原始输入中。

  语义分析(semantic analyzer ):程序的语义就是它的“意思”,它与语法或结构不同。程序的语义确定程序的运行,但是大多数的程序设计语言都具有在执行之前被确定而不易由语法表示和由分析程序分析的特征。这些特征被称作静态语义,而语义分析程序的任务就是分析这样的语义(程序的“动态”语义具有只有在程序执行时才能确定的特性,由于编译器不能执行程序,所以它不能由编译器来确定)。一般的程序设计语言的典型静态语义包括声明和类型检查。由语义分析程序计算的额外信息(诸如数据类型)被称为属性,它们通常是作为注释或“装 饰”增加到树中(还可将属性添加到符号表中)。在正运行的C表达式 a [index] = 4 + 2 中,该行分析之前收集的典型类型信息可能是:a是一个整型值的数组,它带有来自整型子范围的下标;index则是一个整型变量。接着,语义分析程序将用所有的子表达式类型来标注语法树,并检查赋值是否使这些类型有意义了,如若没有,则声明一个类型匹配错误。在上例中, 所有的类型均有意义,有关语法树的语义分析结果可用以下注释了的树来表示。

  优化程序(source code optimizer):编译器通常包括许多代码改进或优化步骤。绝大多数最早的优化步骤是在语义分析之后完 成的,而此时代码改进可能只依赖于源代码。这种可能性是通过将这一操作提供为编译过程中的单独阶段指出的。每个编译器不论在已完成的优化种类方面还是在优化阶段的定位中都有很大的差异。在上例中,我们包括了一个源代码层次的优化机会,也就是:表达式4 + 2可由编译器计算先得到结果6(这种优化称为常量合并)。当然,还会有更复杂的情况。还是在上例中,通过将根节点右面的子树合并为它的常量值,这个优化就可以直接在(注释)语法树上完成:尽管许多优化可以直接在树上完成,但是在很多情况下,优化接近于汇编代码线性化形式的树更为简便。这样节点的变形有许多,但是三元式代码(之所以这样称呼是因为它在存储器中包含了3个(或3个以上)的地址)却是标准选择。另一个常见的选 择是P -代码,它常用于Pascal编译器中。在前面的例子中,原先的C表达式的三元式代码应是:t = 4 + 2 a [ index] = t (请注意,这里利用了一个额外的临时变量t 存放加法的中间值)。这样,优化程序就将这个代码改进为两步。首先计算加法的结果:t = 6 a [index] = t 接着,将t替换为该值以得到三元语句 a [index] = 6 ,指出源代码优化程序可能通过将其输出称为中间代码来使用三元式代码。中间代码一直是指一种位于源代码和目标代码(例如三元式代码或类似的线性表示)之间的代码表示形式。但是,我们可以更概括地认为它是编译器使用的源代码的任何一个内部表示。此时,也可将语法树称作中间代码,源代码优化程序则确实能继续在其输出中使用这个表示。有时,这个中间代码也称作中间表示。

  代码生成(code generator):代码生成器得到中间代码,并生成目标机器的代码。正是在编译的这个阶段中,目标机器的特性成为了主要因素。当它存在于目标机器时,使用指令不仅是必须的而且数据的形式表示也起着重要的作用。例如,整型数据类型的变量和浮点数据类型的变量在存储器中所占的字节数或字数也很重要。在的示例中,现在必须决定怎样存储整型数来为数组索引生成代码。例如,下面是所给表达式的一个可能的样本代码序列(在假设的汇编语言中):

  在以上代码中,为编址模式使用了一个类似C的协定(&a是a的地址,即数组的首址),*R1则意味着间接寄存器地址(因此最后一条指令将值6存放在R1包含的地址中)。这个代码还假设机器执行字节编址,并且整型数占据存储器的两个字节(所以在第2条指令中用2作为乘数)。

  目标代码(target code optimizer ):在这个阶段中,编译器尝试着改进由代码生成器生成的目标代码。这种改进包括选择编址模式以提高性能、将速度慢的指令更换成速度快的,以及删除多余的操作。在给出的样本目标代码中,还可以做许多更改:在第2条指令中,利用移位指令替代乘法(通常地,乘法很费时间),还可以使用更有效的编址模式(例如用索引地址来执行数组存储)。使用了这两种优化后,目标代码就变成:

      和记娱乐,和记h88,h88平台官网