编译原理实验报告++词法分析器实验报告

更新时间:2024-06-28 13:22:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

编译原理实验报告

词法分析器制作与应用 设计思想

(1)程序主体结构部分: 说明部分 %%

规则部分 %%

辅助程序部分 (2)主体结构的说明

在这里说明部分告诉我们使用的LETTER,DIGIT, IDENT(标识符,通常定义为字母开头的字母数字串)和STR(字符串常量,通常定义为双引号括起来的一串字符)是什么意思.这部分也可以包含一些初始化代码.例如用#include来使用标准的头文件和前向说明(forward ,references).这些代码应该再标记\和\之间;规则部分>可以包括任何你想用来分析的代码;我们这里包括了忽略所有注释中字符的功能,传送ID名称和字符串常量内容到主调函数和main函数的功能. (3)实现原理

程序中先判断这个句语句中每个单元为关键字、常数、运算符、界符,对与不同的单词符号给出不同编码形式的编码,用以区分之。 PL/0语言的EBNF表示

<常量定义>::=<标识符>=<无符号整数>; <标识符>::=<字母>={<字母>|<数字>}; <加法运算符>::=+|- <乘法运算符>::=*|/

<关系运算符>::==|#|<|<=|>|>= <字母>::=a|b|?|X|Y|Z

<数字>::=0|1|2|?|8|9 三:设计过程

1. 关键字:void,main,if,then,break,int,Char,float,include,for,while,printfscanf 并为小写。

2.\”;”-”;”*”;”/”;”:=“;”:”;”<“;”<=“;”>“;”>=“;”<>“;”=“;”(“;”)”;”;”;”#”为运算符。

3. 其他标记 如字符串,表示以字母开头的标识符。 4. 空格符跳过。

5. 各符号对应种别码 关键字分别对应1-13

运算符分别对应401-418,501-513。 字符串对应100 常量对应200 结束符#

四:举例说明

目标:实现对常量的判别 代码:

digit [0-9]

