当前位置:文档之家› 北京工业大学 编译原理 实验报告

北京工业大学 编译原理 实验报告

北京工业大学 编译原理  实验报告
北京工业大学 编译原理  实验报告

计算机学院实验报告

课程名称:编译原理

实验人学号:110703xx 姓名:xxx 实验完成日期:2014年5月20日报告完成日期:2014年5月20日

目录

实验一词法分析程序的设计与实现 (3)

词法的正规式描述: (3)

状态图: (4)

词法分析程序数据结构与算法: (4)

词法分析算法: (5)

实验结果: (7)

实验中遇到的问题及其解决: (8)

1、保留字的检测问题: (8)

2、关于0为首位的数字是int8、int10和int16的判断问题: (8)

3、关于回退的问题: (8)

实验二自顶向下的语法分析—递归子程序法 (9)

改写后的产生式集合: (9)

化简后的语法图: (9)

递归子程序算法 (10)

实验结果: (13)

实验中遇到的问题及其解决: (14)

1、消除左递归,提取左因子之后的E、T对应的子程序的编写问题: (14)

2、缩进的控制: (14)

实验三语法制导的三地址代码生成程序 (15)

语法制导定义: (15)

三地址代码生成器的数据结构 (16)

三地址生成器算法: (17)

实验结果: (21)

实验中遇到的问题及其解决: (22)

1、根据化简后的产生式修改语法制导定义: (22)

2、使用真假出口法和继承属性来确定goto的标号: (22)

实验一词法分析程序的设计与实现

词法的正规式描述:

标识符 <字母>(<字母>|<数字字符>)*

十进制整数 0|(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*

八进制整数 0(0|1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*

十六进制整数

0(x|X)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e |f)*

运算符和分隔符 + - * / > < = ( ) ;

关键字 if then else while do .

状态图:

开始

标识符或保留

a-z/A-Z

Int8或int10或

int16

十进制数

1-9

保留字

标识符

其他

运算符和分隔

If/then/while/do/else + - * / > < = ( ) ;

Int 16

X/x int8

1-7

int10

其他

词法分析程序数据结构与算法:

//单词类 class Token { public :

int type;//种别 string value;//属性值 string name;//单词具体内容 Token() {

type = DEFAULT;

value = NONE_OF_VALUE; }

Token(int type, string value, string name): type(type), value(value), name (name){}

~Token() {}

};

词法分析算法:

Token* TokenScan(ifstream &from_file) {

char ch;//用于保存从文件中读取的字符

//读第一个字符

int i =0;

char value[30] ="";//用来存放token的属性值

ch = from_file.get();

while (ch == BLANK || ch == TAB || ch == NEWLINE) {

ch = from_file.get();

}

////////////////////////////////////以下为标识符的检测//////////////////////////////////////////////////////////////////////////// if (isalpha(ch)) {

value[i++] = ch;

ch = from_file.get();

////判断后续的是否为IDN的成分(数字或字母)

while (isalnum(ch)) {

value[i++] = ch;

ch = from_file.get();

}

//直到不是IDN成分,回退一字符

from_file.unget();

//TODO:这里加上保留字检测部分

//进行字符串的对比,即可比较出保留字,通过压栈的形式来获得完整的属性值

////////////////////////////////////以下为保留字的检测//////////////////////////////////////////////////////////////////////////// if (strcmp(value, WORD_IF) ==0) return new Token(IF, NONE_OF_VALUE, WO RD_IF);

if (strcmp(value, WORD_THEN) ==0) return new Token(THEN, NONE_OF_VALUE, WORD_THEN);

if (strcmp(value, WORD_ELSE) ==0) return new Token(ELSE, NONE_OF_VALUE, WORD_ELSE);

if (strcmp(value, WORD_WHILE) ==0) return new Token(WHILE, NONE_OF_VALU E, WORD_WHILE);

if (strcmp(value, WORD_DO) ==0) return new Token(DO, NONE_OF_VALUE, WO RD_DO);

return new Token(IDN, value, value);

}

////////////////////////////////////以下为数字的检测

//////////////////////////////////////////////////////////////////////////// if (isdigit(ch)) {

value[i++] = ch;

//如果第一个数字是0,则有可能是INT10的0、INT8或INT16

if (ch =='0') {

ch = from_file.get();

if ((ch >='0'&& ch <'8') || ch =='x'|| ch =='X') {

//如果0后面紧跟着数字0-8,则为INT8

if (isdigit(ch)) {

while (ch >='0'&& ch <'8') {

value[i++] = ch;

ch = from_file.get();

}

from_file.unget();

return new Token(INT8, value, value);

}

value[i++] = ch;

//到这一步的都是INT16

ch = from_file.get();

while (isdigit(ch) || (ch >='a'&& ch <='f')) {

value[i++] = ch;

//TODO:这里没有解决0xrtr的问题

ch = from_file.get();

}

from_file.unget();

return new Token(INT16, value, value);

} else {//0后面的不为0-7的digit或x或X等 8或16进制特征字符,则为10进制的0,回退一个字符

from_file.unget();

return new Token(INT10, value, value);

}

}

//能到这一步的都是INT10,且不为0打头

ch = from_file.get();

while (isdigit(ch)) {

value[i++] = ch;

ch = from_file.get();

}

from_file.unget();

return new Token(INT10, value, value);

}

////////////////////////////////////以下为运算符的检测//////////////////////////////////////////////////////////////////////////// value[i++] = ch;

switch (ch) {

case'+':return new Token(ADD, value, "+");

case'-':return new Token(MINUS, value, "-");

case'*':return new Token(MUL, value, "*");

case'/':return new Token(DIC, value, "/");

case'>':return new Token(MORE, value, ">");

case'<':return new Token(LESS, value, "<");

case'=':return new Token(EQU, value, "=");

case'(':return new Token(LBRAC,value, "(");

case')':return new Token(RBRAC, value, ")");

case';':return new Token(COMMA, value, ";");

default:ErrorHandle(from_file); break;

}

return new Token(DEFAULT, NONE_OF_VALUE, NONE_OF_VALUE); }

实验结果:

实验中遇到的问题及其解决:

1、保留字的检测问题:

一开始的时候我的想法是遇到if、while、do、then等单词的首字母时即开始划分状态,后来发现这样子判断的分支会特别多,而且效率不是很高,对保留字集合的扩展支持的也不是很好。后来我发现保留字存在于标识符的子集,所以为什么不先判断标识符然后再判断是不是保留字呢?后来我就照着这个思路成功实现了功能。

2、关于0为首位的数字是int8、int10和int16的判断问题:

当读入的第一个字符为0时,可能为int8、可能是int10的0也可能是int16的开头,当下一个字符是0~7时,开始进行int8的匹配;当下一个字符是x或X时,开始进行int16的匹配;当下一个字符为其他字符时,说明这是一个十进制的0(此时还需进行一字节的回退)

3、关于回退的问题:

有些时候需要进行回退,否则不能正常的进行完整个分析过程,需要进行回退的场合为:

(1)匹配标识符(或保留字时),向后逐字读取的时候当下一个不是字母或数字的时候需要

将读取的字符回退,才能继续向下进行;

(2)判断为int10的0的时候需要一步回退:

else {//0后面的不为0-7的digit或x或X等 8或16进制特征字符,则为10进制的0,回退一个字符

from_file.unget();

return new Token(INT10, value, value);

}

(3)判断数字的时候到最后一个不为数字的都需要回退。

实验二自顶向下的语法分析—递归子程

序法

改写后的产生式集合:

S -> id = E;

S -> if C then S;

S -> while C do S;

