基于gui的交互式编译系统之中间代码生成器的设计与实现毕业论文(编辑修改稿)内容摘要:
(label_2:, _, _, _) (+, i, 1, i) // 迭代 (jmp, label_0, _, _) (label_3:, _, _, _) 每个 for 语句会产生四个标号,一个表示类似“ i = 0”的初始化,一个表示类似“ i 3”的条件判断,一个表示 body,一个表示类似“ i++”的表达式。 ifelse 语句 if(a b) 基于 GUI 的交互式编译系统之中间代码生成器的设计与实现 12 c = a。 else c = b。 = (, a, b, temp_0) (jtrue, label_1, temp_0, _) (jmp, label_0, _, _) (label_1:, _, _, _) (=, a, _, c) (jmp, label_2, _, _) (label_0:, _, _, _) (=, b, _, c) (label_2:, _, _, _) 一个 ifelse 语句会产生 3 个标号,一个表示条件为真时的执行语句,一个表示条件为假的执行语句,一个表示跳出 ifelse 语句。 while 语句 while(a b) a = a + 1。 = (label_0:, _, _, _) (, a, b, temp_0) (jtrue, label_1, temp_0, _) (jmp, label_2, _, _) (label_1:, _, _, _) (+, a, 1, temp_1) (=, temp_1, _, a) (jmp, label_0, _, _) (label_2:, _, _, _) 每个 while 语句产生 3 个标号,一个表示类似“ a = 0”的初始化,一个表示类似“ a b”的条件判断,一个表示 body。 基于 GUI 的交互式编译系统之中间代码生成器的设计与实现 13 switch 语句 switch(i) { case 1: a = a + 1。 break。 default: a = a + 2。 } = (jmp, label_0, _, _) (label_3:, _, _, _) (+, a, 1, temp_0) (=, temp_0, _, a) (jmp, label_2, _, _) (label_1:, _, _, _) (+, a, 2, temp_1) (=, temp_1, _, a) (jmp, label_2, _, _) (label_0:, _, _, _) (==, i, 1, temp_2) (jtrue, label_3, temp_2, _) (jmp, label_1, _, _) (label_2:, _, _, _) 每个 switch 语句会 针对相应的 case 和 default 产生标号,同时,还会产生跳出 switch的标号。 函数调用 int add(int a, int b) { return a + b。 } void main() 基于 GUI 的交互式编译系统之中间代码生成器的设计与实现 14 { int a = 1, b = 1, c。 c = add(a, b)。 } = (add:, _, _, _) (enter, 16, _, _) (+, a, b, temp_0) (return, temp_0, _, _) (return, _, _, _) (main:, _, _, _) (enter, 16, _, _) (=, 1, _, a) (=, 1, _, b) (param, b, _, _) (param, a, _, _) (call, add, _, temp_1) (incStackPtr, 8, _, _) (=, temp_1, _, c) (return, _, _, _) 每个函数调用会针对主调函数和被调函数产生相应的标号。 以上只是列举了一些简单情况下的示例,对于复杂的源程序,翻译成的四元式集是以上常见四元式结构组合的结果。 符号表 符号表是一种供编译器用于保存有关源程序构造的各种信息的数据结构,这些信息在编译器的分析阶段被逐步收集并放入符号表 [11]。 编译器用符号表跟踪作用域及名字绑定的相关信息。 在源程序 中每次遇到名字都会去搜索符号表。 如果新的名字出现或关于一个已存在名字新的信息出新,要对符号表进行更新。 符号表条目可在词法分析阶段、语法分析阶段和语义分析阶段创建(如图 )。 在基于 GUI 的交互式编译系统之中间代码生成器的设计与实现 15 本设计中,由语法分析器来创建这些条目。 因为相对于词法分析器而言,语法分析器知道一个程序的语法结构,它可以更好地区分一个词法单元的实际意义,因此常更适合创建符号表条目。 图 符号表 符号表通常用哈希表实现。 KEY:词素( lexeme), VALUE:符号( symbol)。 作用域 在静态类型编程语言中,变量在使用之前必须声明,声明提供了变量的类型。 如:int a。 char c。 通常,声明只在它的作用域内有效。 函数作用域:每个变量在函数内部定义。 块作用域:变量只在代码块内有效。 float foo(int a, float b) { int c。 // c 为局部作用域中变量。 { int b = 100。 // 块作用域中定义的 b 将参数 b 覆盖。 c = a + b。 // 将参数 a 的值与新定义的 b 值之和赋值给 c。 } return float(c) / b // 此处的 b 为参数 b。 } 为防止引用变量产生冲突,须为每个作用域设置一个符号表。 前端 词法分析器 语法分析器 中间代码生成器 符号表 基于 GUI 的交互式编译系统之中间代码生成器的设计与实现 16 局部变量名的存储布局 从变量类型可以知道该变量在运行时刻需要的内存数量。 在编译时刻,可以使用这些数量为每个名字分配一个相对地址。 名字的类型和相对地址信息保存在相应的符号表条目中 [12]。 数据对象的存储布局受目标机器的寻址约束的影响。 比如,将整数相加的指令往往希望整数能够对齐( aligned),也就是说,希望它们被放在内存中特定的位置上,比如地址能够被 4 整除的位置上。 类型的宽度( width)是指该类型的一个对象所需的存储单元的数量。 一般情况下,字符类型( char)占用一个字节,整型( int)占用 4 个字节。 可以使用一个变量,比如 offset,来跟踪下一个可用的相对地址。 在考虑第一个声明之前, offset 被设置为 0。 每处理一个变量 x 时, x 被加入符号表,它的相对地址被设置为 offset 的当前值,随后, x 类型的宽度被加到 offset 上。 基于 GUI 的交互式编译系统之中间代码生成器的设计与实现 17 3 设计与实现 C 子语言 本设计将一个用 C 子语言编写的源程序翻译成中间代码,该C子语言描述如下: 数据类型 该 子语言支持两种数据类型: int: 32 位有符号整型。 char: 8 位无符号整型。 只支持静态数组。 如果 传递一个数组给函数,数组将会以指针形式传递,所以对于数组的任何更改,将会影响调用函数传 递的数组。 另外,如果超过了数组的长度,调用函数的栈结构将会被破坏。 每个作用域中的局部变量应该在该作用域块的开始即任何其他语句之前进行声明,就像以前的 C98 标准那样。 字面值 整型,如: 2343, 123 字符串, 如:“ Hi, my name is XiKangjie\n” 字符, 如: ’a’, ‘\n’ 表达式 表达式中只支持以下运算符: +, ,后缀 ++和 , *, /, %, , =, , =, ==, ||, amp。 amp。 布尔表达式中不支持短路代码。 在短路代码中,布尔运算符 amp。 amp。 、 ||和。 被翻译成跳转指令。 运算符本身不出现在代码中,布尔表达式的值是通过代码序列中的位置来表示的。 基于 GUI 的交互式编译系统之中间代码生成器的设计与实现 18 语句 ifelse 语句 switch 语句 while 语句 dowhile 语句 for 语句 break 和 continue 语句 函数 有几个内建的函数用来基本的输入输出,它们是: printStr(char str[])。 printStr(string)。 在标准输出中打印一个以 null 结尾的字符串。 printChar(char c)。 printInt(int n)。 readStr(char buffer[], int bufferSize)。 readInt(int n) 这些函数会调用标准 C 输入输出函数,如 printf 和 scanf,另外,这些函数名被视为关键字,所以它们是该语言语法的一部 分。 可以自定义函数。 但是,需要知道这里不支持函数的前向声明 : int f(int x)。 所以应该注意定义函数的顺序,当 定义了很多相互调用的函数 ,会使程序变得复杂。 另外,本子语言 尽可能合理地去实现作用域,局部变量的作用域和生存周期就像 C语言那样,但是没有全局作用域 ,也就是说不能定义全局变量。 可是,在函数内部, 可以自由嵌套作用域。 比如: void foo() { int x, y。 // 嵌套块,产生一个新的内部作用域。 { 基于 GUI 的交互式编译系统之中间代码生成器的设计与实现 19 int x。 // 嵌套作用域中的定义的 x,它会将外部作用域中 x 覆盖。 if (true) { int x。 // if 块中定义的变量 x, 它会将外部作用域中 x 覆盖。 } } } 在这个子语言中有很 多的限制,比如没有类型检测,只有少量的语义分析等等。 所以在此 不是创建一种新的语言,而是以此子语言为例编写一个编译器前端。 符号表 一个符号表必须允许添加新项,查找已存在项,支持在编译期间动态增长符号表。 符号表可以实现为线性表和哈希表,线性表虽然容易实现,但表很大时性能会很差,所以本设计采用哈希表。 本设计的符号表由类 SymbolTable 实现,其内部存储结构由哈希表实现(这里使用标准容器 unordered_map), KEY 代表词素( lexeme), VALUE 代表与该词素对应的符号( Symbol)。 符号由类 Symbol 实现。 由于作用域可以嵌套,同时又要为每个作用域创建一个符号表,所以在类SymbolTable 中,容器 inner_scopes_存储嵌套的内部作用域,容器中的每个元素为指向内部作用域符号表的指针。 指针 outer_scope_指向外部作用域符号表。 在创建一个符号表时,要为其传递外部作用域符号表参数,若当前创建的符号表为根符号表,则默认为其传递参数 NULL。 在符号表中插入新项有两种方式。 一是插入 Symbol,二是插入词素和词法单元标记。 通过词素获取相应的符号,由重载运算符 []实现。 class SymbolTable { public: SymbolTable(SymbolTable* prev = NULL。基于gui的交互式编译系统之中间代码生成器的设计与实现毕业论文(编辑修改稿)
相关推荐
泄漏的区域,当煤气或者其他煤气泄漏的时候,空气中气体浓度超过设定值时,装置会发出灯光及声音的报警。 感器需要在加热状态下工作,温度越高,反应越快,响应时间和恢复时间就越快。 为提高响应时间,保证传感器准确地、稳定地工作,需要向气体传感器持续供给 5V 的加热电压。 气体报警器能实时范围检测工作,当烟雾的浓度达到设定的浓度时,发出声光报警。 如果是电磁阀泄漏,还可以添加自动断阀装置。
CPU T0 T2 INT0 INT1 并行I/O接口 串行I/O接口 存储器 P0~P3 T1 TXD 基于 GSM短消息的远程门禁系统设计与实现 8 用到了 ( RXD), ( TXD)位的第二功能,并通过 , 与 GSM模块 TC35i,单片机与 PC机之间的信息传递。 STC89C52RC各引脚对应的第二功能如下图所示: 表 3 STC89C52RC引脚对应第二功能 引脚 第二功能
gate 协议,代理提供了相关的生命周期方法来处理应用程序的系统事件 [9]。 ( 3) UIWindow UIWindow 是一种特殊的 UIView,通常在一个 app 中只会有一个 UIWindow ,但可以手动创建多个 UIWindow[10]。 UIWindow 的主要作用是 提 供 一 个 区 域 来 显 示 视 图 ; 将 事 件 分 发 给 视 图 控 制 器 ;
源模块选定与论证 方案一:工频电源 此电源供电效率较高,转换率在 80%左右,原理是利用变压器将 220V 用户交流电压降压,经过整流桥整流变为直流电,再电容滤波和 L7805 稳压器稳压,最后输出直流 5V 电压,供单片机系统工作。 该方案电气隔离性较好,电路容易,传统可靠,但是形状较大,占用空间位置。 5 方案二:阻容电源 该电源方式适用一些工作电流小的场合,如:液晶显示。
政府的关注、企业的参与等等,都注定了牛奶必定成为一种社会的热点现象。 西安工程大学本科毕业设计(论 文) 5 卫生质量问题 ( 1) 牛奶营养丰富,因而也是细菌繁殖的良好培养基,从原料奶到加工、贮运、销售各个环节稍有不慎,就可能给微生物的生长创造机会,导致卫生问题。 ( 2) 为追求利润,个别不法养牛户参假、制假行为时有发生,更有甚者参入尿素、化肥等物质,情节比较 恶劣
组交换技术,资源 可以被充分 的利用,数据传输速率 最 高 可 达 到。 GPRS技术采用实时 数据分组发送和接收, 可以使 用户永远在线 并 且按 照流量的大小收取费用 , 在不传送数据的时候不会收取费用,这就在很大程度上 降低了 用户的 服务成本。 选择 GPRS 的优势 选择 一个 合适的传输 方案 是 决定 系统运行稳定 性和 经济性的重要 指标。