letter [A-Za-z] other_char [!-@\\[-~]

id ({letter}|[_])({letter}|{digit}|[_])* string {({letter}|{digit}|{other_char})+} int_num {digit}+ %% [ |\\t|\\n]+

\ar\efault\ {Upper(yytext,yyleng);printf(\\\\ {printf(\

-?{int_num}[.]{int_num}?([E][+|-]?{int_num})? {printf(\\

\<=\ {printf(\{id} {printf(\

{digit}({letter})+ {printf(\ %%

#include Upper(char *s,int l) {

int i;

for(i=0;i

s[i]=toupper(s[i]); } }

yywrap() {

return 1; }

五:DFA

六:数据测试

七:心得体会

其实匹配并不困难,主要是C++知识要求相对较高,只要把握住指针就好了。 附源程序:

#include #include #include #include

int i,j,k,flag,number,status;

/*status which is use to judge the string is keywords or not!*/ char ch;

char words[10] = {\char program[500]; int Scan(char program[])

{

char *keywords[13] = {\ \ \number = 0; status = 0;

j = 0;

ch = program[i++];

/* To handle the lettle space ands tab*/

/*handle letters*/ if ((ch >= 'a') && (ch <= 'z' )) {

while ((ch >= 'a') && (ch <= 'z' )) {

words[j++]=ch; ch=program[i++]; } i--;

words[j++] = '\\0';

for (k = 0; k < 13; k++)

if (strcmp (words,keywords[k]) == 0) switch(k) { case 0:{ flag = 1; status = 1; break; } case 1:{ flag = 2; status = 1; break; }

case 2:{ flag = 3; status = 1; break; } case 3:{ flag = 4; status = 1; break; } case 4:{ flag = 5; status = 1; break; }

case 5:{ flag = 6; status = 1; break; } case 6:{ flag = 7; status = 1; break; } case 7:{ flag = 8; status = 1; break; } case 8:{ flag = 9; status = 1; break; } case 9:{ flag = 10; status = 1; break; } case 10:{ flag = 11; status = 1; break;

}

case 11:{ flag = 12; status = 1; break; } case 12:{ flag = 13; status = 1; break; } }

if (status == 0) {

flag = 100; }

}

/*handle digits*/

else if ((ch >= '0') && (ch <= '9')) {

number = 0;

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

number = number*10+(ch-'0'); ch = program[i++]; }

flag = 200;

i--; }

/*opereation and edge handle*/ else switch (ch) {

case '=':{

if (ch == '=') words[j++] = ch; words[j] = '\\0';

ch = program[i++]; if (ch == '=') {

words[j++] = ch; words[j] = '\\0'; flag = 401; } else

{

i--;

flag = 402; } break; } case'>':{

if (ch == '>')

words[j++] = ch; words[j] = '\\0';

ch = program[i++]; if (ch == '=') {

words[j++] = ch; words[j] = '\\0'; flag = 403; } else { i--;

flag = 404; } break; }

case'<':{

if (ch == '<')

words[j++] = ch;

words[j] = '\\0';

ch = program[i++]; if (ch == '=') {

words[j++] = ch; words[j] = '\\0'; flag = 405; }

else {

i--;

flag = 406; }

break; }

case'!':{

if (ch == '!')

words[j++] = ch;

words[j] = '\\0';

ch = program[i++]; if (ch == '=') {

words[j++] = ch; words[j] = '\\0'; flag = 407; } else { i--;

flag = 408; } break; }

case'+':{

if (ch == '+')

words[j++] = ch; words[j] = '\\0';

ch = program[i++]; if (ch == '=') {

words[j++] = ch; words[j] = '\\0'; flag = 409; }

else if (ch == '+') {

words[j++] = ch; words[j] = '\\0'; flag = 410; } else { i--;

flag = 411; } break; } case'-':{

if (ch == '-')

words[j++] = ch; words[j] = '\\0';

ch = program[i++]; if (ch == '=') {

words[j++] = ch; words[j] = '\\0'; flag = 412; }

else if( ch == '-') {

words[j++] = ch; words[j] = '\\0'; flag = 413; } else { i--;

flag = 414; }

break; } case'*':{

if (ch == '*')

words[j++] = ch; words[j] = '\\0';

ch = program[i++]; if (ch == '=') {

words[j++] = ch; words[j] = '\\0'; flag = 415; } else { i--;

flag = 416; } break; }

case'/':{ if (ch == '/')

words[j++] = ch;

words[j] = '\\0';

ch = program[i++]; if (ch == '=')

{

words[j++] = ch; words[j] = '\\0'; flag = 417; } else {

i--;

flag = 418; } break; }

case';':{

words[j] = ch; words[j+1] = '\\0'; flag = 501; break; }

case'(':{

words[j] = ch; words[j+1] = '\\0'; flag = 502; break; }

case')':{

words[j] = ch; words[j+1] = '\\0'; flag = 503; break; }

case'[':{

words[j] = ch; words[j+1] = '\\0'; flag = 504; break; } case']':{

words[j] = ch; words[j+1] = '\\0'; flag = 505; break;

}

case'{':{

words[j] = ch;

words[j+1] = '\\0'; flag = 506; break; }

case'}':{

words[j] = ch; words[j+1] = '\\0'; flag = 507; break; }

case':':{

words[j] = ch; words[j+1] = '\\0'; flag = 508; break; }

case'\

words[j] = ch; words[j+1] = '\\0'; flag = 509; break;

}

case'%':{

if (ch == '%')

words[j++] = ch;

words[j] = '\\0';

ch = program[i++]; if (ch == '=') {

words[j++] = ch; words[j] = '\\0'; flag = 510; } else { i--;

flag = 511; } break; } case',':{

words[j] = ch; words[j+1] = '\\0'; flag = 512;

break;

}

case'#':{

words[j] = ch; words[j+1] = '\\0'; flag = 513; break; }

case'@':{ words[j] = '#'; flag = 0; break; }

default:{ flag = -1; break; } }

return flag; } main()

{ i=0;

printf(\do

{

ch = getchar(); program[i++] = ch; }while(ch != '@'); i = 0;

do{

flag = Scan(program); if (flag == 200) {

printf(\ }

else if (flag == -1) {

printf(\ } else

{

printf(\ }

}while (flag != 0); system(\}

编译原理》实验教学大纲

部门:实验中心 发布人:崔诣 时间:2006-7-4

课程编号:27140001 大纲执笔人:马知行 课程名称:编译原理 大纲审批人:曹启君 英文名称:Compilers Principles

课程学时:54 实验学时:36 实验室名称:计算机技术实验室 实验课性质:非独立设课 适用专业:计算机科学与技术 一、本课程实验教学目的与要求

通过对词法分析、语法分析和代码生成程序的设计和编制,使学生掌握编译程序的基本构造、基本原理和主要实现技巧。加深学生调试程序的能力,使学生对编译程序的构造方法有一定的了解,并对编译程序的各个部件有较深的认识。

二、主要仪器设备及现有台套数 微型计算机每生一台(套)

三、实验课程内容和学时分配

序号 1 2 实验项目目的要求 学时实验类型 每组人数 名称 分配 词法分析 掌握编译程序中词法6 综合性实验 1至3人 分析程序的基本构造方法和实现原理,熟练掌握词法分析程序的调试方法和技巧 自顶向下掌握自顶向下的语法6 综合性实验 1至3人 的语法分分析(递归子程序法/必开、选开 必开 必开 析 3 自底向上的语法分析 4 自顶向下分析技术的代码生成 自底向上分析技术的代码生成 5 预测分析法)器的编制方法,深刻理解语法分析的作用 掌握自底向上的语法6 分析(SLR/LALR)器的编制方法,进一步理解语法分析的作用,并体会语法分析的自动生成方法 掌握代码生成中的生9 成技巧,并深刻理解代码生成的基本方法和符号表、内存管理等编译原理的基本技巧 进一步理解代码生成9 的生成技巧,并深刻理解如何利用语法制导翻译的方法与符号表、内存管理等编译原理的基本技巧相结合生成可运行的目的程序 综合性实验 1至3人 必开 综合性实验 1至3人 选开 综合性实验 1至3人 选开

四:实验项目的内容和要求 (1) 词法分析

1. 实验项目名称:词法分析

2. 实验内容:用C/C++完成一个词法分析程序

3. 实验要求:通过实验要求学生掌握词法分析程序的设计的基本方法以及有限自动机理论在词法分析中的作用。

(2) 自顶向下的语法分析

1. 实验项目名称:自顶向下的语法分析

2. 实验内容:用C/C++完成一个自顶向下的语法分析(递归子程序或预测分析程序)

3. 实验要求:通过实验要求学生掌握自顶向下的语法分析的基本方法,以及左递归、左公因子对自顶向下的语法分析的危害

(3) 自底向上的语法分析

1. 实验项目名称:自底向上的语法分析 2. 实验内容:用C/C++设计一个LR总控程序

3. 实验要求:通过实验要求学生掌握LR分析程序的结构、LR分析表的构造方法以及体会YACC自动生成语法分析程序的含义

(4) 自顶向下分析技术的代码生成

1. 实验项目名称:自顶向下分析技术的代码生成

2. 实验内容:在递归子程序或预测分析程序中配上适当的语义子程序以便生成源程序的目标代码 3. 实验要求:通过实验要求学生掌握代码生成中的生成技巧,并深刻理解代码生成的基本方法和符号表、内存管理等编译原理的基本技巧在程序设计中的应用 (5) 自底向上分析技术的代码生成

1. 实验项目名称:自底向上分析技术的代码生成实验内容:指本项实验的具体内容 2. 实验要求:在LR分析中配上适当的语义子程序以便生成源程序的目标代码

3. 实验要求:通过实验要求学生深刻理解语法制导翻译如何在自底向上分析技术中的应用,进一步加深学生对符号表、内存管理等编译原理的理论和方法的理解 五、考核方式

1、实验报告:学生在实验结束后,将实验目的、实验要求、实验体会、实验编写的源程序和结果存入软盘或U盘并通过Email 上交电子文本实验报告。 2、考核方式

(1) 实验课的考核方式:平时考核为主,即对学生每次实验打分

(2) 实验课考核成绩确定:每次实验结束后,教师检查电子文本实验报告和源程序(包括运行源程序),根据正确性,难度、实现技巧等给予记分(可用5分制)、最后与作业组成不超过30%的平时成绩。 六、实验教材、参考书

1、 教材:编译方法 马知行、曹启君编著名 机械出版社出版 2004年月1 2、 参考书:

编译原理 吕映芝著 清华大学出版社 1998年11月 编译原理和技术 陈云意著 中国科学技术大学出版社 程序设计语言编译方法 肖军模编 大连理工大学出版社 1993年

? 实验项目2

? 1、 实验项目名称:词法分析器的设计

与实现

? 2、 实验项目的目的和要求:

通过设计和实现一个简单的词法分析器,熟悉词法分析的原理与技术,培养站在设计者和实现者的角度分析和评估语言的能力,提高程序设计水平。

? 3、 实验内容:

o 1)设计XXX语言的词法规则,构造

单词符号和内部表示编号表。

o 2)设计XXX语言的词法分析器,构

造词法分析器的状态转换图。

o 3)实现XXX语言的词法分析器,根

据词法规则,对输入的源程序进行扫描和分析,识别出单词符号,并输出相应的二元式序列。

? 4、 设计要点:

o 1)词法分析器从左至右逐个字符的

扫描源程序的字符流,分析出一个个单词符号。经过词法分析器分析出来的单词符号,是一个语言的基本语法符号,可作为语法分析的基础。在语法分析时,把它作为文法的终结符看待。

o 2)语言的符号通常可分为5种:基

本字、标识符、常数、运算符和界符。

o 3)词法分析器以二元式的形式输出

分析结果,即单词符号的序列。二元式形如:(符号的编码,符号自身的值)。其中,对基本字、界符和运算符,可以一字一码;对常数可按它的类型来分类编码;对标识符可以使用统一的编码,然后用它自身的值区分不同的标识符。

o 4)源程序是一个很长的字符串,要

从这样的字符串中把单词识别出来,必须根据语言规定的书写规则,即词法规则,找出相应的分解方法。在分解的时候,经常使用的一种方法是超前搜索方法。这种方法向前多搜索一个或几个字符,用于正确识别当前待分解的单词符号。

o 5)状态转换图是一张有限方向图,

它是设计词法分析器的有效工具。状态转换图和实际的程序之间有比较简单的对应关系,其中,每个状态对应一段程序,表示完成一定的功能;每个分支对应一个选择语句,可用if语句实现,如果分支较多,可用case

实验项目3

语句实现;回路对应一个循环,可用while语句实现。

o 5、 项目需用仪器设备名称: PC机

一台,装有C/C++语言或Java语言的程序开发环境。

o 6、 所需主要元器件及耗材:无 o 7、 学时数:4 ?

o 1、 实验项目名称:语法分析器的设计

与实现

o 2、 实验项目的目的和要求:通过设计

和实现一个简单的语法分析器,熟悉语法分析的原理与技术,培养站在设计者和实现者的角度分析和评估语言的能力,提高程序设计水平。

o 3、 实验内容:

? 1)分析XXX语言的文法规则,构造项

目集规范族,构造LR分析表。必要时对文法规则进行改造以符合LR分析法的要求。

? 2)设计一个通用的LR语法分析器,

设计分析栈、输入串、LR分析表和LR分析程序的相关算法和数据结构。

? 3)实现通用LR语法分析器,根据LR

分析表的内容,对输入串(终结符序列)进行LR分析,输出分析结果。

? 4)将XXX语言的LR分析表导入通用

LR语法分析器中,实现XXX语言的语法分析器。对XXX语言的源程序进行

语法分析(结合XXX词法分析器),输出分析结果。

o 4、 设计要点:

? 1)LR分析法是一种表驱动的方法,它

是由一个分析栈、控制程序和分析表及输入串组成的下推自动机。LR分析法从左向右扫描输入串,每次根据分析栈中的状态、当前的输入符号以及超前搜索的K个输入符号,以确定句柄是否已在分析栈的栈顶形成,从而决定应采取的动作。

? 2)LR分析器主要包括两个部分:一个

总控程序和一张分析表。总控程序是通用的,不同的分析表对应不同的LR分析法。

? 3)分析栈由状态栈和符号栈两部分组

成,状态栈里的每一状态概括了从分析开始到某一时刻已进行的分析工作,分析栈中存放的是当前已经分析部分经前面的移进和归约操作后形成的符号序列。

? 4)LR分析表由action和goto两个子

表组成。action表是一个状态及终结符的二维矩阵,action[s,a]定义了在状态s下,当前输入符号为a时应采取的动作:移进、归约、成功、出错。goto表是一个状态及非终结符的二维矩阵,goto[s,x]定义了在状态s下,面对非终结符x时应采取的动作:状态转换。

? 5)控制程序根据action[s,a]进行下

一步操作:(1)若action[s,a]=sj,

则将状态 j 推入栈顶,输入指针指向下一输入符号。(2)若

action[s,a]=rj,则按第j个产生归约,在分析栈栈顶弹出t个状态。然后根据呈现在栈顶的状态为si及归约后的非终结符A查goto表,如goto[si,A]=j,则将状态j推入栈顶。(3)若action[s,a]=acc,则分析成功结束,输入串合法。(4)若

action[s,a]或goto[s,A]为空,则分析过程出错,输入串不合法。

o 5、 项目需用仪器设备名称: PC机

一台,装有C/C++语言或Java语言的程序开发环境。

o 6、 所需主要元器件及耗材:无 o 7、 学时数:4

本文来源:https://www.bwwdw.com/article/56p3.html

Top