C -> E > E;

C -> E <= E;

E -> T (+ T) *;

E -> T (- T) *;

T -> F (* F) *;

T -> F (/ F) *;

F -> (E);

F -> id;

F -> int8;

F -> int10;

F -> int16;

化简后的语法图:

T

T

F

F

递归子程序算法

int ProcedureS(ifstream& from_file) {

Indent();

cout<<"S"<

indentation +=4;//子程序开始

Indent();

Token* token = TokenScan(from_file);

if (token->type == IF) {

cout<name<

ProcedureC(from_file);

token = TokenScan(from_file);

Indent();

if (token->type == THEN) {

cout<name<

ProcedureS(from_file);

} else {

exit(-1);

}

} else if (token->type == WHILE) {

cout<name<

ProcedureC(from_file);

token = TokenScan(from_file);

Indent();

if (token->type == DO) {

cout<name<

ProcedureS(from_file);

} else {

exit(-1);

}

} else if (token->type == IDN) {

cout<<"id : "<name<

if (token->type == EQU) {

Indent();

cout<name<

ProcedureE(from_file);

} else {

exit(-1);

}

}

indentation -=4;//子程序结束

return0;

int ProcedureC(ifstream& from_file) {

Indent();

cout<<"C"<

indentation +=4;//子程序开始

Token* token;

ProcedureE(from_file);

token = TokenScan(from_file);

Indent();

if (token->type == MORE) {

cout<name<

ProcedureE(from_file);

} else if (token->type == LESS) {

cout<name<

ProcedureE(from_file);

} else {

exit(-1);

}

indentation -=4;//子程序结束

return0;

}

int ProcedureE(ifstream& from_file) {

Indent();

cout<<"E"<

indentation +=4;//子程序开始

Token* token;

ProcedureT(from_file);

while (true) {

token = TokenScan(from_file);

if (token->type == ADD) {

Indent();

cout<name<

ProcedureT(from_file);

} else if (token->type == MINUS) {

Indent();

cout<name<

ProcedureT(from_file);

} else {

for (int i =0; i < (int)token->name.length(); i++) { from_file.unget();//回退

}

indentation -=4;//子程序结束

return0;

}

indentation -=4;//子程序结束

return0;

}

int ProcedureT(ifstream& from_file) {

Indent();

cout<<"T"<

indentation +=4;//子程序开始

Token* token;

ProcedureF(from_file);

while (true) {

token = TokenScan(from_file);

if (token->type == MUL) {

Indent();

cout<name<

ProcedureF(from_file);

} else if (token->type == DIC) {

Indent();

cout<name<

ProcedureF(from_file);

} else {

for (int i =0; i < (int)token->name.length(); i++) { from_file.unget();//回退

}

indentation -=4;//子程序结束

return0;

}

}

indentation -=4;//子程序结束

return0;

}int ProcedureF(ifstream& from_file) {

Indent();

cout<<"F"<

indentation +=4;//子程序开始

Token* token;

token = TokenScan(from_file);

if (token->type == LBRAC) {

cout<name<

ProcedureE(from_file);

token = TokenScan(from_file);

cout<name<

}

Indent();

if (token->type == IDN) {

cout<<"id : "<name<

}

if (token->type == INT8) {

cout<<"int8 : "<value)<

}

if (token->type == INT10) {

cout<<"int10 : "<value<

}

if (token->type == INT16) {

cout<<"int16 : "<value)<

indentation -=4;//子程序结束

return0;

}

实验结果:

实验中遇到的问题及其解决:

1、消除左递归,提取左因子之后的E、T对应的子程序的编写问题:

经过多次测试,我发现在一个expression超过两个运算符的时候我的E、T子程序就只能成功的分析出第一段的式子,后来发现E->T(+T)*类似的产生式没有写循环调用控制,后来在(+T)*的最外层加了一个while(true)循环,然后在while(true)的首行加入了不是‘+’就return的判定,成功解决了问题。

2、缩进的控制:

这个实验中碰到的第二个问题就是语法树缩进的控制问题,最终通过一个全局变量indentation来控制缩进的字符数量,一个Indent()函数来输出缩进(其实就是空格),控制缩进数量的关键点有两个:一为进入子程序的时候indentation+=4,二为结束子程序的时候indentation-=4。剩下的就是根据调试来选择在哪里输出缩进空格的问题了。

实验三语法制导的三地址代码生成程序语法制导定义:

三地址代码生成器的数据结构

typedef struct { /*S的属性定义*/ char code[CODESIZE];

int begin;

int next;

}AttrS;

typedef struct { /*E的属性定义*/ char code[CODESIZE];//CodeSize = 500

char place[BUFSIZE];//BufSize = 200

}AttrE;

typedef struct { /*C的属性定义*/ char code[CODESIZE];

int c_false;//用来标记入口

int c_true;//用来标记入口

}AttrC;

typedef struct { /*T的属性定义*/ char code[CODESIZE];//CodeSize = 500

char place[BUFSIZE];//BufSize = 200

}AttrT;

typedef struct { /*F的属性定义*/ char code[CODESIZE];//CodeSize = 500

char place[BUFSIZE];//BufSize = 200

}AttrF;

typedef struct { /*IDN的属性定义*/

char idname[BUFSIZE];

int entry;

}AttrIDN;

三地址生成器算法:

int ProcedureS(ifstream& from_file, AttrS &s) {

AttrC c;//C的属性

AttrS s1;//s1的属性

AttrE e;//e的属性

char temp_idn_name[50];//用来暂存当下一个是IDN时,s->id:=E 的 id的name

Token* token = TokenScan(from_file);

//////////////////////////////////////////s-> if C then S1///// ////////////////////////////////////////

if (token->type == IF) {

c.c_true = NewLabel();//c.c_true出口有了新标签

s1.begin = c.c_true;// C真则往 S1走

s1.next = c.c_false = s.next; // c假则走s的下一步为L0标签,在前面预置了

ProcedureC(from_file, c);

token = TokenScan(from_file);

if (token->type == THEN) {

ProcedureS(from_file, s1);

sprintf_s(s.code, "\n\t%s\nL%d:\t%s", c.code, c.c_true, s1. code);//将中间代码输出到s.code中

} else {

exit(-1);

}

//////////////////////////////////////////s-> while C do S1////// ///////////////////////////////////////

} else if (token->type == WHILE) {

s1.next = s.begin = NewLabel();

c.c_true = s1.begin = NewLabel();//C真则往 S1走

c.c_false = s.next;// c假则走s的下一步为L0标签,在前面预置了

ProcedureC(from_file, c);

token = TokenScan(from_file);

if (token->type == DO) {

ProcedureS(from_file, s1);

sprintf_s(s.code,"\nL%d:\t%s\nL%d:\t%s\n\tgoto L%d ",s.begi n,c.code,c.c_true,s1.code,s.begin);

} else {

exit(-1);

}

//////////////////////////////////////////s-> id := E//////// /////////////////////////////////////

} else if (token->type == IDN) {

strcpy_s(temp_idn_name, token->name.c_str());

token = TokenScan(from_file);

if (token->type == EQU) {

ProcedureE(from_file, e);

sprintf_s(s.code,"%s\n\t%s=%s",e.code, temp_idn_name, e.pla ce);

} else {

exit(-1);

}

}

return0;

}

int ProcedureC(ifstream& from_file, AttrC &c) {

AttrE e1;//e1的属性

AttrE e2;//e2的属性

Token* token;

ProcedureE(from_file, e1);

token = TokenScan(from_file);

if (token->type == MORE) {

ProcedureE(from_file, e2);

sprintf_s(c.code, "%s%s\n\tif %s>%s goto L%d\n\tgoto L%d",e1. code,e2.code,e1.place,e2.place,c.c_true,c.c_false);

} else if (token->type == LESS) {

ProcedureE(from_file, e2);

sprintf_s(c.code, "%s%s\n\tif %s<%s goto L%d\n\tgoto L%d",e1. code,e2.code,e1.place,e2.place,c.c_true,c.c_false);

} else {

exit(-1);

}

return0;

}

int ProcedureE(ifstream& from_file, AttrE &e) {

AttrT t1;

AttrT t2;

Token* token;

ProcedureT(from_file, t1);

while (true) {

token = TokenScan(from_file);

if (token->type == ADD) {

ProcedureT(from_file, t2);

strcpy_s(e.place,NewTemp());

sprintf_s(e.code,"%s%s\n\t%s=%s+%s",t1.code,t2.code, e.pl ace,t1.place,t2.place);

//这里是关键,用t1.code和t1.place临时记录了上一次while的e.code 和e.place,随着while的不断加深,t1的代码会不断长长

strcpy_s(t1.code,e.code);

strcpy_s(t1.place,e.place);

} else if (token->type == MINUS) {

ProcedureT(from_file, t2);

strcpy_s(e.place,NewTemp());

sprintf_s(e.code,"%s%s\n\t%s=%s-%s",t1.code,t2.code, e.pl ace,t1.place,t2.place);

strcpy_s(t1.code,e.code);

strcpy_s(t1.place,e.place);

} else {

for (int i =0; i < (int)token->name.length(); i++) {

from_file.unget();//回退

}

//////////////////////////////////////////E->T/////////////// //////////////////////////////

strcpy_s(e.place,t1.place);

sprintf_s(e.code,"%s",t1.code);

break;

}

}

return0;

}

int ProcedureT(ifstream& from_file, AttrT &t) {

AttrF f1;

AttrF f2;

Token* token;

ProcedureF(from_file ,f1);

while (true) {

token = TokenScan(from_file);

if (token->type == MUL) {

ProcedureF(from_file, f2);

strcpy_s(t.place,NewTemp());

sprintf_s(t.code,"%s%s\n\t%s=%s*%s",f1.code,f2.code,t.pla ce,f1.place,f2.place);

strcpy_s(f1.code,t.code);

strcpy_s(f1.place,t.place);

} else if (token->type == DIC) {

ProcedureF(from_file, f2);

strcpy_s(t.place,NewTemp());

sprintf_s(t.code,"%s%s\n\t%s=%s/%s",f1.code,f2.code,t.pla ce,f1.place,f2.place);

strcpy_s(f1.code,t.code);

strcpy_s(f1.place,t.place);

} else {

for (int i =0; i < (int)token->name.length(); i++) {

from_file.unget();//回退

}

strcpy_s(t.place,f1.place);

sprintf_s(t.code,"%s",f1.code);

break;

}

}

return0;

}

int ProcedureF(ifstream& from_file, AttrF &f) {

AttrE e;

Token* token;

char temp_value[50];

token = TokenScan(from_file);

if (token->type == LBRAC) {

ProcedureE(from_file, e);

strcpy_s(f.place,e.place);//f.place = e.place

sprintf_s(f.code,"%s",e.code);

token = TokenScan(from_file);//匹配右括号

}

if (token->type == IDN) {

strcpy_s(f.place,token->name.c_str());

sprintf_s(f.code,"\0");

}

if (token->type == INT8) {

sprintf_s(temp_value, "%d", ValueOfINT8(token->value));

strcpy_s(f.place, temp_value);

sprintf_s(f.code,"\0");

}

北京工业大学实验报告

北京工业大学实验报告

————————————————————————————————作者:————————————————————————————————日期: ?

BEIJINGUNIVERSITYOF TECHNOLOGY 实验报告 课程名称:计算机网络应用 学院:经济与管理学院 专业:管理科学与工程 组 11 号: 14110206 陈浩良报告 人: 14110213 郝楠 14110214 邓刘祥鹤 14110217 苏晗实验日期:2015年11 月30 日报告日期:2015年12月 5 日 学期:2015–2016学年第1学期成绩:评语:

教师签字: 评阅日期: ? 分工情况 实验一直通:苏晗、陈浩良 交叉:郝楠、邓刘翔鹤实验三苏晗、郝楠、陈浩良 实验四苏晗、陈浩良 实验五郝楠、陈浩良 试验六苏晗、郝楠

实验一 实验报告要求: 1.说明直通双绞线和交叉双绞线的使用场合 2.说明直通双绞线和交叉双绞线的构成 3.制作直通双绞线和交叉双绞线过程中遇到的问题和解决方法 1. 交叉线一般用来直接连两台电脑的,也就是网卡--网卡 直通线一般用来连接网络设备(比如路由器,交换机,HUB,ADSL 等)与电脑,或者是网络设备与网络设备(除非特殊说明,一般都支持)之间相联。 2. 直通线的双绞线做法是:两端双绞线都做成:橙白- 橙- 绿白 - 蓝- 蓝白-绿-棕白- 棕 3. 交叉线的做法是,网线的两端一边按橙白- 橙- 绿白- 蓝 -蓝白- 绿- 棕白- 棕做,另一端按绿白- 绿-橙白- 蓝-蓝白- 橙-棕白- 棕做 实验三 实验报告要求: 1.对比OSI模型,简述TCP/IP工作过程 2.描述IP地址、子网掩码的配置方法 3.说明在测试过程中使用了哪些网络命令及命令的意义

编译原理实验报告实验一编写词法分析程序

编译原理实验报告实验名称:实验一编写词法分析程序 实验类型:验证型实验 指导教师:何中胜 专业班级:13软件四 姓名:丁越 学号: 电子邮箱: 实验地点:秋白楼B720 实验成绩: 日期:2016年3 月18 日

一、实验目的 通过设计、调试词法分析程序,实现从源程序中分出各种单词的方法;熟悉词法分析 程序所用的工具自动机,进一步理解自动机理论。掌握文法转换成自动机的技术及有穷自动机实现的方法。确定词法分析器的输出形式及标识符与关键字的区分方法。加深对课堂教学的理解;提高词法分析方法的实践能力。通过本实验,应达到以下目标: 1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。 2、掌握词法分析的实现方法。 3、上机调试编出的词法分析程序。 二、实验过程 以编写PASCAL子集的词法分析程序为例 1.理论部分 (1)主程序设计考虑 主程序的说明部分为各种表格和变量安排空间。 数组 k为关键字表,每个数组元素存放一个关键字。采用定长的方式,较短的关键字 后面补空格。 P数组存放分界符。为了简单起见,分界符、算术运算符和关系运算符都放在 p表中 (编程时,还应建立算术运算符表和关系运算符表,并且各有类号),合并成一类。 id和ci数组分别存放标识符和常数。 instring数组为输入源程序的单词缓存。 outtoken记录为输出内部表示缓存。 还有一些为造表填表设置的变量。 主程序开始后,先以人工方式输入关键字,造 k表;再输入分界符等造p表。 主程序的工作部分设计成便于调试的循环结构。每个循环处理一个单词;接收键盘上 送来的一个单词;调用词法分析过程;输出每个单词的内部码。 ⑵词法分析过程考虑 将词法分析程序设计成独立一遍扫描源程序的结构。其流程图见图1-1。 图1-1 该过程取名为 lexical,它根据输入单词的第一个字符(有时还需读第二个字符),判断单词类,产生类号:以字符 k表示关键字;i表示标识符;c表示常数;p表示分界符;s表示运算符(编程时类号分别为 1,2,3,4,5)。 对于标识符和常数,需分别与标识符表和常数表中已登记的元素相比较,如表中已有 该元素,则记录其在表中的位置,如未出现过,将标识符按顺序填入数组id中,将常数 变为二进制形式存入数组中 ci中,并记录其在表中的位置。 lexical过程中嵌有两个小过程:一个名为getchar,其功能为从instring中按顺序取出一个字符,并将其指针pint加1;另一个名为error,当出现错误时,调用这个过程, 输出错误编号。 2.实践部分

编译原理实验报告

编译原理实验报告 姓名: 学号: 班级: 学院: 南昌大学信息工程学院计算机系 2014年6月

目录 实验一 (3) 实验二 (8) 实验三 (15)

实验1 词法分析程序的设计 学生姓名:学号:专业班级: 实验类型:□验证□综合□设计□创新实验日期:实验成绩: 一、实验目的 掌握计算机语言的词法分析程序的开发方法。 二、实验内容 编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。 三、实验要求 1、根据以下的正规式,编制正规文法,画出状态图; 标识符<字母>(<字母>|<数字字符>)* 十进制整数0 |(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)* 如有余力,则进一步分析八进制和十六进制整数,其正规式如下: 八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)* 十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)* 运算符和界符+ - * / > < =<= >=( ) ;{ } 关键字main if then else while do int (可根据需要添加) 2、根据状态图,设计词法分析函数int scan( ),完成以下功能: 1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词, 2)以二元式形式输出单词<单词种类,单词属性> 其中单词种类用整数表示: 0:标识符 1:十进制整数 2:八进制整数 3:十六进制整数 运算符和界符,关键字采用一字一符,不编码 其中单词属性表示如下: 标识符,整数由于采用一类一符,属性用单词表示 运算符和界符,关键字采用一字一符,属性为空 3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。 四、实验环境 PC微机 DOS操作系统或Windows 操作系统 Turbo C 程序集成环境或Visual C++ 程序集成环境

