编译原理_2

  • 编译器在分析阶段把一个源程序划分成各个组成部分,并生成源程序的内部表现形式。这种内部表现称为中间代码。然后,编译器在合成阶段将这个中间代码翻译成目标程序。
  • 分析阶段的工作是围绕这编译语言的“语法展开的”。一个程序设计语言的语法描述了该语言程序的正确形式。而该语言的语义定义了程序的含义。即每个程序运行的时候应该做什么事。比如:
    • 广泛使用的表示方法来描述语法。上下文无关的文法或bnf范式。
  • 使用现有语义表示方法来描述一个语言的语义的难度远远大于描述语言语法的难度。
  • 上下文无关文法不仅可以描述一个语言的语法,还可以指导程序的翻译过程。一种面向文法的编译技术,即语法制导翻译技术。后缀表达式是一种将运算符置于运算分量之后的表示方法。
    • 9-5+2后缀形式是95-2+

      一个编译器前端模型

  • 词法分析器可以处理由多个字符组成的构造。比如标识符,标识符由多个字符组成。但是在语法分析阶段被当做一个单元进行处理。这样的单元被称作词法单元。比如:
    • count+1,标识符count被当做一个单元。

      两种中间代码形式
  • 一种是抽象语法树:表示了源程序层次化的语法结构。
  • 另一种常见的中间表示形式。是一组“三地址”指令序列。
    • x=y op z

      • op是一个二目运算符,y和z是运算分量的地址,x是存放结果的地址。三地址指令最多一般只执行一个运算,通常是计算、比较或者分支跳转运算。

        上下文无关文法
  • 文法自然的描述了大多数程序设计语言构造的层次化语法结构,例如java中的if-else
  • 即一个if-else语句由关键字if、左括号、右括号、一个语句、关键字else和另一个语句连接而成。用expr表示表达式,变量stmt表示语句,这个构造规则表示为
    • stmt->if(expr)stmt else stmt
  • 关键字if和括号这样的词法元素称为终结符号。像exor和stmt这样的变量表示终结符号的序列,他们被称为非终结符号
    文法定义
  • 一个上下文无关文法,由四个元素组成:
    • 一个终结符号集合,有时也称为词法单元。终结符号是该文法定义的语言的基本符号的集合
    • 一个非终结符号的集合,有时也被称为语法变量。每个非终结符号表示一个终结符号串的集合。
    • 一个产生式集合,其中每个产生式包括一个称为产生式头或左部的非终结符号。
    • 指定一个非终结符号为开始符号
  • 词法分析器读入源程序中的字符序列,将他们组织为具有词法含义的词素。生成并输出代表这些词素的词法单元序列。词法单元有两部分组成:名字和属性值。词法单元的名字是语法分析器进行语法分析时使用的抽象符号。这些词法单元名称为终结符号。因为他们在描述程序设计语言的文法中是以终结符号的形式出现的。
  • 如果词法单元具有属性?
    • 这个值就是一个指向符号表的指针,符号表包括了该词法单元的附加信息。这些附加信息不是文法的组成部分,所以通常将词法单元和终结符号当同义词。
  • 如果某个非终结符号是某个产生式的头部,我们就说该产生式时该非终结符号的产生式。一个终结符号串是由零个或者多个终结符号组成的序列。零个终结符号组成的串称为空串。
    推导
  • 根据文法推导符号串时,首先从开始符号出发。不断将某个非终结符号替换为该非终结符号的某个产生式的体。可以冲开始符号推导得到的所有终结符号串的集合称为该文法定义的语言。
    语法分析的任务
  • 语法分析的任务:接收一个终结符号串作为输入,找出从文法的开始符号推导出这个串的方法。如果不能从文法的开始推导得到该终结符号串,则报告该终结符号串中包含的语法错误。语法分析是所有编译过程中最基本的问题之一。
  • 一般情况下,一个源程序中会包含由多个字符串组成的词素。这些词素由词法分析器组成词法单元,而词法单元的第一个分量就是被语法分析器处理的终结符号。
  • 给定一个上下文无关文法,该文法的一颗语法分析树,是具有以下性质的树:
    • 根节点的标号为文法的开始符号
    • 每个叶子节点的标号为一个终结符号或E
    • 每个内部节点的标号为一个非终结符号
    • 如果非终结符号A是某个内部节点的标号,并且他的子节点标号从左至右分别为x1、x2.那么必然存在产生式A->X1X2,其中x1、x2既可以是终结符号,也可以是非终结符号。作为一个特殊情况,如果A->E是一个产生式,那么一个标号为A的节点可以只有一个标号为e的子节点。
      二义性
  • 一个文法可能有多颗语法分析树能够生成同一个给定的终结符号串。这样的文法统称有二义性。需要为编译应用涉及出没有二义性的文法,或者使用二义性文法使用附加的规则来消除二义性。
  • 非终结符号stmts产生一个可能为空的语句列表。stmts第二个产生式生成一个空列表e。第一个产生式生成的是一个可能为空的列表再跟上一个语句。分号的放置方式很微妙,他们出现在所有不以stmt结尾的产生式的末尾。这种方法可以避免在if或者while这样的语句后面出现多余的分号。因为if和while语句的最后是一个嵌套的子语句。当嵌套子语句是一个赋值语句或do-while语句时,分号将作为这个子语句的一部分被生成。
    语法制导翻译
  • 语法制导翻译是通过向一个文法,产生式附加一些规则或程序片段而得到的。比如考虑由如下产生式生成的表达式expr:
    • expr->expr1->t=erm
  • 属性:属性表示与某个程序构造相关的任意的量。属性可以是多重多样的,比如表达式的数据类型、生成的代码中指令数目或为某个构造生成代码中第一条指令的位置都是属性。用文法符号(终结符号或非终结符号)表示程序的构造,所有将属性的概念从程序构造扩展到表达这些构造的文法符号上。
  • 翻译方案:翻译方案是一种将程序片段附加到一个文法的各个产生式上的表示法。当在语法分析过程中使用一个产生式,响应的程序片段就会执行。这些程序片段的执行效果按照语法分析过程中顺序组合起来,得到的结果就是这次分析/综合过程处理源程序得到的翻译结果。
  • 综合属性
    • 将量和程序构造关联起来(比如吧数值类型和表达式相关联)可以基于文法来表示。将属性和文法的非终结符号相关联。文法的各个产生式附加上语义规则,对于语法分析书中的一个节点,如果他和她的子节点之间关系符合某个产生式,那么该产生式对应的规则就描述了如何计算这个节点上的属性。

      简单语法制导定义
    • 要得到代码产生式头部的非终结符号的翻译结果的字符串,只需要将产生式体中各非终结符号的翻译结果按照他们在非终结符号中的出现顺序,并在其中穿插一些附加的串即可。具有这个性质的语法制导定义称为简单语法制导定义。
  • 语法制导翻译方案是一种在文法产生式中附加一些程序片段来描述翻译结果的表示方法。语法制导翻译方案定义相似,只是显式指定了语义规则的计算顺序。
  • 画出一个翻译方案的语法分析树,为每个语义动作构造一个额外的子节点,并使用虚线将他和该产生式头部对应的节点相连。表示上述产生式和语义动作的部分语法分析树。对应的语义动作没有子节点,因此在第一次访问该节点时就会执行这个动作。

    语法分析
  • 语法分析决定如何使用一个文法生成一个终结符号串的过程。尽管在时间中编译器并没有真的构造出这颗树,然而,原则上语法分析器必须能够构造出语法分析树,否则将无法保证翻译的正确性。

    递归下降

  • 这种语法分析方法,这种方法可以实现语法分析和语法制导翻译器。另一种是使用软件工具根据翻译方案生成一个翻译器。比如:Yacc
  • 对于任意上下文无关文法,都可以构造一个时间复杂度为0(n3)的语法分析器,他是最多使用0(n3)的时间就可以完成一个长度为n的符号串的语法分析。但是3次方的时间代码一般来说过于昂贵。对于实际程序设计语言而言,通常能够设计出一个可以被高效分析的文法。线性时间复杂度的算法足够分析实践中出现的各种程序设计语言。
  • 程序设计语言的语法分析器几乎总是一次性从左到右扫描,每次向前看一个终结符号,并在扫描时构造出分析树的各个部分。
  • 大多数语法分析都可以归入以下两类:自顶向下方法和自底向上。指的是语法分析树节点的构造顺序,在自顶向下语法分析器中,构造过程从根节点开始,逐步向叶子节点方向进行,而在自底向上的语法分析器中,构造过程从叶子结点开始,逐步构造出根节点。自顶向下语法分析器之所以受欢迎,是因为这种方法可以很容易的构造出高效的语法分析器。自底向上分析方法可以处理更多文法和翻译方案。
  • 对于非终结符号和向前看符号;,我们使用optexpr的产生式,因为;和optexpr仅有的另一个产生式不匹配,那个产生式的体是终结符号expr
    预测分析法
  • 递归下降分析法是一种自顶向下的语法分析方法,他使用一组递归过程来处理输入。文法的每个非终结符号都有一个相关联的过程,这里我们考虑递归下降分析法的一种简单形式,称为预测分析法。各个非终结符号对应的过程中的控制流可以由向前看符号无二意的确定,在分析输入串时出现的过程调用序列隐式的定义了该输入串的一颗语法分析树,如果需要还可以通过这些过程调用来构建一个显示的语法分析树。
  • 预测分析器在没有其他产生式可用的时候,将∈产生式作为默认选择使用。
  • 预测分析器程序由各个非终结符对应的过程调用。对应于非终结符a的过程完成以下两项任务。
    • 检查向前看符号,决定使用a的那个产生式。如果一个产生式的体为a(这里a不是空串∈)且向前看符号在FIRST(a)中,那么就选择这个产生式。对于任何向前看符号,如果两个非空产生式体之间存在冲突,就不能对这种文法使用预测语法分析。如果有a有∈产生式,只有当向前看符号不在A的其他产生式体的FIRST集合中时,才会使用A的∈产生式
    • 这个过程模拟被选中产生式的体,也就是说,从左边开始逐个执行斥期间产生式体中的符号。“执行”一个非终结符号的放法是调用该非终结符号对应的过程,一个与向前看符号匹配的终结符号“执行”放法是读入下一个输入符号。如果在某个点上,产生式体中的终结符号和向前看符号不匹配,那么语法分析器就会报告一个语法错误。
      左递归
  • 递归下降语法分析器有可能进入无线循环,当出现如下所示的“左递归产生式”,分析器就会进入无限循环。
    • expr->expr+term
  • 非终结符号R和他的产生式R->aR是右递归的。因为这个产生式的右部,因为这个产生式的右部最后一个符号就是R本身。右递归的产生式会使树向右下方向生长。因为树是向右下生长的,对包含了左结合运算符的表达式就变得比较困难。
    左递归消除
  • 左递归消除工作必须小心的进行,以确保消除后的结果爆出语义动作的顺序。+和-都处于产生式的中间,9-5+2会被错误的处理为952+-,即(9-5)+2的表达式
    词法分析
  • 一个词法分析从输入中读取字符,并将他们组成“词法单元对象”,除了用于语法分析的终结符号外,一个词法单元对象还包含一些附加信息。这些信息以属性值得形式出现。

