语法分析

编译原理(语法分析)

删除回忆录丶 提交于 2020-01-25 13:14:11
文章目录 上下文无关文法 下推自动机PDA 自上而下语法分析 二义性 消除左递归 提取公共左因子 预测分析程序 自下而上语法分析 LR(0) 活前缀 项目 SLR(1) 如何判断一个文法是不是SLR(1)? 上下文无关文法 与正规式属于同一层面,表达语法分析的基本单元 越接近根节点的运算优先级越低 运算符左结合和右结合的判断: S=A+S 则+是右结合 A=A*id 则*是左结合 CSL上下文有关文法,sensitive CFL上下文无关文法,free 下推自动机PDA 相比NA自动机,多了下推栈和下推栈内字母表 给定语言,如何写出他的下推自动机? 例如L={a n cb n ,n>=0} 写出他对应的文法,S→aSb | c 生成相应的PDA M 这4个映射关系的含义 1,2,3的映射代表了栈顶是a,读头指向了a,用空串替换了栈里的a 4的映射代表了读头指向了S,栈中没有与之匹配的,故用空串表示,然后向栈里压入S的文法表达,aSb或者c PDA的推导过程,首先收到语言aacbb,栈内是S,表头指向a,因此用aSb替换掉栈内的S,此时栈顶变为a,a对a,抵消,以此类推,如果能抵消掉整个字符串,即最后#对#,代表这个语言符合语法,与定义的文法保持一致; 自上而下语法分析 自上而下分析的含义 从符号开始 从左到右 推导出最后的句子, 自上而下 建立它的分析树

LEX和YACC的使用三

我是研究僧i 提交于 2020-01-21 03:27:52
2.4.3 yacc解决二义性和冲突的方法 在2.3.8中已涉及到二义性和冲突的问题,这里再集中介绍一下,这在写Yacc源程序时会经常碰到。二义性会带来冲突。在2.3.8中我们介绍了yacc可以用为算符确定优先级和结合规则解决由二义性造成的冲突,但是有一些由二义性造成的冲突不易通过优先级方法解决, 如有名的例子: stat:IF bexp THEN stat |IF bexp THEN stat ELSE stat ; 对于这样的二义性造成的冲突和一些不是由二义性造成的冲突,Yacc提供了下面两条消除二义性的规则: A1.出现移进/归约冲突时,进行移进; A2. 出现归约/归约冲突时,按照产生式在yacc源程序中出现的次序,用先出现的产生式归约。 我们可以看出用这两条规则解决上面的IF语句二义性问题是合乎我们需要的。所以用户不必将上述文法改造成无二义性的。当Yacc用上述两条规则消除了二义性,它将给出相应信息。 下面再稍微严格地介绍一下Yacc如何利用优先级和结合性来解决冲突的。 Yacc源程序中的产生式也有一个优先级和结合性.这个优先级和结合性就是该产生式右部最后一个终结符或文字字符的优先级和结合性,当使用了%Prec子句时,该产生式的优先级和结合性由%Prec子句决定。当然如果产生式右部最后一个终结符或文字字符没有优先级或结合性,则该产生式也没有优先级或结合性。 根据终结符

[你必须知道的.NET]第三十五回,判断dll是debug还是release,这是个问题

拥有回忆 提交于 2020-01-21 02:17:07
问题的提出 晚上翻着群里的聊天,发现一个有趣的问题:如何通过编码方式来判断一个dll或者exe为debug build还是release build?由于没有太多的讨论,所以我只好自己找点儿办法,试图解决这个问题,为夜生活带点刺激。于是,便有了本文的探索和分析。 当然,为了充分的调动起大家的主意,省去不必要的google操作,我觉得有必要对Debug和Release两种模式的异同进行一点提纲挈领式的分析,从而为接下来的解决方案打好基础。 Debug & Release 我们应用Visual Studio对代码文件进行F5操作(Build)时,实际是发生了一系列语法检查、词法检查和编译过程,通常情况下我们有两种Build模式,这就是常说的Debug Build和Release Build。望文知意,Debug Build模式通常应用于开发时,便于调试反馈;而Release Build则应用于部署时,这是因为Release模式下,编译器做了很多的优化操作(代码冗余、循环优化等),省去了对调试信息的记录。因此,两种Build模式是各不相同的,我们对其二者进行一点总结如下: Debug用于开发时,Release用于部署时。 Debug模式下,将产生pdb文件,用于保存状态信息和调试信息;Release模式下,不产生调试信息,也没有pdb文件。 Debug模式下,System