北京工业大学电子工程设计--二阶实验报告

电子工程设计第二阶段报告 小型温度测量与控制系统 专业:通信工程小组: 10组 成员:刘志斌 12024228 高培元 12024215 指导教师:高新 完成日期:2014.12.20

摘要: 第一阶段我们已经完成了电源板和变送器。本学期的第二阶段要求是完成这个系统中单片机,A/D,D/A转换电路和显示与键盘控制电路部分。 温度控制系统总体概述 (一)、总述 电子工程设计训练是一门综合理论知识,实践操作,电子电路系统的设计、实现、调试、故障排查等方面的综合性训练。第一阶段只完成了电源以及变送器部分。本阶段工作量非常大,需要完成单片机,数模,模数转换电路和显示与键盘控制电路部分,并且完成测温系统的测试。 (二)设计任务与要求 一、设计任务 设计、制作并调试单片机,数模,模数转换电路和显示电路共四个模块。二、设计要求 1.单片机:具有独立电路板结构。 片选信号:6个, 地址信号:4个, 数据总线:AD0~AD7, I/O口线:P3口,P1口。 2.数/模(D/A)转换电路:具有独立电路板结构。 输入范围:00H ~ 0FFH, 对应输出:-10V~+10V, 电源供电:+5V,±12V。 3.模/数(A/D)转换电路: 独立电路板结构 输入信号范围:0V~+5V 分辨率:8bit 精度:1LSB 转换时间:< 1ms 4.显示与键盘控制电路: 4 位7 段数码显示, 前 3 位含小数点独立电路板安装结构 0 ~ 9数字输入键及若干功能设置按键控制