原文地址:https://www.cnblogs.com/binarysystemloophole/p/10628299.html

时间: 2024-11-01 14:58:34

编译原理_2的相关文章

编译原理123

1.编译原理就是什么? 个人理解,编译就是像翻译一样,将一种语言翻译成另一种语言,编译就是将高级语言或汇编语言翻译成电脑能识别的二进制机器语言,编译原理就是讲解这 个编译的过程.内容包括语言和文法.词法分析.语法分析.语法制导翻译.中间代码生成.存储管理.代码优化和目标代码生成. 编译原理是计算机专业设置的一门重要的专业课程.虽然只有少数人从事编译方面的工作,但是这门课在理论.技术.方法上都对学生提供了系统而有效的训练,有 利于提高软件人员的素质和能力. 2.学习编译原理有什么好处? 学习编译原

编译原理的理解

编译原理内容包括语言和文法.词法分析.语法分析.语法制导翻译.中间代码生成.存储管理.代码优化和目标代码生成.大一点的应用可以做到一定的技术先进性,从而让你在本行业站稳脚跟:分析和分解用户输入的SQL语句,理解是否有害和是否有SQL注入等.如果不学,对于不是不是本行业的人来说就没损失,如果是本行业的专业人士,不学只会令自己的编译理解更慢.

