课程实验报告课程名称:《编译原理》专业班级:计算机科学与技术11级10班学号:XXXXXXX姓名:X X指导教师:**报告日期:2014年6月16日计算机科学与技术学院目录目录 (2)1 实验一词法分析 (3)1.1实验目的 (3)1.2实验要求 (3)1.3算法思想 (4)1.4实验程序设计说明 (5)1.5词法分析实现 (6)1.6词法实验结果及结果分析 (12)2 实验二语法分析 (13)2.1 实验目的 (13)2.2 实验要求 (13)2.3 算法思想 (13)2.4 实验程序设计说明 (15)2.5 语法分析实现 (15)4 实验中遇到的问题及解决 (22)参考资料 (23)1 实验一词法分析1.1 实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
1.2 实验要求1、待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。
(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。
空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。
2、各种单词符号对应的种别码:3、词法分析程序的功能:输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……1.3 算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
1、主程序示意图:主程序示意图如图1所示。
其中初始包括以下两个方面:⑴关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};开始置初值调用扫描子程序输出单词二元组否输入串结束?是结束图1 主程序示意图(2)程序中需要用到的主要变量为syn,token和sum2、扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。
扫描子程序主要部分流程如图2所示。
图2 扫描子程序流程图1.4 实验程序设计说明1、数据结构的设计先来看看WORD 结构的设计: typedef struct {int typenum; //用于存储该字符串的种别码; char *word; //用于存储字符串; }这个词法分析中,我们要将我们识别到的字符串输出他们,而且还要将他们的相应的种别码输出,因此我们得用一个结构体来将这两个属性放在一个结构体中。
开始变量初始化忽略空格是否文件结束?否返回是拼数拼字符串字母 Syn=11关键字?Syn=10否是Syn 为对应关键字的种别码对不同符给出相应的syn 值报错其他符号运算符界符等返回数字2、算法的设计首先将输入端的字符串读入然后进行前期的处理,如去掉空白符号。
之后在一个字符一个字符的进行处理,判断下一个字符串所属类型,然后给出相应类型的种别码,返回给主函数进行输出。
其中主要部分就是分类属性的判断以及判断之后不同属性种别码的赋值,这就是整个程序中的主要部分。
1.5 词法分析实现【使用C语言实现:】#include <stdio.h>#include <stdlib.h>#include <string.h>#include <windows.h>#define _KEY_WORD_END "waiting for your expanding" /*定义关键字结束标志*/ HANDLE gh_std_out; //标准输出设备句柄typedef struct /*单词二元组的结构,可以根据需要继续扩充*/{int typenum;char * word;} WORDS;char input[255]; /*输入缓冲区*/char token[255]="";/*单词缓冲区*/int p_input;/*输入缓冲区指针*/int p_token;/*单词缓冲区指针*/char ch; /*当前读入字符*/char* KEY_WORDS[]={"begin","if","then","while","do","end",_KEY_WORD_END};/*可扩充的关键字数组*/WORDS* scaner();/*词法扫描函数,获得一个单词*/void WriteKeyWord(char *str);/*高亮输出文字*/int main(){int over=1;WORDS* oneword=new WORDS;printf("Enter Your words(end with #):\n");scanf("%[^#]s",input);/*读入源程序字符串到缓冲区,以#结束,允许多行输入*/getchar();p_input=0;printf("Your words:\n%s\n",input);printf("The sequence as follow:\n( 字符\t, 种别码)\n");while(over<1000&&over!=-1){/*对源程序进行分析,直至结束符#*/oneword=scaner();/*获得一个新单词*/if(oneword->typenum<1000){printf("( ");WriteKeyWord(oneword->word);printf("\t,%5d )\n",oneword->typenum);/*打印种别码和单词自身的值*/ }over=oneword->typenum;}return 0;}/***************需要用到的自编函数参考实现*从输入缓冲区读取一个字符到ch中**************************/char m_getch(){ch=input[p_input];p_input=p_input+1;return (ch);}/***************去掉空白符**************/void getbc(){while(ch==' '||ch==10){ch=input[p_input];p_input=p_input+1;}}/***************拼接单词**************/void concat(){token[p_token]=ch;p_token=p_token+1;token[p_token]='\0';}/***************判断是否为字母**************/int letter(){if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')return 1;else return 0;}/***************判断是否为数字**************/int digit(){if(ch>='0'&&ch<='9')return 1;else return 0;}/***************检索关键字表格**************/int reserve(){int i=0;while(strcmp(KEY_WORDS[i],_KEY_WORD_END)){ if(!strcmp(KEY_WORDS[i],token)){return i+1;}i=i+1;}return 10;}/***************回退一个字符**************/void retract(){p_input=p_input-1;}/*****************数字转换成二进制****************/char* dtb(){/*Enter Your Code!*/return NULL;}/***************词法扫描函数**************/WORDS* scaner(){WORDS* myword=new WORDS;myword->typenum=10;myword->word="";p_token=0;m_getch();getbc();if(letter()){while(letter()||digit()){concat();m_getch();}retract();myword->typenum=reserve();myword->word=token;return(myword);}else if(digit()){while(digit()){concat();m_getch();}retract();myword->typenum=11;myword->word=token;return(myword);}else switch(ch){case '=': m_getch();if (ch=='='){myword->typenum=39;myword->word="==";return(myword);}retract();myword->typenum=21;myword->word="=";return(myword);break;case '+':myword->typenum=13;myword->word="+";return(myword);break;case '-':myword->typenum=14;myword->word="-";return(myword);break;case '*':myword->typenum=15;myword->word="*";return(myword);break;case '/':myword->typenum=16;myword->word="/";return(myword);break;case '(':myword->typenum=27;myword->word="(";return(myword);break;case ')':myword->typenum=28;myword->word=")";return(myword);break;case '[':myword->typenum=29;myword->word="[";return(myword);break;case ']':myword->typenum=30;myword->word="]";return(myword);break;case '{':myword->typenum=31;myword->word="{";return(myword);break;case '}':myword->typenum=32;myword->word="}";return(myword);break;case ',':myword->typenum=33;myword->word=",";return(myword);break;case ':':m_getch();if (ch=='='){myword->typenum=18;myword->word=":=";return(myword);}retract();myword->typenum=17;myword->word=":";return(myword);break;case ';':myword->typenum=26;myword->word=";";return(myword);break;case '>': m_getch();if (ch=='='){myword->typenum=24;myword->word=">=";return(myword);}retract();myword->typenum=23;myword->word=">";return(myword);break;case '<': m_getch();if (ch=='='){myword->typenum=22;myword->word="<=";return(myword);}retract();myword->typenum=20;myword->word="<";return(myword);break;case '!': m_getch();if (ch=='='){myword->typenum=21;myword->word="!=";return(myword);}retract();myword->typenum=-1;myword->word="ERROR";return(myword);break;case '\0':myword->typenum=1000;myword->word="OVER";return(myword);break;default:myword->typenum=-1;myword->word="ERROR";return(myword);}}/* 函数功能: 高亮显示指定字符串*/void WriteKeyWord(char *str){COORD pos;CONSOLE_SCREEN_BUFFER_INFO csbi;DWORD len; //指向变量的指针,用来存放字符的实际数目WORD att=FOREGROUND_GREEN | FOREGROUND_INTENSITY;gh_std_out = GetStdHandle(STD_OUTPUT_HANDLE); //获取标准输出设备句柄if (GetConsoleScreenBufferInfo(gh_std_out, &csbi)){pos.Y=csbi.dwCursorPosition.Y;pos.X=csbi.dwCursorPosition.X;}SetConsoleCursorPosition(gh_std_out,pos);printf("%s ",str);FillConsoleOutputAttribute(gh_std_out,att,strlen(str),pos,&len);}1.6 词法实验结果及结果分析输入begin x:=9: if x>9 then x:=2*x+1/3; end #程序输出序列的结果如下图3所示:图3 程序运行结果2 实验二语法分析2.1 实验目的编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。