词法分析.docx
- 文档编号:24517947
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:14
- 大小:80.45KB
词法分析.docx
《词法分析.docx》由会员分享,可在线阅读,更多相关《词法分析.docx(14页珍藏版)》请在冰豆网上搜索。
词法分析
院系:
专业、年级:
课程名称:
编译原理
班级:
学号:
姓名:
指导教师:
2010年11月21日
08软件工程实验类别:
综合型
组员
学号
姓名
实验名称
实验一:
词法分析
实验室
9205
实
验
目
的
或
要
求
一、实验目的
通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。
并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。
并依次输出各个单词的内部编码及单词符号自身值。
二、实验要求
1、基本要求
识别保留字:
if、int、for、while、do、return、break、continue等等;单词种别码为1。
其他的都识别为标识符;单词种别码为2。
常数为无符号数;单词种别码为3。
运算符包括:
+、-、*、/、=、>、<等;单词种别码为4。
分隔符包括:
“,”“;”“(”“)”“{”“}”等;单词种别码为5。
2、扩充功能
增加保留字。
case、char、double等。
识别负数(浮点数)。
增加更复杂情况如>=、<=、!
=等两个字符的运算符。
处理注释“//”和“/**/”,包括存在干扰的“/***/”。
实
验
原
理
(
算
法
流
程
)
一、实验说明
本次实验所用语言为C#,开发环境为VisualStudio2008.。
采用事件驱动来完成相关操作。
可以通过两种方式来导入源程序。
一是直接导入cpp或者txt文件;二是直接在窗口里面敲入源代码进行分析。
二、实验原理
单击“开始分析”按钮后。
先会将整个源程序保存到一个str的字符串里面。
然后判断字符串的长度是否为0。
不为0则取出str的第一个字符,并调用分类函数(classify)进行分类,由一个全变量num记录种类。
接着进入由str的长度控制的循环,并根据不用的种类进行不同的操作。
保留字、标识符:
num为1时(第一个字符为字母),在不超过str.Length–1的情况下,读取下一个字符,同时把已读的字符存入token字符串中(后面会输出token),直到读取的字符不为字母或者当前字符位置(由j记录)超过str.Length–1(下面的其它情况中,读取时均会考虑此越界问题,因此下面的情况就不赘述了),最后再调用Check函数,检查token字符串是保留字还是其它标识符,并输出该字符串及对应的种别码再跳出该情况。
数字:
num为3时(当前字符为数字),读取情况同num为1类似,只是读取过程中会判断是有“.”,即浮点数。
同样,读取的字符不为数字或者“.”时,直接输出token及数字的种别码并跳出该情况。
运算符:
num为4时(当前字符为运算符)。
运算符可以是一个字符也可以是多个字符,同时“-”可以是减运算符也可以是负号,所以得多次单独读取下一个字符进行判断。
先读取下一个字符,若为数字,则会继续读到非数字(浮点数也有考虑)为止,最后输入负数及其种别码;若不为数字,则考虑两个运算符的情况(如“+=”),最后都输出token(一个字符的运算符两个的运算符却别表现在j上面)并跳出这种情况。
分隔符:
num为5时(当前字符为分隔符),由于分隔符只用一个字符,所以直接输出分隔符及对应的种别码,跳出该情况。
注释:
num为6时(当前字符为“/”,除运算或者注释)。
读取下一个字符,若为“/”则说明读到单行注释,就一直读到本行末;若为“*”,则说明读到多行注释的情况,同样一直读下去,知道遇到“*/”为止;剩下的情况则为除运算符,进行输出。
结束这种情况。
判断j 若为真,则读取下一个字符,并进行分类,再根据num重复上面的操作。 若为假,记录j后移以为,token清空,接着进入整个大循环,知道j 程 序 界 面 ( 效 果 图 ) 开始界面效果图 导入源程序分析后的效果图: 程 序 代 码 开发所用语言为C#。 附上的代码为各个按钮的响应事件(即文件Form1.cs)。 usingSystem;//命名空间 usingSystem.Collections.Generic; usingSystem.ComponentModel; usingSystem.Data; usingSystem.Drawing; usingSystem.Linq; usingSystem.Text; usingSystem.Windows.Forms; namespaceWinForm1 { publicpartialclassForm1: Form { intnum=0;//分类标记 charch='';//当前读到的字符 stringtoken="";//存已读字符 stringstr="";//保存整个源文件 publicForm1()//构造函数 { InitializeComponent(); } privatevoidForm1_Load(objectsender,EventArgse) { AboutBox1aboutBox=newAboutBox1();//关于对话框 aboutBox.StartPosition=System.Windows.Forms.FormStartPosition.CenterScreen; aboutBox.ShowDialog(); } privatevoidMenuItemAboutBox_Click(objectsender,EventArgse) { AboutBox1about=newAboutBox1(); about.StartPosition=System.Windows.Forms.FormStartPosition.CenterParent; about.ShowDialog(); } privatevoidbtn_Exit_Click(objectsender,EventArgse)//退出 { this.Close(); } privatevoidbtn_FileOpen_Click(objectsender,EventArgse)//导入源文件 程 序 代 码 { btn_InputByHand.Enabled=false; richTextBox1.Clear(); openFileDialog1.Filter="纯文本文件(*.txt)|*.txt|C/C++源文件(*.cpp)|*.cpp|所有文件(*.*)|*.*"; openFileDialog1.FilterIndex=1; if(openFileDialog1.ShowDialog()==DialogResult.OK) richTextBox1.LoadFile(openFileDialog1.FileName,RichTextBoxStreamType.PlainText); richTextBox1.ReadOnly=true; } privatevoidbtn_InputByHand_Click(objectsender,EventArgse)//手动输入 { richTextBox1.Clear(); richTextBox1.ReadOnly=false; btn_FileOpen.Enabled=false; } privatevoidbtn_reset_Click(objectsender,EventArgse)//重置按钮 { richTextBox1.Clear(); textBox1.Clear(); btn_FileOpen.Enabled=true; btn_InputByHand.Enabled=true; } publicvoidclassify()//分类 { if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z')))//字母 num=1;//种别码为1或2: 标识符 elseif(ch>='0'&&ch<='9')//数字 num=3;//种别码为3: 常数。 elseif(ch=='+'||ch=='-'||ch=='*'||ch=='='||ch=='<'||ch=='>'||ch=='! ') num=4;//种别码为4: 运算符 elseif(ch==','||ch==';'||ch=='('||ch==')'||ch=='{'||ch=='}'||ch==': ') num=5;//种别码为5: 分隔符 elseif(ch=='/')//处理换行 num=6; else num=0; } 程 序 代 码 publicvoidCheck(strings)//保留字与标识符 { if(s=="break"||s=="case"||s=="char"||s=="continue"||s=="default"|| s=="do"||s=="double"||s=="else"||s=="float"||s=="for"||s== "goto"||s=="if"||s=="int"||s=="long"||s=="return"||s== "short"||s=="struct"||s=="switch"||s=="while"||s=="void") textBox1.Text=textBox1.Text+"1,"+s+"\r\n"; else textBox1.Text=textBox1.Text+"2,"+s+"\r\n"; } publicintDealNote(inti,stringstr)//处理注释“/***/” { boolflag=true; i++; do { while(str[i]! ='*'&&i i++; i++; if(str[i]=='/'&&i flag=false; }while(flag&&i returni; } privatevoidbtn_begin_Click(objectsender,EventArgse)//开始分析 { str=richTextBox1.Text; intj=0; if(str.Length! =0) { ch=str[j]; classify(); } while(j { switch(num) { case1: //标识符 while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))&&j { 程 序 代 码 token=token+ch; ch=str[++j]; } Check(token); j--; break; case2: break; case3: //常数 while(ch>='0'&&ch<='9'&&j { token=token+ch; ch=str[++j]; } textBox1.Text=textBox1.Text+"3,"+token+"\r\n"; j--; break; case4: //运算符 charc=''; if(ch=='+'||ch=='-'||ch=='*'||ch=='<'||ch=='>'||ch=='! ') {//'-'为负数或减运算 c=str[j-1]; if(ch=='-'&&! ((c>='0'&&c<='9')||((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))))//'-'前面是数字或字母时,定位负号 { ch=str[++j]; while(ch>='0'&&ch<='9'&&j { token=token+ch; ch=str[++j]; } textBox1.Text=textBox1.Text+"3,-"+token+"\r\n"; j--; } else 程 序 代 码 { token=token+ch; ch=str[++j]; if(ch=='='||ch=='+'||ch=='-') token=token+ch; else j--; textBox1.Text=textBox1.Text+"4,"+token+"\r\n"; } } else textBox1.Text=textBox1.Text+"4,"+ch+"\r\n"; break; case5: //分隔符 token=token+ch; textBox1.Text=textBox1.Text+"5,"+token+"\r\n"; break; case6: //注释 ch=str[++j]; if(ch=='/')//注释"//" while(ch! ='\n'&&j ch=str[++j]; elseif(ch=='*')//注释"/**/" j=DealNote(j,str); else textBox1.Text=textBox1.Text+"4,\\"+"\r\n"; break; default: break; } if(j { ch=str[++j]; classify(); } else j++; token=""; } } } } 实 验 结 果 分 析 及 心 得 体 会 程序运行结果: 心得体会: 本次实验,完成实验要求并实现一些拓展功能。 完成这次实验,让我对编译原理有了更深的认识,特别是词法分析,对程序源代码的运行机制有一定的了解。 在写代码过程中也遇到一些,在老师和同学的帮助下得到很好的解决。 同时,在完成实验基本要求后,很感谢老师鼓励我去实现一些拓展功能,而不仅仅满足当前完成的任务。 组 员 分 工 个人独立完成。 成 绩 评 定 教师签名: 2010年11月日
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 词法 分析