编译原理

1.编译原理是什么? (1)就是对程序语言进行翻译: (2)介绍编译程序构造的原理和基本方法: (3)从本质上讲是一个算法问题: 2.学习编译原理有什么好处? (1)接触一些新的算法,如,贪心算法,图论算法等: (2)学习一些新的思想,如,有限状态机,递归下降等: (3)多了一项技能: 3.不学有什么损失? (1)将来出社会可能比较难混: (2)不学好这门课程期末可能不及格: (3)有学不一定有用,不学肯定没用: 4.如何学习编译原理? (1)上课跟上老师的步伐,课前预习,课后复习: (2)多从

编译原理第二次作业 编译器任务总结

在学习了编译原理后我开始明白编译的工作原理了,也更了解编译语言的结构.明白了编译器的编写中需要注意的各项问题,更了解了编译器的编译过程为我之后的编程提供了一些必不可少的经验,还是我的改错能力有所提高.因为写编译器使我在编程发生错误后能及时了解程序在编译过程中的原理是什么,这样我就能知道我的程序是何处的问题. 而且在学习编译原理的时候,学到了一些比较难理解的东西,通过实践不断地消化书本上的理论,最终就会有一个雏形出现.而且在编写的过程时候有一些不知道如何解决的问题时,我就会和组员讨论以得出一个可行

