编译原理

Javac编译原理:Item(1)——基本介绍

落花浮王杯 提交于 2019-12-19 23:51:32
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 首先,必须明确Java语言规范和Java虚拟机规范不是一回事。 Java语言规范描述了Java语言有哪些词法和语法,而Java虚拟机也有Java虚拟机规范,它们都有自己的词法和语法解析规则,而且解析规则也是不同的。 那么如何才能让Java的语言规则适应Java虚拟机的语法规则呢? 这个任务就由Javac编译器来完成的,它的任务就是将Java语言规范转化为Java虚拟机语言规范,完成”翻译“工作。 一、Javac是什么? Javac是一种编译器,能够将一种语言规范转化成另外一种语言规范 Javac的任务就是将Java源代码语言先转化为JVM能够识别的一种语言(Java字节码),这种字节码不是针对某种机器、某种平台的 如何消除不同种类、不同平台机器之间的差别,这个任务就由JVM完成, VM将JVM语言(Java字节码)转换成当前机器能够识别的机器语言。 二、Javac编译器编译程序的步骤 词法分析 首先是读取源代码,找出这些字节中哪些是我们定义的语法关键词,如Java中的if、else、for等关键词。 词法分析的结果:从源代码中找出一些规范化的Token流。 语法分析 这一步就是检查关键词组合在一起是不是符合Java语言规范,如if的后面是不是紧跟着一个布尔判断表达式。 语法分析的结果

从hello world 说程序运行机制

我们两清 提交于 2019-12-18 15:41:00
转自: http://www.cnblogs.com/yanlingyin/archive/2012/03/05/2379199.html 开篇 编译,简单的说,就是把源程序转换为可执行程序。 从hello world 说程序运行机制 里面简单的说明了程序运行的过程,以及一个程序是如何一步步变成可执行文件的。在这个过程中,编译器做了很多重要的工作。对底层该兴趣的我,自然的,也就迫切想搞清楚编译的内部实现,也就是编译的原理。 这篇文章主要说的是编译器前端,词法分析器的原理,最后会给出一个词法分析器的简单实现。 介绍 编译简单的说,就是把源程序转化为另一种形式的程序,而其中关键的部分就是理解源程序所要表达的意思,才能转化为另一种源程序。 可以用一个比喻来说明问题:人A和人B想要交谈,但是他们都不知道彼此的语言,这就需要一个翻译C,同时懂得A和B的语言。有了C做中间层,A和B才能正常交流。C的作用就有点像编译器,它必须能理解源程序所要表达的意思,才能把信息传递给另一个。 编译器也一样,它的输入是语言的源文件(一般可以是文本文件)对于输入的文件,首先要分离出这个输入文件的每个元素(关键字、变量、符号、、) 然后根据语言的文法,分析这些元素的组合是否合法,以及这些组合所表达的意思。 程序设计语言和自然语言不一样,都是用符号来描述,每个特定的符号表示特定的意思,而且程序设计语言是上下文无关的

编译原理——证明文法具有二义性

谁说我不能喝 提交于 2019-12-15 02:55:26
证明一个文法具有二义性我们需要掌握两个知识点。 1.语法分析树 定义很简单,就是把一个句型的推导写成树的形式,这种表示法就叫语法分析树,或者简称为语法树。大概是这个样子的 2.二义性 一个文法存在某个句子对应两棵不同的语法树,则称这个文法是二义的。也就是该句子有两个不同的最左(最右)推导。 ok,让我们 证明下列文法G(S)是二义的 S->Ac|aB A->ab B->bc 过程很简单就是自己定义一个句子,然后说明这个句子有两个语法树就可以了。 这里定义句子是abc,对应的两个语法树像这个样子 所以该文法是二义文法。 来源: CSDN 作者: 哆啦m梦 链接: https://blog.csdn.net/weixin_44162921/article/details/103481890

编译原理 14 算符优先分析

走远了吗. 提交于 2019-12-14 12:33:17
1、 栈 关系 输入串 动作 1 # < (i+i)*i# 移进 2 #( < i+i)*i# 移进 3 #(i > +i)*i# 规约 4 #(N < +i)*i# 移进 5 #(N+ < i)*i# 移进 6 #(N+i > )*i# 规约 7 #(N+N > )*i# 规约 8 #(N = )*i# 移进 9 #(N) > *i# 规约 10 #N < *i# 移进 11 #N* < i# 移进 12 #N*i > # 规约 13 #N*N > # 规约 14 #N # 接受 2、   (1)       S->a | ^ | (T)   T->T,S | S     FIRSTVT(S)={a,^,(}     FIRSTVT(T)={, ,a,^,(}     LASTVT(S)={a,^,)}     LASTVT(T)={,,a,^,)}   (2)   (3) a ^ ( ) , # a > > > ^ > > > ( < < < = < ) > > > , < < < > > # < < < =    (4)     符合   (5) 栈 关系 输入串 动作 # < (a,(a,a))# 移进 #( < a,(a,a))# 移进 #(a > ,(a,a))# 规约 #(N < ,(a,a))# 移进 #(N < (a,a))# 移进 #(N,( < a,a))#

编译原理实验:中间代码生成——逆波兰表达式

