词法分析.docx
- 文档编号:10463328
- 上传时间:2023-02-13
- 格式:DOCX
- 页数:17
- 大小:126.16KB
词法分析.docx
《词法分析.docx》由会员分享,可在线阅读,更多相关《词法分析.docx(17页珍藏版)》请在冰豆网上搜索。
词法分析
广州大学学生实验报告
开课学院及实验室:
计算机科学与工程实验室2012年4月24日
学院
计算机学院
年级/专业/班
计科091
姓名
学号
实验课程名称
编译原理实验
成绩
实验项目名称
词法分析
指导老师
(***报告只能为文字和图片,老师评语将添加到此处,学生请勿作答***)
一、实验目的
设计实现一个词法分析程序,加深对词法分析原理的理解
二、实验内容
(1)设一小型编译程序关于高级语言有如下的规定:
高级语言程序具有四种基本结构:
顺序结构﹑选择结构﹑循环结构和过程。
为了便于掌握编译的核心内容,突出重点,简化编译程序的结构,同时又涵盖高级语言程序的基本结构,我们选取赋值语句﹑if语句和while语句作为前三种结构的代表,略去了过程结构。
实际上,上述三种语句已经基本满足了高级语言的程序设计。
因此,我们仅考虑由下面产生式所定义的程序语句:
S→ifBthenSelseS︱whileBdoS︱beginLend︱A
L→S;L︱S
A→i:
=E
B→B∧B︱B∨B︱¬ B︱(B)︱iropi︱i
E→E+E︱E*E︱(E)︱i
其中,各非终结符的含义如下:
S——语句;
L——语句串;
A——赋值句;
B——布尔表达式;
E——算术表达式。
各终结符的含义如下:
i ——整型变量或常数,布尔变量或常数;
rop ——六种关系运算符的代表;
; ——起语句分隔符作用;
:
= ——赋值符号;
¬ ——逻辑非运算符“not”;
∧ ——逻辑与运算符“and”;
∨ ——逻辑或运算符“or”;
+ ——算术加运算符;
* ——算术乘运算符;
( ——左括号;
) ——右括号。
注意,六种关系运算符分别为
<:
小于<=:
小于等于<>:
不等于
>:
大于>=:
大于等于=:
等于
关于表达式的运算,我们规定由高到低优先顺序为算术运算、关系运算、布尔运算;并且服丛左结合规则。
算术运算符优先级的顺序依次为“()”﹑“*”﹑“+”;布尔运算符优先级的顺序依次为“¬ ”﹑“∧”﹑“∨”;六个关系运算符优先级相同。
我们规定的程序是由一条语句或由begin和end嵌套起来的复合语句组成的,并且规定在语句末要加上“#~”表示程序结束。
下面给出的是符合规定的程序示例:
begin
A:
=A+B*C;
C:
=A+2;
whileA whileA>Bdo ifM=NthenC: =D elsewhileA<=Ddo A: =D end#~ (2)该小型编译程序关于单词的内部定义 由于我们规定的程序语句中涉及单词较少,故在词法分析阶段忽略了单词输入错误的检查,而将编译程序的重点放在中间代码生成阶段。 词法分析器的功能是输入源程序,输出单词符号。 我们规定输出的单词符号格式为如下的二元式: (单词种别,单词自身的值) 我们对常量,变量,临时变量,保留关键字(if、while、begin、end、else、then、do等),关系运算符,逻辑运算符,分号,括号等,规定其内部定义如表1所示。 表1关于单词的内部定义 三、实验原理 通过对输入的字符串进行分析,并通过与内部定义表进行匹配,分析所输入的字符串中的内容,并输出各个单词字符的(单词种别,单词自身的值)二元式. 四、实验设备 Windows7,VS2008 五、实验要求 请对下列程序进行词法分析,输出单词的种别编码和值: begin begin begin a: =1 end; begin b: =1 end; q: =10 end; x: =9; y: =11; z: =12 end #~ 六、实验程序与分析 由上面的内部定义的单词表,可以知道当程序代码输入时,词法分析器的分析步骤如下: (1)从输入文件中读入一个字节,如果是空字节,则继续输入下一个字节,直到遇到一个非空字节; (2)当一个空字节后,读入一个字节是一字母,则继续读取下一个字节,直到读入字节内容不是字母或数字就停止,然后判断这前读入的字符串是否为保留字或是逻辑关系符,如果不是则为变量; (3)当上一个读入的字节内容并非是字母时,则现在读入的字节内容是一个数字,则继续读入,直到遇到非字母或数字,就停止读入,然后判断之前读入的是否只要一串数字,如果是则为整常量,否则这是非词法器能分析内容 (4)当读入的是一个字节内容不是数字或字字母,则查表,是否有它的(单词种别,单词自身的值),没有则输出非词法器能分析内容; 根据上面步骤对程序代码的分析如下: begin(4,null) begin(4,null) begin(4,null) a: =1(15,a),(38,null),(57,1) end;(6,null),(8,null) begin(4,null) b: =1(15,b),(38,null),(57,1) end;(6,null),(8,null) q: =10(15,q),(38,null),(57,10) end;(6,null),(8,null) x: =9;(15,x),(38,null),(57,9) y: =11;(15,y),(38,null),(57,11) z: =12(15,z),(38,null),(57,12) end(6,null) #~程序结束 七、程序部分代码与截图 //保留字结构; typedefstructstack { CStringstr[mmax]; CStringcode[mmax]; }List; intInitList(List&L) { L.str[0]="if"; L.code[0]="0"; L.str[1]="then"; L.code[1]="1"; L.str[2]="else"; L.code[2]="2"; L.str[3]="while"; L.code[3]="3"; L.str[4]="begin"; L.code[4]="4"; L.str[5]="do"; L.code[5]="5"; L.str[6]="end"; L.code[6]="6"; L.str[7]="and"; L.code[7]="39"; L.str[8]="or"; L.code[8]="40"; L.str[9]="not"; L.code[9]="41"; return1; } //读一个字符 intGetChar(CStringm_str,char&m_ch,int&m_length) { m_ch=m_str[m_length]; if(m_ch==EOF) return0; else { m_length++; return1; } } //判断是否为一个英文字母 intIsLetter(charm_ch) { if((m_ch>='a')&&(m_ch<='z')) //if(isalpha(m_ch)) return1; else return0; } //判断是否为一个数字 intIsDigit(charm_ch) { if((m_ch>='0')&&(m_ch<='9')) //if(isdigit(m_ch)) return1; else return0; } //读入字符存入数组 voidConcatenation(CString&m_token,charm_ch) { m_token.Insert(m_token.GetLength(),m_ch); } //判断字符是否为空格 intIsSpace(charm_ch) { if(isspace(m_ch)) return1; else return0; } //滤除空格 voidGetBe(CStringm_str,char&m_ch,int&m_length) { do { GetChar(m_str,m_ch,m_length); }while(IsSpace(m_ch)&&(m_ch! =EOF)); } //扫描指针回退一个字符 voidRetract(char&m_ch,int&m_length) { m_length--; m_ch='\0'; } //查看是否为保留字 intReserve(CString&m_token,ListL,CString&m_strtwo) { for(inti=0;i { if(! m_token.Compare(L.str[i])) { m_strtwo.Insert(m_strtwo.GetLength(),_T("<")); m_strtwo.Insert(m_strtwo.GetLength(),L.code[i]); m_strtwo.Insert(m_strtwo.GetLength(),_T(",")); m_strtwo.Insert(m_strtwo.GetLength(),L.str[i]); m_strtwo.Insert(m_strtwo.GetLength(),_T(">")); //cout<<"<"; //cout< //cout<<">"< return1; } } m_strtwo.Insert(m_strtwo.GetLength(),_T("<56")); m_strtwo.Insert(m_strtwo.GetLength(),_T(",")); m_strtwo.Insert(m_strtwo.GetLength(),m_token); m_strtwo.Insert(m_strtwo.GetLength(),_T(">")); //cout<<"<"; //cout<<"56,"< //cout<<">"< return0; } //清除储存字符串 voidEmpty(CString&m_str) { m_str.Empty(); } voidmylexmain(CStringm_str,CString&m_strtwo) { inttemp=m_str.GetLength(); inttemptwo=m_strtwo.GetLength(); intlength=0; intlengthtwo=0; charch;//读入的一个字符 //计录存数组个数 CStringtoken(""); //cout< intflag;//标志 ListL; InitList(L); //cout<<"************词法分析开始**************"< while(length { flag=2; GetBe(m_str,ch,length); //判断结束 if(ch=='#') { GetChar(m_str,ch,length); if(ch=='~') { //cout< //cout<<"************分析结束*************"< break; } Retract(ch,length); ch='#'; } //实现保留字与标识符的判别 if(IsLetter(ch)) { do{ Concatenation(token,ch); GetChar(m_str,ch,length); }while(IsLetter(ch)||IsDigit(ch)); Retract(ch,length); flag=Reserve(token,L,m_strtwo); } elseif(IsDigit(ch))//实现整常数的判别 { do{ Concatenation(token,ch); GetChar(m_str,ch,length); }while(IsDigit(ch)); flag=Reserve(token,L,m_strtwo); Retract(ch,length); } else//分析其它字符 { switch(ch) { case';': m_strtwo.Insert(m_strtwo.GetLength(),_T("<8,null>")); //cout<<"<8,null>"< break; case'#': m_strtwo.Insert(m_strtwo.GetLength(),_T("<10,null>")); //cout<<"<10,null>"< break; case'+': m_strtwo.Insert(m_strtwo.GetLength(),_T("<34,null>")); //cout<<"<34,null>"< break; case'*': m_strtwo.Insert(m_strtwo.GetLength(),_T("<36,null>")); //cout<<"<36,null>"< break; case': ': GetChar(m_str,ch,length); if(ch=='=') { m_strtwo.Insert(m_strtwo.GetLength(),_T("<38,null>")); ///cout<<"<38,null>"< break; } else Retract(ch,length);// case'(': m_strtwo.Insert(m_strtwo.GetLength(),_T("<48,null>")); //cout<<"<48,null>"< break; case')': m_strtwo.Insert(m_strtwo.GetLength(),_T("<49,null>")); //cout<<"<49,null>"< break; default: m_strtwo.Insert(m_strtwo.GetLength(),_T("<词不在检测范围内,NULL>")); //cout<<"你输入的词不在检测范围内! "< } } if(flag==1) { //cout< Empty(token); } elseif(flag==0) { //cout< Empty(token); } } return; } voidCmfclexDlg: : OnBnClickedButton1() { //TODO: 在此添加控件通知处理程序代码 CStrings; UpdateData(true); s=m_sEdit_Content.GetString(); mylexmain(s,strtwo); GetDlgItem(IDC_STATIC_INPUT)->SetWindowText(strtwo); strtwo.Empty(); s.ReleaseBuffer(); } 截图: 八、总结心得 通过实验可以知道词法分析的分析思路与步骤,进一步深入学习了词法分析,而对上面代码的分析,还有几处不明白,如对变量是选临时变量还是变量都难以决定,而什么复合语句之类的,也是不明白,希望以后进一步学习。 九、
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 词法 分析
![提示](https://static.bdocx.com/images/bang_tan.gif)