语法制导翻译与生成中间代码(附代码)

合集下载

语法制导翻译和中间代码生成

语法制导翻译和中间代码生成

A ∨ B→if A then true else B A ∧B→if A then B else false ┐ A →if A then false else true
这种翻译法涉及到如何翻译if-thenelse的问题,将在下面具体讨论。
33
控制语ห้องสมุดไป่ตู้中布尔表达式的翻译
if E then S1 else S2,其中E为布尔式
第8章 语法制导翻译和中间代码生成
经过词法分析、语法分析后,源程序 在静态结构上的正确性得到了保证,编译 程序接着要对源程序进行静态语义检查和 翻译。 语义检查:类型检查、控制流检查、 一致性检查等。 翻译:源程序→中间代码
1
本章主要内容
1. 属性文法 2. 语法制导翻译概念 3. 中间代码的几种形式 4. 几个语句的翻译:如赋值语句、条件语 句等。
26
翻译 a:= -b+c*d

t1:=uminus b t2:=c*d t3:=t1+t2
a
:=
E1

+ E2 E 21 c *
a:=t3

E 11 b
E 22 d
27
类型转换
如:X := Y + I * J,X,Y为实型,I,J为整型, 则相应的四元式序列应为: – (*i , I , J , T1 ) – ( itr , T1 , _ , T2 ) – ( +r , Y , T2 , T3 ) – ( := , T3 , _ , X )
23
四元式
1. 四元式对中间结果的引用必须通过 给定的名字,而三元式是通过产生中间结 果的三元式编号。四元式之间的联系是通 过临时变量实现的。 2. 四元式出现顺序与原表达式计算顺 序一致。(同三元式)

编译原理-语法制导翻译和中间代码生成

编译原理-语法制导翻译和中间代码生成

例:类型、运算、维数、越界
–语义处理:
执行真正的翻译,生成程序的中间代码目标代码。
–例:变量的存储分配
–例:表达式的求值
–例:语句的翻译(中间代码的生成)
3
8.1 属性文法
• 语义分析的描述 –描述语法规则的同时,编写相应的语义 动作和计算顺序
• 语义的形式化描述 –操作语义学、公理语义学、指称语义学
例8-3 3*5+4 的 语法树与属性计算
T.val=3 F.val=3 digit.lexval=3
E.val=15 T.val=15

L Print(19)
E.val=19 +
T.val=4
F.val=4
F.val=5
digit.lexval=4
dgit.lexval=5
19
T.type=real
• 继承属性 – 从其兄弟结点和父结点的属性值计算出来的 – 如:L.in
• 固有属性(单词属性)
17
属性的计算
• 语法制导翻译:作语法分析,构造语法树,然 后在树的每个结点上添加相应的语义规则
• 综合属性 – 自底向上按照语义规则来计算各结点的综合 属性值
• 继承属性 –需要探讨计算次序
18
文法
E→ -E1 E.p:= mknode('-', 0, E1.p)
E→ (E1) E.p:= E1.p E→ id E.p:= mkleaf(id, id.entry) E→ num E.p:=mkleaf(num,num.val)
37
生成后缀式的属性文法
产生式
语义规则
S→id:=E Print( || E.code || “:=”)

第八章语法制导翻译和中间代码生成

第八章语法制导翻译和中间代码生成
但文法开始符号没有继承属性。 终结符只有综合属性。
继承的和综合的属性
属性文法中,对应每一个产生式 A 都有 一套与之相关联的语义规则,每条规则的形 式为:b:=f(c1,c2,……,ck) 其中:f是一个函数,b和c1,c2,……,ck是该 产生式文法符号的属性。
(1)如果b是A的一个属性, c1,c2,……,ck是产 生式右部文法符号的属性或A的其它属性, 则称b是A的综合属性。
To relate each applied occurrence of an identifier in the source program to the corresponding declaration.
语义学
语义形式化、语义建模 文法模型—属性文法 命令式或操作式模型—操作语义学 公理式模型—公理语义学 应用式模型—指称语义学 目前在实际应用中比较流行的语义描述和语
语义规则
D TL T int T real L L1,id
L.in:=T.type T.type=integer T.type:=real L1.in:=L.in addtype(id.entry,L.in)
L id
addtype(id.entry,L.in)
继承属性
一个结点的继承
Real id1,id2,id3
属性文法
使用 N.t 的形式表示与非终结符N相连的属 性t。
T.t的值为int或bool。 与非终结符E的产生式相连的断言表明:两
个T的属性必须相同。
继承的和综合的属性
属性通常分为两类:综合属性和继承属性 综合属性用于“自下而上”传递信息, 继承属性用于“自上而下”传递信息。 非终结符既可有综合属性也可有继承属性,
语义规则 Print(E.val) E.val:=E1.val+T.val E.val:=T.val T.val:=T1.val F.val T.val:=F.val F.val:=E.val F.val:=digit.lexval