实验二 递归下降语法分析

折月煮酒 提交于 2019-12-26 10:45:56
一、实验目的: 利用C语言编制递归下降分析程序,并对简单语言进行语法分析。 编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。 二、实验原理 每个非终结符都对应一个子程序。 该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端: 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理 每遇到一个非终结符,则调用相应的子程序 三、实验要求说明 输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。 例如: 输入begin a:=9;x:=2*3;b:=a+x end # 输出success 输入x:=a+b*c end # 输出‘end' error 四、实验步骤 1.待分析的语言的语法(参考P90) 2.将其改为文法表示,至少包含 –语句 –条件 –表达式 3. 消除其左递归 4. 提取公共左因子 5. SELECT集计算 6. LL(1)文法判断 7. 递归下降分析程序 #include <iostream> #include<stdio.h> #include<string.h> #include<stdlib.h> char prog[80],token

预编译 AO

人盡茶涼 提交于 2019-12-22 02:16:28
js运行时会进行三件事: 1.语法分析 2.预编译 3.解释执行 语法分析会在代码执行前对代码进行通篇检查,以排除一些低级错误 预编译发生在代码执行的前一刻 解释执行就是执行代码 预编译的作用: 1、函数声明整体提前; 写出一个函数声明,不管写在哪里,系统总会将其提升到逻辑最前面。 2、变量声明提前 例如: document . write ( x ) ; //undefined var x = '你好' ; 相当于 var x ; //提前 document . write ( x ) ; //undefined x = '你好' ; 预编译前奏 1、任何变量,如果变量未经声明就赋值,此变量就为全局对象所有, 2、一切声明的全局变量,全是window的属性; 预编译四个步骤: 1、创建AO(activation object/执行期上下文)对象 2、找形参和变量声明,将变量和形参作为AO的属性名,值为undefined 3、将实参值和形参统一 4、在函数中找函数声明,值赋予函数体 根据预编译四个步骤逐步分析: function fun ( x ) { console . log ( x ) ; var x = 'beautiful' ; console . log ( x ) ; function x ( ) { } console . log ( x ) ; var y =

YACC (Yet Another Compiler Compiler)

走远了吗. 提交于 2019-12-20 00:38:15
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> yacc(Yet Another Compiler Compiler) 是Unix/Linux上一个用来生成 编译器 的编译器(编译器代码生成器)。yacc生成的编译器主要是用C语言写成的语法解析器(Parser),需要与词法解析器Lex一起使用,再把两部份产生出来的C程序一并编译。yacc本来只在Unix系统上才有,但现时已普遍移植往Windows及其他平台。 分析程序生成器(parser generator)是一个指定某个格式中的一种语言的语法作为它的输入,并为该种语言产生分析过程以作为它的输出的程序。在历史上,分析程序生成器被称作编译-编译程序( compiler- compiler ),这是由于按照规律可将所有的编译步骤作为包含在分析程序中的动作来执行。现在的观点是将分析程序仅考虑为编译处理的一个部分,所以这个术语也就有些过时了。合并 LALR(1) 分析算法是一种常用的分析生成器,它被称作 Yacc( yet another compiler- compiler )。给出 Yacc 的概貌来,将使用Yacc为 TINY 语言开发一个分析程序。   作为 Yacc 对说明文件中的 %token NUMBER 声明的对应。Yacc 坚持定义所有的符号记号本身,而不是从别的地方引入一个定义

如何用flex+bison写语法分析器

无人久伴 提交于 2019-12-19 23:27:53
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 背景 这个星期,项目中要使用C++或C语言解析JSON格式的数据,把解析的结果放到一个通用的数据结构。这个通用的数据结构,实际上是作为web服务层(这一层大家可以认为是类似于PHP服务器或webpy的服务器容器)到web页面层(这一层是语法类似PHP脚本或者tornardo模板)的数据传输的协议。 之所以要这样处理, 主要是因为这个web类的项目(一般的web类项目也是如此)需求变化较快,而web的服务层使用是采用C++进行开发的,为了使当web服务层的数据格式变化不影响web页面层,所以双方使用统一的通用的数据结构。而之所以交代这么多的背景是, 为了让大家了解为什么我们不使用类似rapidjson或jsoncpp来实现json的解析而需要手写解析器。 因为使用类似rapidJson或者是jsoncpp之类的Json解析器,相当于我们要做: JSON文档 -> json DOM -> 通用数据结构。 而如果手写解析器,只需要做: JSON文档 -> 通用数据结构。 少一层转换能换来很多效率的提升。 说了这么多,下面开始进入正题。 以前学编译原理的时候,老师推荐过LEX /YACC来写编译器,其实这是古老的UNIX软件。 LINUX上有他们的GNU版本 FLEX、BISON。 这两个东西一个是词法分析器