编译原理简单介绍

编译原理学习导论 大学课程为什么要开设编译原理呢?这门课程关注的是编译器方面的产生原理和技术问题,似乎和计算机的基础领域不沾边,可是编译原理却一直作为大学本科的必修课程,同时也成为了研究生入学考试的必考内容.编译原理及技术从本质上来讲就是一个算法问题而已,当然由于这个问题十分复杂,其解决算法也相对复杂.我们学的数据结构与算法分析也是讲算法的,不过讲的基础算法,换句话说讲的是算法导论,而编译原理这门课程讲的就是比较专注解决一种的算法了.在20世纪50年代,编译器的编写一直被认为是十分困难的事情,第

编译原理基础概念介绍

关于编译原理 语法树 句柄 简单短语 短语 的区分,通过两个例子来理解概念以及方法: 例子1——语法树 S -> a|b|(T)  T -> TdS|S Vt={a,b,d,(,)}.Vn={S,T},S是开始符 句型(Sd(T)db)是S的一个推导,其中___是句柄;____是最左素短语:____是该句型的直接短语,_____是短语.     素短语的概念:它是一个递归的定义,至少含有一个终结符,并且除它自身之外不再含任何更小的素短语,所谓最左素短语就是处于句型最左边的素短语的短语.而一个算

编译原理之扫描器

https://github.com/zzusunjs/Scanner 编译原理实验课要求自己实现一个简单一些的扫描器. 我是用c++实现的.具体的原理的话,完全是按照书上的算法实现的,也没有什么特别难懂的地方,不过想要写的比较完备的话还是有一定难度的. Go ->  preProcess() -> init() -> delete-space() ->  Scanner() -> 首字符 ->.... 代码大致的结构就是上面的那个样子.

python实现算术表达式的词法语法语义分析(编译原理应用)

本学期编译原理的一个大作业,我的选题是算术表达式的词法语法语义分析,当时由于学得比较渣,只用了递归下降的方法进行了分析. 首先,用户输入算术表达式,其中算术表达式可以包含基本运算符,括号,数字,以及用户自定义变量. 词法分析,检查单词变量是否正确:语法分析,检查算术表达式语法是否正确并输出生成语法树:语义分析,输出四元表达式. 最终效果图: 例如输入: 词法分析结果: 语法分析结果: 语义分析结果: 算术表达式的组成语法如下: 无符号整数 = 〈数字〉{〈数字〉} 〈标识符〉= 〈字母〉{〈字母

编译原理的实验报告一

实验一 词法分析程序实验 专业 商软2班   姓名 黄仲浩  学号 201506110166 一. 实验目的      编制一个词法分析程序. 二. 实验内容和要求 输入:源程序字符串 输出:二元组(种别,单词符号本身). 三. 实验方法.步骤及结果测试 源程序名:bianyiyuanli.c 可执行程序名:bianyiyuanli.exe 原理分析及流程图 通过一些for循环和while循环进行一个个的翻译. 源程序如下: #include<stdio.h> #include<stri