(三)单片机应用电路 一、电路设计方案 1.芯片介绍 MCS-51系列单片机有众多性能优异的兼容产品、成熟的开发环境、世界上最大的单片机客户群、高性价比、畅通的供货渠道,是初学者的首选机型。8051是MCS-51系列单片机早期产品之一,内建一次性可编程只读存储器 ( PROM ) ,只需要很少的外围元件即可组成最小系统。所以我们选择8051作为我们的单片机 2.安装结构 3.电路方案的确定 通过比较,我们最后选定相对容易实现的部分地址译码,无总线驱动的方案,因为这样可以简化电路。电路图如下:

编译原理实验报告

编译原理实验报告 班级 姓名: 学号: 自我评定:

实验一词法分析程序实现 一、实验目的与要求 通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。 二、实验内容 根据教学要求并结合学生自己的兴趣和具体情况,从具有代表性的高级程序设计语言的各类典型单词中,选取一个适当大小的子集。例如,可以完成无符号常数这一类典型单词的识别后,再完成一个尽可能兼顾到各种常数、关键字、标识符和各种运算符的扫描器的设计和实现。 输入:由符合或不符合所规定的单词类别结构的各类单词组成的源程序。 输出:把单词的字符形式的表示翻译成编译器的内部表示,即确定单词串的输出形式。例如,所输出的每一单词均按形如(CLASS,VALUE)的二元式编码。对于变量和常数,CLASS字段为相应的类别码;VALUE字段则是该标识符、常数的具体值或在其符号表中登记项的序号(要求在变量名表登记项中存放该标识符的字符串;常数表登记项中则存放该常数的二进制形式)。对于关键字和运算符,采用一词一类的编码形式;由于采用一词一类的编码方式,所以仅需在二元式的CLASS字段上放置相应的单词的类别码,VALUE字段则为“空”。另外,为便于查看由词法分析程序所输出的单词串,要求在CLASS字段上放置单词类别的助记符。 三、实现方法与环境 词法分析是编译程序的第一个处理阶段,可以通过两种途径来构造词法分析程序。其一是根据对语言中各类单词的某种描述或定义(如BNF),用手工的方式(例如可用C语言)构造词法分析程序。一般地,可以根据文法或状态转换图构造相应的状态矩阵,该状态矩阵同控制程序便组成了编译器的词法分析程序;也可以根据文法或状态转换图直接编写词法分析程序。构造词法分析程序的另外一种途径是所谓的词法分析程序的自动生成,即首先用正规式对语言中的各类单词符号进行词型描述,并分别指出在识别单词时,词法分析程序所应进行的语义处理工作,然后由一个所谓词法分析程序的构造程序对上述信息进行加工。如美国BELL实验室研制的LEX就是一个被广泛使用的词法分析程序的自动生成工具。 总的来说,开发一种新语言时,由于它的单词符号在不停地修改,采用LEX等工具生成的词法分析程序比较易于修改和维护。一旦一种语言确定了,则采用手工编写词法分析程序效率更高。 四、实验设计 1)题目1:试用手工编码方式构造识别以下给定单词的某一语言的词法分析程序。 语言中具有的单词包括五个有代表性的关键字begin、end、if、then、else;标识符;整型常数;六种关系运算符;一个赋值符和四个算术运算符。参考实现方法简述如下。 单词的分类:构造上述语言中的各类单词符号及其分类码表。 表I 语言中的各类单词符号及其分类码表 单词符号类别编码类别码的助记符单词值

北京工业大学实验报告1

