C语言语法分析器
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
break; case'>': token[m++]=ch;; ch=prog[p++];//读取下一个字符; if(ch=='=') { syn=24;//将>=的中别码=>syn; token[m++]=ch;; } else { syn=23; p=p-1;//回退一个字符; } break; case':': token[m++]=ch;; ch=prog[p++];//读取下一个字符; if(ch=='=') { syn=18; token[m++]=ch;; } else { syn=17; p=p-1;//回退一个字符; } break; case'+': syn=13;token[0]=ch; break; case'-': syn=14;token[0]=ch; break; case'*': syn=15;token[0]=ch; break; case'/': syn=16;token[0]=ch; break; case'=': syn=25;token[0]=ch; break; 8
12
目
录
一、设计题目………………………………………………………14
二、运行环境(软、硬件环境)…………………………………1 4
三、算法设计的思想………………………………………………14
四、算法流程图……………………………………………………15
五、算法设计分析…………………………………………………16
case';': syn=26;token[0]=ch; break; case'(': syn=27;token[0]=ch; break; case')': syn=28;token[0]=ch; break; case'#': syn=0;token[0]=ch; break; default: syn=-1; break; } } /////////////////////////////////////////// //主函数 /////////////////////////////////////////// void main() { char A; cout<<"*****************************************"<<endl; loop: p=0; cout<<"*****************************************"<<endl; printf("please input string (以#结束):\n"); do { scanf("%c",&ch); prog[p++]=ch;//输入源程序字符串,送到缓冲区 prog[p++]中; } while(ch!='#'); p=0; do { scaner(); switch(syn) { case 11:cout<<"( "<<syn<<","<<sum<<" )"<<endl;//输出(数的二 元组) ; 9
(七)运行结果分析
10
11
(八)收获及体会
为期一周的编译原理课程设计结束了,我们这次的任务是做一个编译 器。这次课程设计我做的是用 C++编写词法分析器,编译程序是在单词的 级别上来分析和翻译源程序的,因此词法分析是编译的基础。 通过此次实验, 我基本上了解了词法分析器的工作原理和功能以及实现 方法。进一步学习了 C 语言的知识。此次实验,遇到的最大的一个问题就 是用了 C++语言里的 cin 输入字符串,结果空格符号直接给预处理掉了, 导致开始的关键字与字母连接时会不识别,最后通过查阅,终于找到了这 个问题的所在,最后通过 C 语言里的 Scanf 函数来输入,就解决了这个问 题。总而言之,本程序实现了所要求的全部功能。美中不足的是程序中没 有运用文件,对文件的掌握不是很到位,相信经过以后的程序训练,会熟 练的运用文件来编程。
四、算法流程图……………………………………………………5
五、算法设计分析…………………………………………………5
六、源代码…………………………………………………………6
七、运行结果……………………………………………………11
八、收获及体会……………………………………………………12
2
(一)设计题目
置初值
调用扫描子程序
输出单词二元组
否
输入串结束?
是
结束
(2)程序需要用到的主要变量为 syn,token 和 sum。 2.扫描子程序的算法思想 首先设置 3 个变量: (1)token 用来存放构成单词符号的字符串; (2)sum 用来存放整型单词(3)syn 用来存放单词符号的种别码。
4
(四)算法的流程图
(四)算法的流程图
14
15
(五)算法设计分析
语法分析: a) ∵E=>E+T=>E+T*F=>E+T*(E)即有 E=>E+T*(E)存在左递归。用直接改 写法消除左递归,得到如下: E TE’ E’ +TE’ | −TE’|ε T FT’ T’ *FT’ | /FT’|ε F (E) | i b) 对于以上改进的方法。可得: 对于 E’: FIRST( E’ )=FIRST(+TE’)∪FIRST(-TE’)∪{ε}={+,−,ε} 对于 T’: FIRST( T’ )=FIRST(*FT’)∪FIRST(/FT’)∪{ε}={*,∕,ε} 而且: FIRST( E ) = FIRST( T ) = FIRST( F )=FIRST((E)) ∪ FIRST(i)={(,i } 由此我们容易得出各非终结符的 FOLLOW 集合如下: FOLLOW( E )= { ),#} FOLLOW(E’)= FOLLOW(E)={ ),#} FOLLOW( T )= FIRST(E’)\ε∪FOLLOW(E’)={+,−,),#} FOLLOW( T’ ) = FOLLOW( T ) ={+,−,),#}
if(strcmp(token,rwtab[n])==0) { syn=n+1;//给出 syn 值; break; } } else if(ch>=48&&ch<=57/*ch 为数字字符*/) { while(ch>=48&&ch<=57/*ch 为数字字符*/) { sum=sum*10+ch-'0'; ch=prog[p++];//读取下一个字符; } p=p-1;//回退一个字符; syn=11; } else switch(ch) { case '<': m=0;token[m++]=ch; ch=prog[p++];//读取下一个字符; if(ch=='>') { syn=21; token[m++]=ch; } else if(ch=='=') { syn=22; token[m++]=ch; } else { syn=20; p=p-1;//回退一个字符; } 7
5
首先设置 3 个变量: (1)token 用来存放构成单词符号的字符串; (2)sum 用来存放整型单词(3)syn 用来存放单词符号的种别码。
(六)源代码
#include<stdio.h> #include<iostream.h> #include<string.h> #define MAX 150 //词法分析表的最大容量 #define MAXBUF 255//缓冲区的最大缓冲量 char prog[MAXBUF],token[MAX]; char ch; int syn,p,m,n,sum; char *rwtab[6]={"begin","if","then","while","do","end"}; /////////////////////////////////////////////// //词法分析程序 /////////////////////////////////////////////// void scaner() { for(m=0;m<MAX;m++) token[m]=NULL; m=0;sum=0; ch=prog[p++]; while(ch==' ') ch=prog[p++];//读取下一个字符; if(ch>=65&&ch<=122 /*是字母字符*/) { while(ch>=65&&ch<=122||ch>=48&&ch<=57)/*为字母字 符或数字字符*/ { token[m++]=ch; ch=prog[p++];//读取下一个字符; } token[m++]='\0'; p=p-1; syn=10; for(n=0;n<6;n++) 6
break; case -1:cout<<"error"<<endl; break; default:cout<<"( "<<syn<<","<<token<<" )"<<endl;//输出(其他单 词二元组); } }while(syn!=0); cout<<"*****************************************"<<endl; cout<<"请确定是否继续使用程序:S 为继续;其它为退出;"<<endl; cout<<"是否继续:"; cin>>A; switch(A) { case 'S': goto loop; default: cout<<"*****************************************"<<endl; cout<<"Thank you ! Bye Bye !"<<endl; cout<<"*****************************************"<<endl; break; } }
郑州轻工业学院
编译原理课程设计总结报告
设计题目:词法分析器(语法分析器) 学生姓名: 系 专 班 学 别: 业: 级: 号:
指导教师:
20013 年 6 月 2 日
1
目
录
一、设计题目………………………………………………………3
wenku.baidu.com
二、运行环境 (软、 硬件环境) …………………………………… 3
三、算法设计的思想………………………………………………3
六、源代码…………………………………………………………17
七、运行结果……………………………………………………26
八、收获及体会……………………………………………………27
13
(一)设计题目
语法分析器
(二)运行环境
Visual C++.6.0
(三)算法设计的思想
利用 C 语言编制递归下降分析程序,并对简单语言进行语法分析。 待分 析的简单语言得语法: EE+T | E-T | T TT*F | T/F |F F(E) | i 输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打 印“Accept! Right Expression!” ,否则输出“Error!!!” 。
main
变量初始化
忽略空格
文件结束否
结束
否
其它字符 拼字符串
是否是关
数字
对不同符号给
拼数 syn=10 syn=11
出相应的 syn 值
报错
syn 为对应单 词的种别码
结束
(五)算法设计分析
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符 号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的 单词符号。 其中初值包括如下两个方面: (一)关键字表的初值。关键字作为特殊标示 符处理,把它们预先安排到一张表格中(称为关键字表) ,当扫描程序识别 出标识符时,查关键字表。如果能查到匹配的单词,则该单词为关键字, 否则为一般的标识符。关键字表为一个字符串数组,其描述如下: Char*rwtab[6]={“begin”,”if”,”then”,”while”,”do”,”end”}; (2)程序需要用到的主要变量为 syn,token 和 sum。 2.扫描子程序的算法思想
词法分析器
(二)运行环境
Visual C++.6.0
(三)算法设计的思想
源程序
词法分析器
Token 串
各种单词符号对应的种别码:
单词符号 begin if then while do end letter(letter|digit)* digitdigit* + * / 种别码 1 2 3 4 5 6 10 11 13 14 15 16 单词符号 : := < <> <= > >= = ( ) ; # 种别码 17 18 20 21 22 23 24 25 26 27 28 0
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符 号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的 单词符号。 1. 主程序示意图: 主程序示意图如下;其中初值包括如下两个方面:
3
(1) 关键字表的初值。 关键字作为特殊标示符处理,把它们预先安排到一张表格中 (称为关键字表) ,当扫描程序识别出标识符时,查关键字表。 如果能查到匹配的单词,则该单词为关键字,否则为一般的标 识符。关键字表为一个字符串数组,其描述如下: Char*rwtab[6]={“begin”,”if”,”then”,”while”,”do”,”end”};