≯℡__Kan透↙ 提交于 2019-12-12 05:31:52
编译原理实验:中间代码生成——逆波兰表达式 逆波兰表达式 测试 逆波兰表达式 运算对象写在前,运算符写在后(后缀表示形式) 例如:a+b → \rightarrow → ab+   (a+b) c → \rightarrow → ab+c   a+b c → \rightarrow → abc +   a=b c+b d → \rightarrow → abc bd += 优点:易于计算机处理 利用栈,将扫描到的运算对象入栈,碰到运算符: 若是双目运算符,则对栈顶的两个运算对象实施该运算并将运算结果代替这两个运算对象进栈; 若是单目运算符,对栈顶元素,执行该运算,将运算结果代替该元素进栈,最后结果即栈顶元素。 c++代码: # include <string> # include <iostream> # include <map> # include <stack> # include <vector> using namespace std ; string str ; //需要进行分析的算术表达式 stack < char > tem ; //当无法确定运算符是否要输出的时候,将运算符进栈 vector < string > exp ; //逆波兰表达式序列 map < char , int > opPri ; //定义预定义运算符的优先级 bool convert ( )

编译原理:算符优先分析

梦想的初衷 提交于 2019-12-11 10:41:33
1. 已知算符优先关系矩阵如下表: + * i ( ) # + > < < < > > * > > < < > > i > > > > ( < < < < = ) > > > > # < < < < = 写出符号串(i+i)*i#的算符优先分析过程。 <= 移进 > 归约 分析过程如下: 栈 关系 输入串 动作 1 # < (i+i)*i# 移进 2 #( < i+i)*i# 移进 3 #(i > +i)*i# 归约 4 #(N < +i)*i# 移进 5 #(N+ < i)*i# 移进 6 #(N+i > )*i# 归约 7 #(N+N > )*i# 归约 8 #(N = )*i# 移进 9 #(N) > *i# 归约 10 #N < *i# 移进 11 #N* < i# 移进 12 #N*i > # 归约 13 #N*N > # 归约 14 #N # 接受 2.接上个作业(P121练习1),完成4),5)两个步骤。 1)计算FIRSTVT和 LASTVT。 2)找三种关系对。 3)构造算符优先关系表。 4)是否算符优先文法? 5)给出输入串(a,(a,a))#的算符优先分析过程。 优先关系: a ^ ( ) , # a > > > ^ > > > ( < < < = < ) > > > , < < < > > # < < < = 4) 是。 5)算符优先分析过程如下: <=

编译原理——判断文法是否为算符优先文法

余生长醉 提交于 2019-12-10 16:53:55
编译原理——判断文法是否为算符优先文法 在判断之前我们需要看一下该文法是否为算符文法。 算符文法定义 一个文法,如果它的任意产生式的右部都不含两个相继(并列)的非终结符,即不含如下形式的产生式右部: …QR… 那么我们称该文法为算符文法。 接下来就可以构造优先关系表了,再构造之前我们需要了解两个基本知识。 1.算符优先关系 关系有三种: a<b a的优先性低于b a>b a的优先性高于b a=b a的优先性等于b 注意 :<,>,=写的时候中间有个点,而且关系不像数学中的那样,a<b不一定意味着b>a,a=b也不一定意味着b等于a。 2.FIRSTVT集和LASTVT集的构造方法 FIRSTVT集构造方法: 1.P->a…或者P->Qa…,那么a∈FIRSTVT(P) 2.a∈FIRSTVT(Q)且P->Q…,那么a∈FIRSTVT(P) LASTVT集构造方法: 1.P->…a或者P->…aQ,那么a∈LASTVT(P) 2.a∈LASTVT(Q),P->…Q,那么a∈LASTVT(P) 看上去是不是很简单,那我们 设有文法G: S→a|b|(A) A→SdA|S 对于FIRSTVT(S),很容易看出来有a,b(…在这里就是空字),还有(【这里的…就是A)】,对于FIRSTVT(A),有d(应用了P->Qa…),再通过第二条规则,在这里SdA和S哪个产生式都行

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

故事扮演 提交于 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). 消除直接左递归 ​ 当同一个非终结符的多个候选式存在相同的前缀时,会导致回溯(最终只会匹配其中一个

编译原理(一)

心不动则不痛 提交于 2019-12-06 14:15:27
编译器结构: 编译器实例:(stack:栈式计算机) 编译器的前端: 词法分析: 手工实现(需要书写词法分析器): 词法分析识别关键字和标识符 方法一: 方法二: 自动生成(需要书写声明式的规范):正则表达式 正则表达式的定义: 例子: 如果是C语言,∑=ASCII;如果是Java语言,∑=UNodd 简化的正则表达式: 有限状态自动机: 来源: https://www.cnblogs.com/lq13035130506/p/11988914.html

编译原理 十三

折月煮酒 提交于 2019-12-06 13:07:46
1.已知文法: E→E+T | T T→T*F | F F→(E) | i 以句柄作为可归约串,写出符号串‘i+i*i#’的"移进-归约"分析过程。 解: 2.P121练习1的(1)(2)。 1)计算FIRSTVT和 LASTVT。 2)找三种关系对。 3)构造算符优先关系表。 已知文法为: S->a|Λ|(T) T->T,S|S 解: 1) FIRSTVT(S)={a Λ ( } FIRSTVT(T)={, a Λ ( } LASTVT(S)={a Λ ) } LASTVT(T)={a , Λ ) } 2) =   #S#   (T) <   #S   (T   ,S >   S#   T)   T, 3) 来源: https://www.cnblogs.com/huangwenshuo/p/11986417.html