1.有一硅单晶片,厚0.5mm,其一面上每107个硅原子包含两个镓原子,另一个面经处理后含镓的浓度增高。试求在该面上每107个硅原子需包含几个镓原子,才能使浓度梯度为2×10-26原子/m3m硅的晶格常数为0.5407nm。 2.为研究稳态条件下间隙原子在面心立方金属中的扩散情况,在厚0.25mm的金属薄膜的一个端面(面积1000mm2)保持对应温度下的饱和间隙原子,另一端面为间隙原子为零。测得下列数据: 温度(K)薄膜中间隙原子的溶解度 (kg/m3) 间隙原子通过薄膜的速率 (g/s) 122314.40.0025 113619.60.0014 计算在这两个温度下的扩散系数和间隙原子在面心立方金属中扩散的激活能。 3.一块含0.1%C的碳钢在930℃渗碳,渗到0.05cm的地方碳的浓度达到0.45%。在t>0的全部时间,渗碳气氛保持表面成分为1%, 4.根据上图4-2所示实际测定lgD与1/T的关系图,计算单晶体银和多晶体银在低于700℃温度范围的扩散激活能,并说明两者扩散激活能差异的原因。 5.设纯铬和纯铁组成扩散偶,扩散1小时后,Matano平面移动了1.52×10-3cm。已知摩尔分数C Cr=0.478时,dC/dx=126/cm,互扩散系数为1.43×10-9cm2/s,试求Matano面的移动速度和铬、铁的本征扩散系数D Cr,D Fe。(实验测得Matano 面移动距离的平方与扩散时间之比为常数。D Fe=0.56×10-9(cm2/s)) 6.对于体积扩散和晶界扩散,假定Q晶界≈1/2Q体积,试画出其InD相对温度倒数1/T的曲线,并指出约在哪个温度范围内,晶界扩散起主导作用。 7.γ铁在925℃渗碳4h,碳原子跃迁频率为1.7×109/s,若考虑碳原子在γ铁中的八面体间隙跃迁,(a)求碳原子总迁移路程S;(b)求碳原子总迁移的均方根位移; (c)若碳原子在20℃时跃迁频率为Γ=2.1×10-9/s,求碳原子的总迁移路程和根均方位移。 8.假定聚乙烯的聚合度为2000,键角为109.5°,求伸直链的长度为L max与自由旋转链的均方根末端距之比值,并解释某些高分子材料在外力作用下可产生很大变形的原因。(l=0.154nm,h2=nl2) 9.已知聚乙烯的Tg=-68℃,聚甲醛的Tg=-83℃,聚二甲基硅氧烷的Tg=-128℃,试分析高分子链的柔顺性与它们的Tg的一般规律。 10.试分析高分子的分子链柔顺性和分子量对粘流温度的影响。 11.有两种激活能分别为E1=83.7KJ/mol和E2=251KJ/mol的扩散反应。观察在温度从25℃升高到600℃时对这两种扩散的影响,并对结果作出评述。

北京工业大学电子实验报告压控阶梯波发生器(数字类)

北京工业大学 课程设计报告 学院电子信息与控制工程 专业 班级组号 题目1、压控阶梯波发生器 2、基于运放的信号发生器设计姓名 学号 指导老师 成绩 年月日

压控阶梯波发生器(数字类)(一)设计任务 在规定时间内设计并调试一个由电压控制的阶梯波发生器。 (二)设计要求 1、输出阶梯波的频率能被输入直流电压所控制,频率控制范围为600Hz至1000Hz。 2、输出阶梯波的台阶级数为10级,且比例相等。 3、输出阶梯波的电压为1V/级。 4、输入控制电压的范围0.5V至0.6V。 5、电路结构简单,所用元器件尽量少,成本低。 (三)调试要求 利用实验室设备和指定器件进行设计、组装和调试,达到设计要求,写出总结报告。 (四)方案选择 在压频转换部分存在两种方案。 1、Lm358组成压频转换电路; 2、NE555构成压频转换电路。 方案论证 数字电路精确度较高、有较强的稳定性、可靠性和抗干扰能力强,数字系统的特性不易随使用条件变化而变化,尤其使用了大规模的继承芯片,使设备简化,进一步提高了系统的稳定性和可靠性,在计算精度方面,模拟系统是不能和数字系统相比拟的。数字系统有算术运算能力和逻辑运算能力,电路结构简单,便于制造和大规模集成,可进行逻辑推理和逻辑判断;具有高度的规范性,对电路参数要求不严,功能强大。为了得到更精彩的波形采用数模混合方案。 (五)实验元器件和芯片 运算放大器Lm358,TTL电路74LS20、74LS161、74LS175,CMOS缓冲器CD4010,稳压管,二极管1N4148,电位器,电容,电阻。 (六)设计方案 整体设计思路:

压频转换→计数器→权电阻→运放=>阶梯波 利用Lm358组成压频转换电路;使用CD4010缓冲,形成可被数字电路识别的矩形波信号;74LS161与74LS20组合构成十进制计数器;利用74LS175提高负载、整流信号,并组成权电阻网络;最后利用运放放大信号,并输出。仿真电路图:

编 译 原 理 实 验 报 告

编译原理实验报告 课程:编译原理 系别:计算机系 班级:11网络 姓名:王佳明 学号:110912049 教师:刘老师 实验小组:第二组 1

实验一熟悉C程序开发环境、进行简单程序的调试 实验目的: 1、初步了解vc++6.0环境; 2、熟悉掌握调试c程序的步骤: 实验内容: 1、输入下列程序,练习Turbo C 程序的编辑、编译、运行。 #include main() { printf(“Programming is fun.\n”); } 2、分析程序,预测其运行结果,并上机检测你的预测。 #include main() { printf(“*\n”); printf(“* * *\n”); printf(“* * * * *\n”); printf(“* * * * * * *\n”); } 3、下面是一个加法程序,程序运行时等待用户从键盘输入两个整数,然后求出它们的和并输出。观察运行结果(程序输出),上机验证该程序。 #include main() { int a,b,c; printf(“Please input a,b:”); scanf(“%d,%d”,&a,&b); c=a+b; printf(“%d+%d=%d\n”,a,b,c); } 2

实验二词法分析器 一、实验目的: 设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。 二、实验要求: 1.对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。 2.本程序自行规定: (1)关键字"begin","end","if","then","else","while","write","read", "do", "call","const","char","until","procedure","repeat" (2)运算符:"+","-","*","/","=" (3)界符:"{","}","[","]",";",",",".","(",")",":" (4)其他标记如字符串,表示以字母开头的标识符。 (5)空格、回车、换行符跳过。 在屏幕上显示如下: ( 1 , 无符号整数) ( begin , 关键字) ( if , 关键字) ( +, 运算符) ( ;, 界符) ( a , 普通标识符) 三、使用环境: Windows下的visual c++6.0; 四、调试程序: 1.举例说明文件位置:f:、、11.txt目标程序如下: begin x:=9 if x>0 then x:=x+1; while a:=0 do 3

编译原理实验报告总结

学年第学期《编译原理》实验报告 学院(系):计算机科学与工程学院 班级:11303070A 学号:11303070*** 姓名:无名氏 指导教师:保密式 时间:2016 年7 月

目录 1.实验目的 (1) 2.实验内容及要求 (1) 3.实验方案设计 (1) 3.1 编译系统原理介绍 (1) 3.1.1 编译程序介绍 (2) 3.1.2 对所写编译程序的源语言的描述 (2) 3.2 词法分析程序的设计 (3) 3.3 语法分析程序设计 (4) 3.4 语义分析和中间代码生成程序的设计 (4) 4. 结果及测试分析 (4) 4.1软件运行环境及限制 (4) 4.2测试数据说明 (5) 4.3运行结果及功能说明 (5) 5.总结及心得体会 (7)