语法制导翻译与中间代码生成

语法制导翻译与中间代码生成

(2)如果b是产生式右部某个文法符号X的一个属性,并且 c1,c2,„,ck是A或产生式右边任何文法符号的属性,则称b 是文法符号X的继承属性。
2013-8-12 莆田学院许振和 12
综合属性:归约型属性,用于“自下而上”传递信 息。 继承属性:推导型属性,用于“自上而下”传递信 (1)非终结符既可有综合属性也可有继承属性,但文法 息。 开始符号没有继承属性。 (2)终结符只有综合属性,它们由词法程序提供。例 8.1中,E、T和F的val属性是综合属性,例8.2中的L的in 是继承属性。 结点的综合属性值通过分析树中该结点的子结点的属 性值计算。继承属性值由该结点的兄弟结点和父结点的属 性值计算。
莆田学院许振和
18
1、计算语义规则
属性之间的依赖关系, 实质上反映了属性计算 的先后次序
所谓依赖图是一个有向图,用于描述分析 树中的属性和属性间的相互依赖关系。
如果分析树中一结点的属性b依赖于属性c, 那么这个结点的属性b的语义规则的计算必须 在定义属性c的语义规则的计算之后。分析树 结点的继承属性和综合属性间的互相依赖关系 可以用名为依赖图的有向图来描绘。
2013-8-12
莆田学院许振和
13
例5.1
产 生 式
简单算术表达式求值的语义描述 综合属性的例子
语 义 规 则
Print(E.val) L→ E E →E1+T E.val:=E1.val+T.val E→T E.val:=T.val T →T1 * F T.val:=T1.val F.val T→F T.val:=F.val F→(E) F.val:=E.val F→digit F.val:=digit.lexval
2013-8-12

第八章_3语法制导翻译和中间代码生成-中间代码生成

第八章_3语法制导翻译和中间代码生成-中间代码生成

