1、专 业 : 计 算 机 科 学 与 技 术学 号 : 14101103姓 名 : 傅 开 煤2016 年 11 月编译原理实验报告1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 1 -前 言“编 译 原 理 ”是 一 门 研 究 设 计 和 构 造 编 译 程 序 原 理 和 方 法 的 课 程 , 是 计 算 机 各 专 业 的 一 门重 要 专 业 基 础 课 。 编 译 原 理 这 门 课 程 蕴 含 着 计 算 机 学 科 中 解 决 问 题 的 思 路 、 形 式 化 问 题 和 解决 问 题 的 方 法 , 对 应 用 软 件 和 系 统 软 件
2、的 设 计 与 开 发 有 一 定 的 启 发 和 指 导 作 用 。 编 译 程 序 构造 的 原 理 和 技 术 在 软 件 工 程 、 逆 向 工 程 、 软 件 再 工 程 、 语 言 转 换 及 其 他 领 域 中 都 有 着 广 泛 的应 用 。通 过 本 课 程 的 实 验 教 学 , 使 学 生 加 深 对 编 译 系 统 的 结 构 、 工 作 流 程 及 编 译 程 序 各 组 成部 分 设 计 原 理 的 理 解 , 使 他 们 能 够 掌 握 和 应 用 常 用 的 编 译 技 术 和 方 法 , 为 今 后 从 事 应 用 软 件和 系 统 软 件 的 开 发 打 下
3、 一 定 的 理 论 和 实 践 基 础 。编 译 原 理 实 验 指 导 书 围 绕 着 实 验 教 学 目 标 , 详 细 阐 述 了 各 实 验 的 原 理 和 步 骤 。 希 望 同学 们 能 够 充 分 利 用 实 验 条 件 , 认 真 完 成 实 验 , 从 实 验 中 得 到 应 有 的 锻 炼 和 培 养 。1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 2 -实 验 要 求为 了 顺 利 完 成 编 译 原 理 课 程 实 验 , 学 生 应 做 到 :( 1) 熟 练 掌 握 一 种 高 级 程 序 设 计 语 言 。( 2) 实 验 前
4、 , 认 真 学 习 教 材 以 及 实 验 指 导 书 的 相 关 内 容 , 提 前 做 好 实 验 准 备 。( 3) 每 次 实 验 先 分 析 后 编 程 , 在 实 验 报 告 中 应 写 明 自 己 的 编 程 思 路 和 设 计 流 程 。( 4) 实 验 结 束 一 周 后 提 交 实 验 报 告 。 实 验 报 告 内 容 应 包 括 : 实 验 目 的 、 实 验 内 容 、 设 计思 路 和 流 程 框 图 , 源 程 序 ( 含 注 释 ) 清 单 、 测 试 结 果 以 及 实 验 总 结 。( 5) 遵 守 机 房 纪 律 , 服 从 辅 导 教 师 指 挥 ,
5、爱 护 实 验 设 备 。实 验 的 验 收 将 分 为 两 个 部 分 。 第 一 部 分 是 上 机 操 作 , 随 机 抽 查 程 序 运 行 和 即 时 提 问 ;第 二 部 分 是 提 交 书 面 的 实 验 报 告 。 此 外 杜 绝 抄 袭 现 象 , 一 经 发 现 雷 同 , 双 方 成 绩 均 以 0分 计算 。1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 3 -目 录实 验 一 词 法 分 析 程 序 设 计 1实 验 二 递 归 下 降 语 法 分 析 程 序 设 计 51 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理
6、实 验 报 告- 1 -实 验 1 词 法 分 析 程 序 设 计【 开 发 语 言 及 实 现 平 台 或 实 验 环 境 】C/C+/C#Microsoft Visual Studio 6 .0 / Microsoft Visual Studio .NET 2 0 0 5 -2 0 0 8【 实 验 目 的 】( 1 ) 理 解 词 法 分 析 在 编 译 程 序 中 的 作 用( 2 ) 加 深 对 有 穷 自 动 机 模 型 的 理 解( 3 ) 掌 握 词 法 分 析 程 序 的 实 现 方 法 和 技 术【 实 验 内 容 】对 一 个 简 单 语 言 的 子 集 编 制 一 个
7、一 遍 扫 描 的 词 法 分 析 程 序 。【 实 验 要 求 】( 1) 待 分 析 的 简 单 语 言 的 词 法1) 关 键 字begin if then while do end2) 运 算 符 和 界 符:= + - * / = = 24digitdigit* 11 = 25+ 13 ; 26- 14 ( 271 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 2 -* 15 ) 28/ 16 # 0( 3) 词 法 分 析 程 序 的 功 能输 入 : 所 给 文 法 的 源 程 序 字 符 串输 出 : 二 元 组 ( syn,token 或 su
8、m) 构 成 的 序 列 。syn为 单 词 种 别 码 ;token为 存 放 的 单 词 自 身 字 符 串 ;sum为 整 形 常 数 。例 如 : 对 源 程 序 begin x:=9;if x0 then x:=2*x+1/3;end# 经 词 法 分 析 后 输 出 如 下 序列 : ( 1, begin) (10,x) (18,:=) (11,9) (26,;) (2,if)【 实 验 步 骤 】( 1 ) 根 据 图 1 .1 构 建 主 程 序 框 架图 1 .1 词 法 分 析 主 程 序 示 意 图主 代 码 :void main() p=0;row=1;cout=a /
9、错 误else switch(ch)/其 他 字 符 情 况case) syn=21;tokenm+=ch;else if(ch=) syn=22;tokenm+=ch;elsesyn=23;p-;break;case:m=0;tokenm+=ch;1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 5 -ch=progp+;if(ch=) syn=24;tokenm+=ch;else syn=20;p-;break;case:m=0;tokenm+=ch;ch=progp+;if(ch=) syn=18;tokenm+=ch;else syn=17;p-;bre
10、ak;case*:syn=13;token0=ch;break;case/:syn=14;token0=ch;break;case+:syn=15;token0=ch;break;case-:syn=16;token0=ch;break;case=:syn=25;token0=ch;break;case;:syn=26;token0=ch;break;case(:syn=27;token0=ch;break;case):syn=28;token0=ch;break;case#:syn=0;token0=ch;break;casen:syn=-2;break;default: syn=-1;br
11、eak;( 4 ) 调 试 程 序 , 验 证 输 出 结 果 。源 程 序 代 码 如 下 :#include1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 6 -#include#includeusing namespace std;char prog80, token8, ch;int syn, p, m, n, sum, row;char *rwtab6 = “begin“,“if“,“then“,“while“,“do“,“end“ ;void main() p = 0;row = 1;cout = a /错 误else switch (ch)/其
12、他 字 符 情 况case) syn = 21;tokenm+ = ch;else if (ch = =) syn = 22;tokenm+ = ch;1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 8 -else syn = 23;p-;break;case:m = 0; tokenm+ = ch;ch = progp+;if (ch = =) syn = 24;tokenm+ = ch;else syn = 20;p-;break;case:m = 0; tokenm+ = ch;ch = progp+;if (ch = =) syn = 18;token
13、m+ = ch;else syn = 17;p-;break;case*:syn = 13; token0 = ch; break;case/:syn = 14; token0 = ch; break;case+:syn = 15; token0 = ch; break;case-:syn = 16; token0 = ch; break;case=:syn = 25; token0 = ch; break;case;:syn = 26; token0 = ch; break;case(:syn = 27; token0 = ch; break;case):syn = 28; token0 =
14、 ch; break;case#:syn = 0; token0 = ch; break;casen:syn = -2; break;default: syn = -1; break;1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 9 -源 程 序 代 码 运 行 结 果 截 图 如 下 :【 思 考 题 】( 1 ) 在 编 程 过 程 中 遇 到 了 哪 些 问 题 , 你 是 如 何 解 决 的 。答 : 1) 在 “ 读 下 一 个 字 符 “ 的 时 候 遇 到 少 读 或 多 读 一 个 字 符 的 情 况 。解 决 :通 过 多 次 调 试 将
15、读 字 符 的 每 种 情 况 都 考 虑 。2) 当 输 入 数 字 开 头 的 字 符 串 时 , 需 要 报 错 。解 决 : 在 主 函 数 里 面 对 输 入 的 第 一 个 字 符 进 行 判 断 , 是 否 为 数 字 , 若 为 数 字 , 输 出 error。3) 输 入 内 容 时 计 算 机 是 从 键 盘 缓 冲 区 里 读 内 容 的 , 在 多 次 输 入 中 导 致 数 据 读 取 错 误 。解 决 : 在 输 入 前 用 rewind函 数 清 除 键 盘 缓 冲 区 的 内 容 , 再 输 入 即 可 。( 2 ) 源 程 序 若 存 在 注 释 , 如 何
16、实 现 词 法 分 析 , 在 现 有 程 序 基 础 上 进 行 扩 充 。【 实 验 总 结 】1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 1 0 -通 过 本 次 实 验 让 我 了 解 了 编 译 原 理 如 何 设 计 、 编 制 并 调 试 词 法 分 析 程 序 , 并 加 深 了 我 对词 法 分 析 器 原 理 的 理 解 ; 熟 悉 了 直 接 构 造 词 法 分 析 器 的 方 法 和 相 关 原 理 , 并 学 会 使 用 C/C+语 言 直 接 编 写 词 法 分 析 器 ; 同 时 更 熟 练 的 掌 握 用 C/C+语 言 编
17、 写 程 序 , 实 现 一 定 的 实 际 功 能 。【 参 考 文 献 】1. 胡 伦 骏 、 徐 兰 芳 等 , 编 译 原 理 ( 第 2 版 ) , 电 子 工 业 出 版 社 , 246, 2005.72. 王 雷 、 刘 志 成 等 , 编 译 原 理 课 程 设 计 , 机 械 工 业 出 版 社 , 138, 2005.31 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 1 1 -实 验 2 递 归 下 降 语 法 分 析 程 序 设 计【 开 发 语 言 及 实 现 平 台 或 实 验 环 境 】C/C+/C#Microsoft Visual
18、 Studio 6 .0 / Microsoft Visual Studio .NET 2 0 0 5 -2 0 0 8【 实 验 目 的 】( 1) 理 解 语 法 分 析 在 编 译 程 序 中 的 作 用 , 以 及 它 与 词 法 分 析 程 序 的 关 系( 2) 加 深 对 递 归 下 降 语 法 分 析 原 理 的 理 解( 3) 掌 握 递 归 下 降 语 法 分 析 的 实 现 方 法【 实 验 内 容 】编 制 一 个 递 归 下 降 分 析 程 序 , 实 现 对 词 法 分 析 程 序 提 供 的 单 词 序 列 的 语 法 检 查 和 结 构 分 析 。【 实 验 要
19、 求 】( 1) 待 分 析 的 简 单 语 言 的 词 法 同 实 验 1( 2) 待 分 析 的 简 单 语 言 的 语 法用 扩 充 的 BNF表 示 如 下 :1) : : =beginend2) : : =; 3) : : =4) :=ID:=5) : : =+|-6) :=*|/7) :=ID|NUM|()( 3) 语 法 分 析 程 序 的 功 能输 入 单 词 串 以 ”#”结 束 , 如 果 是 文 法 正 确 的 句 子 , 输 出 成 功 信 息 ; 否 则 输 出 错 误 信 息 。例 如 :输 入 begin a:=9; x:=2 * 3; b:=a + x end
20、#输 出 success输 入 x:=a + b * c end #输 出 error【 实 验 步 骤 】1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 1 2 -( 1 ) 根 据 图 2 .1 递 归 下 降 分 析 程 序 示 意 图 构 建 主 程 序 框 架图 2 .1 递 归 下 降 分 析 程 序 示 意 图( 2 ) 编 写 各 语 法 单 位 分 析 函 数1 ) 编 写 语 句 串 及 语 句 分 析 函 数int yucu() /语 句 串 分 析 函 数 statement();while (syn = 26) scanner();
21、/读 下 一 个 单 词 符 号statement(); /调 用 statement 函 数return 0;int statement() if (syn = 10) scanner(); /读 下 一 个 单 词 符 号if (syn = 18) scanner(); /读 下 一 个 单 词 符 号expression();else置 初 值调 用 scaner 读 下 一 个 单 词 符 号调 用 lrparser结 束1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 1 3 -cout #include#includeusing namespace
22、std;char prog80, token8;char ch;int syn, p, m, n, sum, kk;char *rwtab6 = “begin“, “if“, “then“, “while“, “do“, “end“ ;int scanner(); /调 用 scanner函 数int lrparscr(); /调 用 lrparscr函 数int yucu(); /调 用 yucu函 数int statement(); /调 用 statement 函 数int expression(); /调 用 expression函 数int term(); /调 用 term函 数i
23、nt factor(); /调 用 factor函 数void main() p = 0;1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 1 5 -cout = a /出 现 错 误else switch (ch) /其 他 字 符 时case) syn = 21; /不 等 于tokenm+ = ch;else if (ch = =) syn = 22; /小 于 等 于tokenm+ = ch;else syn = 23; /大 于p-; /回 退 一 个 字 符1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 1 9 -b
24、reak;case:m = 0; tokenm+ = ch;ch = progp+; /读 下 一 个 单 词 符 号 并 赋 给 chif (ch = =) syn = 24; /大 于 等 于tokenm+ = ch;else syn = 20; /小 于p-; /回 退 一 个 字 符break;case:m = 0; tokenm+ = ch;ch = progp+; /读 下 一 个 单 词 符 号 并 赋 给 chif (ch = =) syn = 18; /等 于tokenm+ = ch;else syn = 17; /冒 号 :p-;break;case+:syn = 13;
25、token0 = ch; break;case-:syn = 14; token0 = ch; break;case*:syn = 15; token0 = ch; break;case/:syn = 16; token0 = ch; break;case=:syn = 25; token0 = ch; break;case;:syn = 26; token0 = ch; break;case(:syn = 27; token0 = ch; break;case):syn = 28; token0 = ch; break;case#:syn = 0; token0 = ch; break;ca
26、sen:syn = -2; break;default: syn = -1; break;return syn;源 程 序 代 码 运 行 结 果 截 图 如 下 :1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 2 0 -【 思 考 题 】( 1) 你 所 编 制 的 程 序 与 实 验 1 程 序 有 何 联 系 , 如 何 应 用 实 验 1。1 4 1 0 1 1 0 3 -傅 开 煤 -编 译 原 理 实 验 报 告- 2 1 -答 : 语 法 分 析 程 序 用 到 了 词 法 分 析 程 序 中 的 scanner函 数 ( 词 法 扫 描 程
27、序 ) , 并 将 其 作为 其 中 一 个 模 块 , 与 其 它 函 数 共 同 完 成 语 法 分 析 任 务 , 语 法 分 析 程 序 以 词 法 分 析 程 序 提 供 的单 词 序 列 为 来 源 , 并 对 其 进 行 语 法 检 查 和 结 构 分 析 。 编 译 程 序 对 源 程 序 字 符 串 要 先 进 行 词 法分 析 , 然 后 进 行 语 法 分 析 、 语 义 分 析 等 后 续 工 作 。( 2) 将 源 程 序 放 置 在 文 本 文 件 中 , 运 用 流 操 作 实 现 对 源 程 序 的 扫 描 和 分 解 , 编 程 实 现 。【 实 验 总 结
28、】通 过 本 次 实 验 , 使 我 掌 握 编 译 原 理 自 上 而 下 语 法 分 析 的 要 求 与 特 点 , 也 更 加 了 解 递 归 下降 语 法 分 析 的 基 本 原 理 和 方 法 并 学 会 相 应 数 据 结 构 的 设 计 方 法 。 递 归 下 降 分 析 法 简 单 、 直 观 ,易 于 构 造 程 序 , 但 它 对 文 法 要 求 较 高 , 必 须 是 LL 文 法 , 同 时 递 归 调 用 较 多 , 在 编 程 的 时 候要 特 别 注 意 , 函 数 的 顺 序 不 能 打 乱 , 函 数 声 明 要 位 置 明 确 , 不 能 乱 , 掌 握 一
29、 定 的 规 律 , 使 程序 有 条 理 。 在 实 验 中 也 出 现 了 一 些 错 误 和 碰 到 了 一 些 难 题 , 不 过 在 同 学 的 帮 助 下 基 本 上 都 解决 了 。 在 刚 开 始 的 设 计 分 析 思 路 和 程 序 设 计 中 , 也 遇 到 过 一 些 问 题 , 一 般 的 情 况 是 对 所 学 的知 识 还 没 有 完 全 掌 握 好 , 没 有 透 彻 理 解 , 对 所 学 知 识 不 能 够 灵 活 运 用 , 在 课 后 需 要 多 巩 固 。在 以 后 的 日 子 里 , 需 要 学 习 的 还 有 很 多 , 不 能 懈 怠 。【 参 考 文 献 】1 胡 伦 骏 、 徐 兰 芳 等 , 编 译 原 理 ( 第 2 版 ) , 电 子 工 业 出 版 社 , 246, 2005.72 王 雷 、 刘 志 成 等 , 编 译 原 理 课 程 设 计 , 机 械 工 业 出 版 社 , 138, 2005.3