1.实验目的 根据Sample语言或者自定义的某种语言,设计该语言的编译前端。包括词法分析,语法分析、语义分析及中间代码生成部分。 2.实验内容及要求 (1)词法分析器 输入源程序,输出对应的token表,符号表和词法错误信息。按规则拼单词,并转换成二元形式;滤掉空白符,跳过注释、换行符及一些无用的符号;进行行列计数,用于指出出错的行列号,并复制出错部分;列表打印源程序;发现并定位词法错误; (2)语法分析器 输入token串,通过语法分析,寻找其中的语法错误。要求能实现Sample 语言或自定义语言中几种最常见的、基本的语法单位的分析:算术表达式、布尔表达式、赋值语句、if语句、for语句、while语句、do while语句等。 (3)语义分析和中间代码生成 输入token串,进行语义分析,修改符号表,寻找其中的语义错误,并生 成中间代码。要求能实现Sample语言或自定义语言中几种最常见的、基本的语法单位的分析:算术表达式、布尔表达式、赋值语句、if语句、for语句、while 语句、do while语句等。 实验要求:功能相对完善,有输入、输出描述,有测试数据,并介绍不足。3.实验方案设计 3.1 编译系统原理介绍 编译器逐行扫描高级语言程序源程序,编译的过程如下: (1).词法分析 识别关键字、字面量、标识符(变量名、数据名)、运算符、注释行(给人看的,一般不处理)、特殊符号(续行、语句结束、数组)等六类符号,分别归类等待处理。 (2).语法分析 一个语句看作一串记号(Token)流,由语法分析器进行处理。按照语言的文法检查判定是否是合乎语法的句子。如果是合法句子就以内部格式保存,否则报错。直至检查完整个程序。 (3).语义分析 语义分析器对各句子的语法做检查:运算符两边类型是否相兼容;该做哪些类型转换(例如,实数向整数赋值要"取整");控制转移是否到不该去的地方;是

北工大matlab作业实验报告

北工大MATLAB实验报告 完成日期:2018.12

目录 实验一用FFT进行谱分析 (3) 一、实验内容 (3) 二、实验过程 (3) 三、实验代码 (4) 四、实验结果及分析 (5) 五、实验心得 (5) 实验二噪声数据的抑制 (6) 一、实验内容 (6) 二、实验过程 (7) 三、实验结果分析 (14) 四、实验心得 (15) 参考文献 (15)

实验一用FFT进行谱分析 一、实验内容 FFT的用途之一是找出隐藏或淹没在噪声时域信号中信号的频率成分。本题要求用FFT 对试验数据进行谱分析,指出数据包含的频率成份。 提示:首先建立试验数据。过程推荐如下:生成一个包含两个频率成分的试验信号,对这个信号加入随机噪声,形成一个加噪信号y。(试验数据参数推荐为:数据采样频率为1000Hz,时间区间从t=0到t=0.25,步长0.001秒,噪声的标准偏差为2,两个频率成分的试验信号可取50Hz和120Hz)。 (1)绘制加噪信号y它的波形。 (2)求出含噪声信号y的离散傅立叶变换(取它的FFT),(FFT试验参数推荐为:256点)。 (3)求出信号的功率谱密度(它是不同频率所含能量的度量),并绘制功率谱图,标记出两个频谱峰值对应的频率分量。 二、实验过程 1.打开matlab软件,根据实验要求,用已知条件求出重要参数: N=256; n=0:N-1; t=n/fs; 2.绘制加入了噪声信号的y图象: y=sin(2*pi*50*t)+sin(2*pi*120*t)+2*randn(size(t)); subplot(2,2,1); plot(y);title('y的波形'); 3.对y求付里叶变换: Y=fft(y,N); 4.绘制Y的幅值图象: fudu=abs(Y); f=n*fs/N; subplot(2,2,2) plot(f,fudu); 5.抽取256点进行绘图:

编译原理实验报告

学生学号0120810680316 实验课成绩 武汉理工大学 学生实验报告书 实验课程名称《编译原理》 开课学院计算机科学与技术学院 指导老师姓名何九周 学生姓名刘洋 学生专业班级软件工程0803 2010 —2011 学年第二学期

实验课程名称:编译原理 实验项目名称单词的词法分析程序设计实验成绩实验者刘洋专业班级软件0803 组别 同组者实验日期 2011 年 5 月 17日 第一部分:实验分析与设计(可加页) 一、实验内容描述(问题域描述) 实验目的: 设计,编制并调试一个词法分析程序,加深对词法分析原理的理解。 实验要求: 在上机前应认真做好各种准备工作,熟悉机器的操作系统和语言的集成环境,独立完成算法编制和程序代码的编写;上机时应随带有关的高级语言教材或参考书;要学会程序调试与纠错;每次实验后要交实验报告。 实验题目: 对于给定的源程序(如C语言或Pascal等),要求从组成源程序的字符行中寻找出单词,并给出它们的种别和属性——输出二元组序列。以便提供给语法分析的时候使用。要求能识别所有的关键字,标志符等,并且能够对出先的一些词法规则的错误进行必要的处理。 二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或 者算法描述) 实验原理: 由于这是一个用高级语言编写一个词法分析器,使之能识别输入串,并把分析结果(单词符号,标识符,关键字等等)输出.输入源程序,输入单词符号,本词法分析器可以辨别关键字,标识符,常数,运算符号和某些界符,运用了文件读入来获取源程序代码,再对该源程序代码进行词法分析,这就是词法分析器的基本功能.当词法分析器调用预处理子程序处理出一串输入字符放进扫描缓冲区之后,分析器就从此缓冲区中逐一识别单词符号.当缓冲区里的字符串被处理完之后,它又调用预处理子程序来处理新串. 编写的时候,使用了文件的输入和输出,以便于词法分析的通用型,同时在文件输出时,并保存在输出文件output文件中。 从左到右扫描程序,通过初始化:1为关键字;2为标志符; 3为常数;4为运算符或界符。 三、主要仪器设备及耗材 计算机

北京工业大学微机原理实验报告

微机原理实验报告 —实验二熟悉汇编程序建立 及其调试方法 姓名:刘莹莹 学号:13024104

一、实验目的 1、熟悉汇编语言源程序的框架结构,学会编制汇程序。 2、熟悉汇编语言上机操作的过程,学会汇编程序调试方法。 二、实验内容 1、学习编写汇编语言源程序的方法,了解数据存放格式。 2、阅读给出的程序,找出程序中的错误。 3、通过调试给出的汇编语言源程序,了解并掌握汇编语言程序的建立、汇编、链接、调试、修改和运行等全过程。 三、实验预习 1、阅读实验指导第一章的内容,了解汇编语言程序建立、汇编、链接、调试的全过程。 2、下面的汇编语言源程序有错误的,试给程序加注释。通过调试手段找出程序中的错误并修改之。写出程序的功能,画出程序流程图。(1)程序修改前: STACKSG:SEGMENT PARA STACK ‘STACK’ ;不能有冒号DB 256 DUP(?) STACKSG ENDS DATASG: SEGMENT PARA ‘DATA’;不能有冒号BLOCK DW 0,-5,8,256,-128,96,100,3,45,6,512 DW 23,56,420,75,0,-1024,-67,39,-2000 COUNT EQU 20 MAX DW ? DATASG ENDS CODESG: SEGMENT ;不能有冒号ASSUME SS:STACKSG , CS:CODESG ASSUME DS:DATASG ORG 100H BEGIN MOV DS, DATASG ;BEGIN: 应改为MOV AX , DATASG MOV DS, AX LEA SI ,BLOCK

编译原理实验报告一