8.5
控制语句中布尔表达式的翻译
1
控制语句 S→ if E then S E 的代码 E.true: S 1 的代码 goto out S 2 的代码 out:
else S 2 E.true E.false
E.false:
. 把条件转移的布尔表达式翻译成仅含 把条件转移的布尔表达式翻译成仅含 和无条件转 条件真转 (jrop,B,C,L) 和无条件 转 (jump,_,_,L)的四元式 E =a rop b ⇒ if a rop b goto E.true goto E.false 如 :a<b or c<d and e<f 翻译成如下四元式: 可 翻译成如下四元式: (1) if a<b goto E.true (2) goto (3) (3) if c<d goto (5) (4) goto E.false (5) if e<f goto E.true (6) goto E.false
• 高级:最接近高级语言,保留了大部分源语言 的结构。 • 中级:介于二者之间,与源语言和机器语言都 有一定差异。 • 低级:最接近机器语言,能够反映目标机的系 统结构,因而经常依赖于目标机。
不同层次的中间代码
源语言 高级语言) (高级语言)
float a[10][20]; a[i][j+2];
中间代码 高级) (高级)
逆波兰 : 四元式 : ABCD-*+ECD–N^/+ (1) ( C D T1 D N T5 T1 ) T2) T4) T5) T6) T7)
(2) ( * B (3) ( + A (4) ( (6) ( / C E (5) ( ^ T4
T2 T3)

第08章语法制导翻译和中间代码生成

第08章语法制导翻译和中间代码生成
• 如:说明语句的属性文法
17
翻译模式
◆定义
翻译模式是语法制导定义的一种便于翻译的书写 形式。其中属性与文法符号相对应,语义规则或 语义动作用花括号{ }括起来,可被插入到产生 式右部的任何合适的位置上。
这是一种语法分析和语义动作交错的表示法,他 表达在按深度优先遍历分析树的过程中何时执行 语义动作。
–将值 val 作为表达式 E、项 T 和因子 F 的属性
• 用语义规则描述表达式的求值
7
属性文法(语法制导定义)
•L → E
print( E.val )
• E → E1 + T E.val := E1.val + T.val
•E → T
E.val := T.val
• T → T1 * F T.val := T1.val * F.val
33
四元式(三地址代码)
一般形式 x := y op z
–其中 x, y, z 为变量名、常数或编译 产生的临时变量
–四元式(op, x, y, z)
种类:x := y op z
双目运算
x := op y
单目运算
x := y
赋值
if x relop y goto
条件转移
34
a∶=b*c+b*d的四元式表示
a Print(A.in) a Print(A.in)
24
如果计算A1.in和A2.in的值的动作分别被嵌入在产
生式SA1A2 的右部A1和A2之前,而不是后面,
那么A.in在执行Print(A.in)时已有定义。
S {A1in:=1 }A1{A2 in:=2} A2
A a
{ print(A in) }

编译原理:语法制导翻译和中间代码生成

编译原理:语法制导翻译和中间代码生成

中间代码生成的常用方法
三地址码
使用类似于三元表达式的形式 来表示指令,使得生成的代码 更加简洁和高效。
间接中间代码
通过引入临时变量和临时操作 符的方式,将复杂的表达式转 化为更简单的形式。
基于栈的代码生成
将表达式的计算过程用栈来组 织,以实现表达式的计算和结 果的存储。
中间代码表示的形式和结构
符号表达式
编译原理:语法制导翻译 和中间代码生成
在编译原理中,语法制导翻译和中间代码生成是至关重要的步骤。本次演讲 将深入探讨其基本概念、步骤、目的以及常用方法等内容。
语法制导翻译的基本概念
语法制导翻译是基于文法规则和语义分析,将源程序转化为目标程序的过程。它利用文法规则来进行翻译和转 换,以实现对源程序的解释和执行。
使用符号来表示变量、常量和操 作符等,用于描述程序的特定语 义。
抽象语法树
以树的形式组织代码的结构,表 示程序在语法和语义上的结构。
四元式
使用四元组来表示中间代码的指 令和操作数,以便进行翻译和执 行。
中间代码生成的优化技术
1 常量折叠
对于常量表达式,将其直 接计算为常量的值,以减 少运行时的开销。
语法制导翻译的步骤和原理
1
语法分析
通过词法分析和语法分析,将源程序转化为语法树。
2
ห้องสมุดไป่ตู้语义分析
在语法树的基础上,进行类型检查、语义检测和符号表管理。
3
翻译
根据语法树和语义动作,生成目标代码。
中间代码生成的作用和目的
中间代码生成是将源代码转化为一种介于源代码和目标代码之间的中间形式,用于承载程序的执行。 它提供了优化和跨平台的能力,使编译器的输出能够在不同体系结构上正常运行。

语法制导翻译和中间代码生成

语法制导翻译和中间代码生成
addtype(id.entry,L.in)
继承属性L.in
语 义 规 则
语句: real id1, id2, id3 的分析树,采用自上而下的分析方法
产 生 式
D TL
T int
T real
L L1,id
L id
L.in:=T.type
T.type=integer
F.val=3
F.val=5
digit.lexval=4
digit.lexval=5
digit.lexval=3
+
*
3*5+4的带注释的分析树
如果一个语法制导定义仅仅使用综合属性,则称这种语法制导定义为S属性定义。通常采用自底向上的方法对其分析树加注释,即从树叶到树根,按照语义规则计算每个节点的属性值。
表达式文法 E→T+T| T or T T → n | true | false
E → T1 + T2 { T1.type = int AND T2.type = T1. type E.type :=int } E → T1 or T2 { T1.type = bool AND T2.type= T1.type E.type :=bool } T → n { T.type := int } T → true { T.type := bool } T → false { T.type := bool }
T.type:=real
L1.in:=L.in
addtype(id.entry,L.in)
addtype(id.entry,L.in)
D
L.in= real
L.in= real
L.in= real
T.type=real

语法制导翻译和中间代码生成

语法制导翻译和中间代码生成

产生式
语义子程序
(1)A i=E
{GEN(=, E•PLACE ,_,ENTRY(i)}
(2)E -E (1)
{T=NEWTEMP;
GEN(@, E(1)•PLACE ,_,T);
E•PLACE =T }
(3)E E (1)*E(2) {T=NEWTEMP;
GEN(*, E(1)•PLACE , E(2)•PLACE ,T);
予不同的语义值:类型、地址、代码值等。
2021/4/9
9
4、语义栈 各个符号的语义值放在语义栈中 当产生式进行归约时,需对产生式右部符号 的语义值进行综合,其结果作为左部符号的语义 值保存到语义栈中。
下推栈包含3部分: 状态栈、符号栈和语义栈
注:语义栈与状态栈和符号栈是同步变化的。
2021/4/9
10
注:
1)若把语义子程序改成产生某种中间代码的动 作,就能在语法分析制导下,随着分析的进展逐 步生成中间代码。
2)若把语义子程序改成产生某种机器的汇编语 言指令,就能随着分析的进展逐步生成某机器的 汇编语言代码。
2021/4/9
11
例如:
产生式
语义子程序
(0)S` E
{PRINT E•VAL}
注:这些翻译工作很大程度上决定了要产生什么形 式的中间代码。
2021/4/9
8
2、写法 语义子程序写在该产生式后面的花括号内。
Eg: X α {语义子程序1}
注:在一个产生式中同一个文法符号可能出现多次, 但他们代表的是不同的语义值,要区分可以加上 角标。如:E E(1)+E (2)
3、语义值 为了描述语义动作,需要为每个文法符号赋
E•PLACE =T }

语法制导翻译与生成中间代码(附代码)

语法制导翻译与生成中间代码(附代码)

《编译系统设计实践》实验项目三:语法制导翻译与生成中间代码学号::年级:学院:数计学院专业:计算机本组其它成员:学号学号实验时间:2016-2017学年第一学期任课教师:一、实验目的通过语法制导或翻译模式生成中间代码。

二、实验容在自底向上语法分析基础上设计语义规则(语法制导翻译),将源程序翻译为四元式输出,若有错误将错误信息输出。

三、设计思路1.分析过程主函数,读取文件,存入字符串数组,调用语义分析,判断关键字,调用相应的语义规则(这里只有if和while和赋值语句),赋值语句调用表达式处理,if语句调用条件表达式处理,while也是调用表达式处理,然后是一个递归过程,不断的递归调用,按序输出三地址语句。

在本例程序中选用expr及num 作为运算数。

2.主要函数string link() //字符串和数字的连接string element() //获取表达式中的元素对象string expression() //处理表达式string expression_1() //处理表达式string biaodashi() //处理表达式,转为三地址输出string biaodashi_1() //递归---处理表达式,转为三地址输出string getOperator() //判断并获取运算符void condition(int L1,int L2) //输出if语句的条件的三地址代码void yuyifenxi_list() //生成并输出条件返回地址void yuyifenxi_list_1() //递归---生成并输出条件返回地址void yuyifenxi(int next,int &flag) //判断关键字,调用相应的产生式分析void readfile() //文件读入四、测试报告1.第一组测试:图1-1 输入待翻译代码图1-2 中间代码生成2.第二组测试:图2-1 输入待翻译代码图2-2 中间代码生成3.第三组测试:错误待翻译代码图3-1 输入待翻译代码图3-2 中间代码生成五、实验总结实验三的重点在于判断关键字,调用相应的产生式分析及处理表达式,转为三地址输出部分,也是很费时间的难点部分,但通过查阅书本及网上资料,还是将其以多个处理函数的递归调用实现了,虽然最后实现结果对错误的分析还不够精确有些差强人意,但毕竟还算有些收获了。

第五章 语法制导翻译和中间代码生成.

第五章 语法制导翻译和中间代码生成.

a * b c
b
+
* c
抽象语法树
DAG
后缀式与抽象语法树的关系:
后缀式是抽象语法树的线性表示形式; 后缀式是树的结点的一个序列,每个结点 都是在它的所有子结点之后立即出现。 抽象语法树的边没有显式地出现在后缀 式中,可以根据结点出现的次序和算符 的目数还原出来。 如上例的后缀式为 a b c - * b c - * + =
5.4.2 图表示法

图表示法包括DAG与抽象语法树 DAG(directed acyclic graph)无循环有向图


每个子表达式一个结点,一个内部结点代表一 个操作符,它的子结点代表操作数; 公共子表达式的结点具有多个父结点。

DAG描述源程序的自然层次结构,比抽象 语法树更紧凑。
a=b*-c+b*-c的图表示法 = a * b c + =

产生式
语义规则


L→E
E → E1 + T E→T T → T1 * F T→F
print( E.val )
E.val = E1.val + T.val E.val = T.val T.val = T1.val * F.val T.val = F.val


F→(E)
F → digit
4、循环语句的逆波兰表示:

循环语句:FOR ( i=m;i<= n;i++) S FOR语句展开为等价形式:
i=m; 10: if i<= n {S; i=i+1; goto 10}

逆波兰式:
im= <序号1:> S的逆波兰式 <序号2:> i n<= <序号2> BF i i1+= 序号1 BR
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《编译系统设计实践》实验项目三:语法制导翻译与生成中间代码学号:姓名:年级:学院:数计学院专业:计算机本组其它成员:学号姓名学号姓名实验时间:2016-2017学年第一学期任课教师:一、实验目的通过语法制导或翻译模式生成中间代码。

二、实验内容在自底向上语法分析基础上设计语义规则(语法制导翻译),将源程序翻译为四元式输出,若有错误将错误信息输出。

三、设计思路1.分析过程主函数,读取文件,存入字符串数组,调用语义分析,判断关键字,调用相应的语义规则(这里只有if和while和赋值语句),赋值语句调用表达式处理,if语句调用条件表达式处理,while也是调用表达式处理,然后是一个递归过程,不断的递归调用,按序输出三地址语句。

在本例程序中选用expr及num作为运算数。

2.主要函数string link() //字符串和数字的连接string element() //获取表达式中的元素对象string expression() //处理表达式string expression_1() //处理表达式string biaodashi() //处理表达式,转为三地址输出string biaodashi_1() //递归---处理表达式,转为三地址输出string getOperator() //判断并获取运算符void condition(int L1,int L2) //输出if语句的条件的三地址代码void yuyifenxi_list() //生成并输出条件返回地址void yuyifenxi_list_1() //递归---生成并输出条件返回地址void yuyifenxi(int next,int &flag) //判断关键字,调用相应的产生式分析void readfile() //文件读入四、测试报告1.第一组测试:图1-1 输入待翻译代码图1-2 中间代码生成2.第二组测试:图2-1 输入待翻译代码图2-2 中间代码生成3.第三组测试:错误待翻译代码图3-1 输入待翻译代码图3-2 中间代码生成五、实验总结实验三的重点在于判断关键字,调用相应的产生式分析及处理表达式,转为三地址输出部分,也是很费时间的难点部分,但通过查阅书本及网上资料,还是将其以多个处理函数的递归调用实现了,虽然最后实现结果对错误的分析还不够精确有些差强人意,但毕竟还算有些收获了。

另外,通过三次实验下来,对于一个简易编译器的实现已经有了一个整体的构架了,相信在通过自己以后的深入学习,一定能写出属于自己的编译器。

六、附录代码#include <iostream>#include <algorithm>#include<conio.h>using namespace std;int address=100; //每条分析语句的地址int LID=0; //表示过程执行到相应位置的地址符号int tID=0;//用于替换表达式的标识符int ip=0;string shuru[666];//存放从文件读入的字符串int maxsize;//设置存放数组的长度string biaodashi();/*****字符串和数字的连接*****/string link(string a,int b){string t="";do{t+=b%10+'0';b/=10;}while(b);reverse(t.begin(),t.end());return a+t;}/*****获取表达式中的元素对象*****/string element(){if(shuru[ip]=="expr"||shuru[ip]=="num"){ip++;return shuru[ip-1];}else if(shuru[ip]=="("){ip++;string result=biaodashi();if(shuru[ip]==")")ip++;else puts("Lack)");return result;}else puts("error");return "";}/*****处理表达式*****/string expression_1(string &op){if(shuru[ip]=="*"||shuru[ip]=="/"){op=shuru[ip];ip++;string arg1=element();string op_1="",result=link("t",tID++);string arg2=expression_1(op_1);if(op_1=="")op_1="=";if(arg2=="") cout<<address++<<":"<<" "<<result<<" = "<<arg1<<endl;else cout<<address++<<":"<<" "<<result<<" = "<<arg1<<" "<<op_1<<" "<<arg2<<endl;return result;}return "";}/*****处理表达式*****/string expression(){string op="",result=link("t",tID++);string arg1=element();string arg2=expression_1(op);if(op==""){op="=";}if(arg2==""){cout<<address++<<":"<<" "<<result<<" = "<<arg1<<endl;}else{cout<<address++<<":"<<" "<<result<<" = "<<arg1<<" "<<op<<" "<<arg2<<endl;}return result;}/*****递归---处理表达式,转为三地址输出*****/string biaodashi_1(string &op){string result="";if(shuru[ip]=="+"||shuru[ip]=="-"){op=shuru[ip];ip++;string arg1=expression();string op_1="";string arg2=biaodashi_1(op_1);result=link("t",tID++);if(op_1==""){op_1="=";}if(arg2==""){cout<<address++<<":"<<" "<<result<<" = "<<arg1<<endl;}else{cout<<address++<<":"<<" "<<result<<" = "<<arg1<<" "<<op_1<<" "<<arg2<<endl;}}return result;}/*****处理表达式,转为三地址输出*****/string biaodashi(){string arg1="",op="";if(shuru[ip]=="+"||shuru[ip]=="-"){arg1=shuru[ip];ip++;}arg1+=expression();string arg2=biaodashi_1(op);string result=link("t",tID++);if(op==""){op="=";}if(arg2==""){cout<<address++<<":"<<" "<<result<<" = "<<arg1<<endl;}else{cout<<address++<<":"<<" "<<result<<" = "<<arg1<<" "<<op<<" "<<arg2<<endl;}return result;}/*****判断并获取运算符*****/string getOperator(){if(shuru[ip]=="="||shuru[ip]=="<>"||shuru[ip]=="<"||shuru[ip]==">"||shuru[ip]=="<="||shuru[ip]==">="){ip++;return shuru[ip-1];}else{puts("error");}return "";}/*****输出if语句的条件的三地址代码*****/void condition(int L1,int L2) //L1,L2分别为if条件为true和false时候的跳转地址{string result=link("t",tID++);string arg1=biaodashi(); //获得表达式的运算符的左边内容string op=getOperator();//获得表达式的运算符string arg2=biaodashi();//获得表达式的运算符的右边内容if(arg2==""){cout<<" "<<result<<" = "<<arg1<<endl;}else{cout<<address++<<":"<<" "<<result<<" = "<<arg1<<" "<<op<<" "<<arg2<<endl;}cout<<address++<<":"<<" if true "<<result<<" goto "<<"L"<<L1<<endl;cout<<address++<<":"<<" if false "<<result<<" goto "<<"L"<<L2<<endl;}/*****判断关键字,调用相应的产生式分析*****/void yuyifenxi(int next,int &flag){if(shuru[ip]=="expr"){ip++;if(shuru[ip]=="=")//赋值语句转化为四元式{ip++;string arg1=biaodashi();string arg2="";if(arg2 == "") cout<<address++<<":"<<" expr = "<<arg1<<endl;}else puts("error");}else if(shuru[ip]=="if") //if的语义子程序{ip++;int L1=LID++;int L2=LID++;if(shuru[ip]=="("){ip++;condition(L1,L2);}else{puts("Lack(");return;}if(shuru[ip]==")") ip++;else {puts("Lack)");return;}printf("L%d:\n",L1);yuyifenxi(next,flag);ip++;if(shuru[ip]=="else"){printf("L%d:\n",L2);ip++;yuyifenxi(next,flag);}}else if(shuru[ip]=="while")//while的语义子程序{ip++;int L1=LID++;int L2=LID++;if(shuru[ip]=="("){ip++;printf("L%d:\n",L1);condition(L2,next);}else{puts("Lack(");return;}if(shuru[ip]==")") ip++;else {puts("Lack)");return;}printf("L%d:\n",L2);yuyifenxi(next,flag);printf("goto L%d\n",L1);flag=1;}}/*****递归---生成并输出条件返回地址*****/ void yuyifenxi_list_1(){if(shuru[ip]==";"){ip++;int next=LID++;int flag=0;yuyifenxi(next,flag);if(flag)printf("L%d:\n",next);yuyifenxi_list_1();}}/*****生成并输出条件返回地址*****/void yuyifenxi_list(){int next=LID++;int flag=0;yuyifenxi(next,flag);if(flag)printf("L%d:\n",next);yuyifenxi_list_1();}void Modular(){int next=LID++;int flag=0;yuyifenxi_list();if(flag)printf("L%d:\n",next);}/*****文件读入*****/void readfile() //将字符串输入到shuru中{maxsize=0;while(cin>>shuru[maxsize])maxsize++;}/*****主函数*****/int main(){freopen("input.txt","r",stdin);cout<<"语义分析如下:"<<endl;readfile();Modular();return 0;}。

相关文档
最新文档