第十二次-递归下降语法分析

那年仲夏 提交于 2019-12-18 12:30:08
一、实验目的: 利用C语言编制递归下降分析程序,并对简单语言进行语法分析。 编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。 二、实验原理 每个非终结符都对应一个子程序。 该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端: 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理 每遇到一个非终结符,则调用相应的子程序 三、实验要求说明 输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。 例如: 输入begin a:=9;x:=2*3;b:=a+x end # 输出success 输入x:=a+b*c end # 输出‘end' error 四、实验步骤 1.待分析的语言的语法(参考P90) 2.将其改为文法表示,至少包含 –语句 –条件 –表达式 3. 消除其左递归 4. 提取公共左因子 5. SELECT集计算 6. LL(1)文法判断 7. 递归下降分析程序 解: #include<stdio.h> #include <iostream> #include<string.h> using namespace std; char *reserved

语法分析:算术表达式预测分析程序设计

一个人想着一个人 提交于 2019-12-16 18:02:26
1、实验目的: (1)掌握自上而下语法分析的要求与特点。 (2)掌握LL(1)语法分析的基本原理和方法。 (3)掌握相应数据结构的设计方法。 2、实验内容: 编程实现给定算术表达式的分析器。 算术表达式文法如下: E-->E+T|T T-->T*F|F F-->(E)|i 3、设计说明: 首先改写文法为LL(1)文法;构造LL(1)分析表,然后编写预测分析程序。 4、设计分析与步骤 (1)将原算术表达式方法改写为LL(1)文法为: E-->TE' E'-->+TE'|ε T-->FT' T'-->*FT'|ε F-->(E)|i (2)计算文法中每一个非终结符的FIRST集和FOLLOW集 /*--> */ /*--> */ FIRST FOLLOW E { (,i } { $,) } E’ { +,ε } { ),$ } T { (,i } { ),+,$ } T’ { *,ε } { ),+,$ } F { (,i } { * } (3)构造预测分析表 1、对于规则E-->TE’,因为有E的FIRST(TE’)={(,i},所以可以置M[E,(]=E-->TE’,M[E,i]=E-->TE’ 2、 对规则E’-->+TE’,有FIRST(+TE’)={+},所以有M[E’,+]=E’-->+TE’ 3、对规则E’-->ε,有FOLLOW(E’)={), $},所以有M[E’,

编译原理-----第四章 语法分析

故事扮演 提交于 2019-12-10 11:08:09
第四章 语法分析 文章目录 第四章 语法分析 @[toc] 1. 自顶向下分析概述 (1). 最左推导 (2). 递归向下分析 2. 文法转换 (1). 消除直接左递归 (2). 消除间接左递归 (3). 提取左公因式 3. LL1文法 (1). 预测分析法 1). 工作过程 4. FIRST集和FOLLOW集 (1). 非终结符的后继符号集 (2). 产生式的可选集 (3). 串首终结符集 (4). LL1文法 (5). 预测分析表 1). 求FIRST集 2). 求FOLLOW集 3). 求SELECT集 4). 预测分析表 5. 递归的预测分析法 6. 非递归的预测分析法 7. 预测分析法中的错误处理 8. 自底向上的分析概述 (1). 移入-归约分析 9. LR分析法概述 (1). 基本原理 1. 自顶向下分析概述 ​ 从分析树的根节点向叶节点方向构造分析树,可以看做是从文法开始符号推导出词串的过程 (1). 最左推导 ​ 在最左推导中,总是选择每个句型的最左侧非终结符进行替换. (2). 递归向下分析 ​ 计算机程序实现的自顶向下分析的通用形式. ​ 每层递归对应一个非终结符(相当于遍历一个树的子节点,非终结符对应的是非叶子节点) ​ 搭配回溯使用 2. 文法转换 (1). 消除直接左递归 ​ 当同一个非终结符的多个候选式存在相同的前缀时,会导致回溯(最终只会匹配其中一个