实验一词法分析程序实现 一、实验目得与要求 通过编写与调试一个词法分析程序,掌握在对程序设计语言得源程序进行扫描得过程中,将字符流形式得源程序转化为一个由各类单词符号组成得流得词法分析方法 二、实验内容 基本实验题目:若某一程序设计语言中得单词包括五个关键字begin、end、if、then、else;标识符;无符号常数;六种关系运算符;一个赋值符与四个算术运算符,试构造能识别这些单词得词法分析程序(各类单词得分类码参见表I)。 表I语言中得各类单词符号及其分类码表 输入:由符合与不符合所规定得单词类别结构得各类单词组成得源程序文件。 输出:把所识别出得每一单词均按形如(CLASS,VALUE)得二元式形式输出,并将结果放到某个文件中。对于标识符与无符号常数,CLASS字段为相应得类别码得助记符;V AL UE字段则就是该标识符、常数得具体值;对于关键字与运算符,采用一词一类得编码形式,仅需在二元式得CLASS字段上放置相应单词得类别码得助记符,V ALUE字段则为“空". 三、实现方法与环境 词法分析就是编译程序得第一个处理阶段,可以通过两种途径来构造词法分析程序.其一就是根据对语言中各类单词得某种描述或定义(如BNF),用手工得方式(例如可用C语言)构造词法分析程序。一般地,可以根据文法或状态转换图构造相应得状态矩阵,该状态矩阵连同控制程序一起便组成了编译器得词法分析程序;也可以根据文法或状态转换图直接编写词法分析程序。构造词法分析程序得另外一种途径就是所谓得词法分析程序得自动生成,即首先用正规式对语言中得各类单词符号进行词型描述,并分别指出在识别单词时,词法分析程

编译原理标准实验报告

电子科技大学 实验报告 学生姓名:学号:指导教师: 实验地点:实验时间: 一、实验室名称:计算机学院软件工程实验室 二、实验项目名称:词法分析器的设计与实现 三、实验学时:4学时 四、实验原理 1.编译程序要求对高级语言编写的源程序进行分析和合成,生成目标程序。词法分析是对源程序进行的首次分析,实现词法分析的程序为词法分析程序。 2.词法分析的功能是从左到右逐个地扫描源程序字符串,按照词法规则识别出单词符号作为输出,对识别过程中发现的词法错误,输出相关信息。 3.状态转换图是有限有向图,是设计词法分析器的有效工具。 五、实验目的 通过设计词法分析器的实验,使同学们了解和掌握词法分析程序设计的原理及相应的程序设计方法,同时提高编程能力。 六、实验内容 实现求n!的极小语言的词法分析程序,返回二元式作为输出。 七、实验器材(设备、元器件) 1.操作系统:Windows XP

2.开发工具:VC6.0 3.普通PC即可 八、实验步骤 (1)启动VC6.0,创建空白工程项目。选择菜单中的“文件”->“新建”->“项目”,在弹出的对话框中,左边的“项目类型”框中,选择“Visual C++ 项目”,在右边框中,选择“空项目(.Net)”,在对话框下边,选择工程文件存放目录及输入名称,如Example1,单击“确定”。 (2)建立相应的单词符号与种别对照表; (3)根据状态转换图编写相应的处理函数; (4)完成词法分析器; (5)编译与调试以上程序; (6)生成相应的*.dyd文件,作为后面语法分析的输入文件。 九、实验数据及结果分析

可以对源程序进行词法分析,如果有错给出出错信息和所在行数,如果无错则生成二元式文件。 十、实验结论 本实验程序较好地完成了词法分析程序的设计与实现,能够对所给文法的程序进行词法分析,在没有词法错误的时候生成相应的二元式文件。该实验程序可一次性给出源程序中的词法错误。 十一、总结及心得体会 通过该实验,对词法分析程序的设计,以及运用C语言进行编程有了更深刻的理解,同时加深了自己对词法分析程序的原理的理解与掌握,提高了自己的动手能力。 十二、对本实验过程及方法、手段的改进建议 程序设计合理,代码可进一步优化。 报告评分: 指导教师签字:

编译原理实验报告

《编译原理》实验报告软件131 陈万全132852

一、需求分析 通过对一个常用高级程序设计语言的简单语言子集编译系统中词法分析、语法分析、语义处理模块的设计、开发,掌握实际编译系统的核心结构、工作流程及其实现技术,获得分析、设计、实现编译程序等方面的实际操作能力,增强设计、编写和调试程序的能力。 通过开源编译器分析、编译过程可视化等扩展实验,促进学生增强复杂系统分析、设计和实现能力,鼓励学生创新意识和能力。 1、词法分析程序设计与实现 假定一种高级程序设计语言中的单词主要包括五个关键字begin、end、if、then、else;标识符;无符号常数;六种关系运算符;一个赋值符和四个算术运算符,试构造能识别这些单词的词法分析程序。 输入:由符合和不符合所规定的单词类别结构的各类单词组成的源程序文件。 输出:把所识别出的每一单词均按形如(CLASS,VALUE)的二元式形式输出,并将结果放到某个文件中。对于标识符和无符号常数,CLASS字段为相应的类别码的助记符;VALUE字段则是该标识符、常数的具体值;对于关键字和运算符,采用一词一类的编码形式,仅需在二元式的CLASS字段上放置相应单词的类别码的助记符,VALUE字段则为“空”。 2、语法分析程序设计与实现 选择对各种常见高级程序设计语言都较为通用的语法结构——算术表达式的

一个简化子集——作为分析对象,根据如下描述其语法结构的BNF定义G2[<算术表达式>],任选一种学过的语法分析方法,针对运算对象为无符号常数和变量的四则运算,设计并实现一个语法分析程序。 G2[<算术表达式>]: <算术表达式>→<项> | <算术表达式>+<项> | <算术表达式>-<项> <项>→<因式>|<项>*<因式>|<项>/<因式> <因式>→<运算对象> | (<算术表达式>) 若将语法范畴<算术表达式>、<项>、<因式>和<运算对象>分别用E、T、F和i 代表,则G2可写成: G2[E]:E → T | E+T | E-T T → F | T*F | T/F F → i | (E) 输入:由实验一输出的单词串,例如:UCON,PL,UCON,MU,ID······输出:若输入源程序中的符号串是给定文法的句子,则输出“RIGHT”,并且给出每一步分析过程;若不是句子,即输入串有错误,则输出“ERROR”,并且显示分析至此所得的中间结果,如分析栈、符号栈中的信息等,以及必要的出错说明信息。 3、语义分析程序设计与实现 对文法G2[<算术表达式>]中的产生式添加语义处理子程序,完成运算对象是简单变量(标识符)和无符号数的四则运算的计值处理,将输入的四则运算转换为四元式形式的中间代码。 输入:包含测试用例(由标识符、无符号数和+、?、*、/、(、)构成的算术表达式)的源程序文件。 输出:将源程序转换为中间代码形式表示,并将中间代码序列输出到文件中。 若源程序中有错误,应指出错误信息 二、设计思路 1、词法分析程序设计与实现 1)单词分类 为了编程的实现。我们假定要编译的语言中,全部关键字都是保留字,程序员不得将它们作为源程序中的标识符;作了这些限制以后,就可以把关键字和标识符的识别统一进行处理。即每当开始识别一个单词时,若扫视到的第一个字符为字母,则把后续输入的字母或数字字符依次进行拼接,直至扫视到非字母、数字字符为止,以期获得一个尽可能长的字母数字字符串,然后以此字符串查所谓保留字表(此保留字表要事先造好),若查到此字符串,则取出相应的类别码;反之,则表明该字符串应为一标识符。

北京工业大学 编译原理 实验报告

计算机学院实验报告 课程名称:编译原理 实验人学号:110703xx 姓名:xxx 实验完成日期:2014年5月20日报告完成日期:2014年5月20日

目录 实验一词法分析程序的设计与实现 (3) 词法的正规式描述: (3) 状态图: (4) 词法分析程序数据结构与算法: (4) 词法分析算法: (5) 实验结果: (7) 实验中遇到的问题及其解决: (8) 1、保留字的检测问题: (8) 2、关于0为首位的数字是int8、int10和int16的判断问题: (8) 3、关于回退的问题: (8) 实验二自顶向下的语法分析—递归子程序法 (9) 改写后的产生式集合: (9) 化简后的语法图: (9) 递归子程序算法 (10) 实验结果: (13) 实验中遇到的问题及其解决: (14) 1、消除左递归,提取左因子之后的E、T对应的子程序的编写问题: (14) 2、缩进的控制: (14) 实验三语法制导的三地址代码生成程序 (15) 语法制导定义: (15) 三地址代码生成器的数据结构 (16) 三地址生成器算法: (17) 实验结果: (21) 实验中遇到的问题及其解决: (22) 1、根据化简后的产生式修改语法制导定义: (22) 2、使用真假出口法和继承属性来确定goto的标号: (22)

实验一词法分析程序的设计与实现 词法的正规式描述: 标识符 <字母>(<字母>|<数字字符>)* 十进制整数 0|(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)* 八进制整数 0(0|1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)* 十六进制整数 0(x|X)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e |f)* 运算符和分隔符 + - * / > < = ( ) ; 关键字 if then else while do .

编译原理实验报告2

学生学号实验课成绩 武汉理工大学 学生实验报告书 实验课程名称编译原理 开课学院计算机科学与技术学院 指导老师姓名饶文碧 学生姓名 学生专业班级

—学年第学期 实验课程名称:编译原理 实验项目名称单词的词法分析实验成绩 实验者专业班级组别 同组者实验日期 第一部分:实验分析与设计(可加页) 一、实验内容描述(问题域描述) 完成对某一种常用高级语言(如Pascal、C语言、PL/0语言)的各类单词进行词法分析,即对源程序从左到右进行扫描,对组成源程序的字符串拼接成为单词;并把其转换成属性字输出。 实验要求: (1)选择常用高级程序设计语言(如 Pascal、C语言、PL/0语言)的源程序作为词法分析对象。 (2)根据教学要求和学生具体情况,从上列语言之一中选取它的一个适当大小的子集,可以选取一类典型单词,也可以尽可能使各种类型的单词都能兼顾到。其基本要求是:对源程序从左到右进行扫描,对组成源程序的字符串拼接成为单词,并把其转换成属性字输出。

二、实验基本原理与设计(包括实验方案设计,实验手段的确定,试验步骤等,用硬件逻辑或者算法描述) #include #include #include #include char *table[7]={" ","main","int","if","then","else","return"},TOKEN[20],ch; //定义关键字 int lookup(char *TOKEN){ //关键字匹配函数 int m,i; for(i=1;i<6;i++){ if((m=strcmp(TOKEN,table[i]))==0) return(i); } return(0); } void out(int c,char *TOKEN){ //输出函数 printf("(%d,%s)\n",c,TOKEN); } void scanner(FILE *fp){ //扫描函数

编译原理实验报告(手打)

《编译原理》实验报告 班级:计C104 姓名:李云霄 学号:108490

实验一词法分析程序实现 一、实验目的与要求 通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。 二、实验内容 选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。 输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。 输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。 三、实现方法与环境 1、首先设计识别各类单词的状态转换图。 描述无符号常数的确定、最小化状态转换图如图1所示。其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。 图1 文法G[<无符号数>]的状态转换图 其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>, 1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。 在一个程序设计语言中,一般都含有若干类单词符号,为此可首先为每类单词建立一张状态转换图,然后将这些状态转换图合并成一张统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。 四则运算算术符号的识别很简单,直接在状态图的0状态分别引出相应标记的矢

北工大数字积分器实验报告

数字电子技术实验 实验一:数字积分器 一、设计题目 数字积分器 二、设计要求 1.模拟输入信号0-10V,积分时间1-10秒,步距1秒。 2.积分值为0000-9999。 3.误差小于1%±1LSB 4.应具有微调措施,以便校正精度。 基本要求: 1.通过数字积分器,对输入模拟量进行积分,将积分值转化为数字量并显示。 输入与输出的对应关系:输入1V,转化为频率100Hz,计数器计数为100,积分时间为1s,积分10次,输出为1000。 2. 输入模拟量的范围为0-10V,通过10次积分,输出积分值为0000-9999。误 差要求小于1%±1LSB。 3. 数字积分器应具有微调措施,对于由元件参数引起的误差,可以通过微调进 行调节,使其达到误差精度。微调的设置应尽可能使电路简单,便于调节,能提供微小调节,尽快达到要求。 参考元器件: 组件:74LS00 74LS08 74LS20 74LS161 uA741 NE555 3DK7 电阻、电容:若干 调零电位器:10K 三、设计框图

图1.3 设计框图 针对设计方案的要求,将整个电路分为五个部分,分别为:V/F 压频转换器、时间积分电路、电路(与门)、计数器电路、数字显示电路。 四、设计方案的选择及比较 (1)V/F 转换器的设计: 通过上网查阅资料,得出两个方案 方案一:采用LM331直接构成V/F 转换器。 方案二:采用uA741和NE555两个芯片来构成压频转换器。我们采 Vi V/F转换器 单稳电路 (积分时间)四位16进制计数器与门 数字显示

用方案二实现电路。 首先介绍V/F转换器的组成电路: 2.NE555构成的施密特触发器原理: 施密特触发器的特点: (1)双稳态触发器,有两个稳定的状态; (2)电平触发——电压达到某个值时电路状态翻转; (3)具有滞后电压传输特性——回差特性(两次翻转输入电平不同); 施密特触发器原理分析:

编译原理实验报告

实验一词法分析程序实现 一、实验目的与要求 通过编写和调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将字符形式的源程序流转化为一个由各类单词符号组成的流的词法分析方法。 二、实验内容 选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。 输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。 输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。 三、实现方法与环境 1、首先设计识别各类单词的状态转换图。 描述无符号常数的确定、最小化状态转换图如图1所示。其中编号0,1,2, (6) 表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>,1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。 图1 文法G[<无符号数>]的状态转换图 其中编号0,1,2,…,6代表非终结符号<无符号数>、<余留无符号数>、<十进小数>、<小数部分>、<指数部分>、<整指数>及<余留整指数>,1,2和6为终态,分别代表整数、小数和科学计数的识别结束状态。 在一个程序设计语言中,一般都含有若干类单词符号,为此可首先为每类单词建立一张状态转换图,然后将这些状态转换图合并成一张统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。 四则运算算术符号的识别很简单,直接在状态图的0状态分别引出相应标记的矢线至一个新的终态即可。根据自己的习惯,也可以将其转换为状态矩阵形式。 2、词法分析程序编写 根据描述语言中各类单词的文法状态转换图或状态矩阵,利用某种语言(C语言或JA V A 语言)直接编写词法分析程序。 3、词法分析程序测试 用于测试扫描器的实例源文件中应有词法正确的,也应有错误的字符串,对于输入的测试用例的源程序文件,以对照的形式将扫描器的分析结果信息在输出文件中表示出来。四、参考资料 实现无符号数识别的参考方法:将设计的状态转换图直接转化为一张程序流程图,并在外层再增加一个以EOF为循环终止条件的while循环,即形成能连续识别各类单词的词法分析程序。 各类单词的编码建议如表1。 表1 单词的内部编码

相关主题
文本预览
相关文档 最新文档