实验一词法分析报告

实验一、词法分析实验

专业:商业软件工程三班       姓名:郑锦诚      学号:201506110198

一、实验目的

词法分析是编译的第一阶段,它的主要任务是从左至右逐个字符地对源程序进行扫描,产生一个个单词序列,用于语法分析。

二、实验内容和要求

让用户输入一段程序段,然后逐个读取字符,将它们拼在一起,获取一个有意义的单词或符号,识别出单词或符号种别以及自身的值,并输出。

各种单词符号对应的种别码:

单词符号

种别码

单词符号

种别码

begin

1

:

17

if

2

:=

18

then

3

<

20

while

4

<=

21

do

5

<>

22

end

6

>

23

l(l|d)*

10

>=

24

dd*

11

=

25

+

13

;

26

-

14

(

27

*

15

)

28

/

16

#

0

三、实验方法、步骤及结果测试

  1. 1.      源程序名:压缩包文件(rarzip)中源程序名词法分析.c

可执行程序名:词法分析.exe

  1. 2.      原理分析及流程图

主要总体设计问题:本次实验程序是用顺序存储结构,关键函数为mor,没有参数,也没有返回值,全用全局变量来实现运行代码,多次使用循环语句while、do whlie以及for,也使用了判断语句if、else判断是否为符号时使用了switch语句进行执行判断。

 

  1. 3.      主要程序段及其解释:   
void mor()//主要函数的调用

{   

    sum=0;  //先把sum赋值为0

      ch=a[p++];  //把有程序段数组a的字符赋给ch,p再加一

    m=0;      //把m赋值为0

    while((ch==' ')||(ch=='\n')||(ch=='\t'))   ch=a[p++];  //判断ch是否为空格,若是则进行判断下一个字符,p再加一

    if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))) 

    {//判断字符ch是否是字母,若是则赋值给数组b,ch指向判断下一个字符是否是字母或是数字,并且p加一

while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) 

        { 

            b[m++]=ch; 

            ch=a[p++]; 

        }   

           p--; //循环结束后,p减一,为了防止漏掉字符

           syn=10; //先把syn赋值为10,再进行判断是否是保留字或是关键字

           b[m++]='\0';//并把数组b的下一位赋值为\0,这样防止系统出现混乱

           for(n=0;n<6;n++)  //循环6次进行判断是否为保留字

              if(strcmp(b,word[n])==0)    //关键字数组比较,相同则表示为关键字,种别码即为下标值加一

              {

                     syn=n+1; 

                     return; 

              } 

    }                                  

    else if((ch>='0')&&(ch<='9'))  //或者字符ch是数字的

  {  

       while((ch>='0')&&(ch<='9'))  //再次判断下一个字符是否为数字

       { 

           sum=sum*10+ch-'0';    //将字符型转化为整形sum

           ch=a[p++];  //字符ch指向下一个程序段数组a的字符

       } 

       p--;  //循环结束后,p减一,为了防止漏掉字符

       syn=11;  //数字的种别码是11

    } 

    else    //else语句内识别除关键字、标识符、数字以外的其他字符

    {  

        switch(ch) 

        { 

        case '+':  //字符ch是+的,syn赋值为13

            syn=13; 

                  b[m++]=ch;  //字符ch指向程序段数组a的下一个字符,p加一       

            break; 

        case '-':   /字符ch是-的,syn赋值为14

                  syn=14;

            b[m++]=ch;//字符ch指向程序段数组a的下一个字符,p加一

            break;

           case '*': 

            syn=15; 

            b[m++]=ch;//字符ch指向程序段数组a的下一个字符,p加一 

            break; 

        case '/': 

            syn=16; 

            b[m++]=ch; /字符ch指向程序段数组a的下一个字符,p加一 

            break; 

        case ':': 

            b[m++]=ch; 

            ch=a[p++];//字符ch指向程序段数组a的下一个字符,p加一 

                  if(ch=='=')  //判断字符ch是否为=,若是则赋值到数组b中

                  { 

                         syn=18; 

                         b[m++]=ch; 

                  } 

                  else  //否则赋值为18,再p减一

                  {  

                         syn=18; 

                         p--; 

                  } 

                  break;

           case '!': //为!则结束程序

                  syn=-2;

                  break;

        default:  //输入一个错误的字符的时候

            syn=-1; 

            break; 

        } 

    } 

    b[m++]='\0';  //把数组b的下一位赋值为\0

}       运行结果及分析

四、实验运行结果

结果符合预期,词法分析程序先识别字母if进行判断,符合字符数组Word的保留字进行输出种别码以及自身的值,遇到空格就指向下一位,从而执行i,以此类推,当识别到!时程序结束。

 

五、 实验总结

难点问题:1.编译时出现死循环或不循环。

          2.输入保留字或关键字时,输出的结果没有符合预期,有时保留字变成关键字,关键字变成保留字。

解决方法:1.循环嵌套出错以及循环条件&&,||的不规范使用导致的,已修改好。

          2.在数组b的下一位等于\0,就可以解决了。

心得体会:经过这次的实践,我认识到自己的不足以及粗心,在今后的学习道路上相信会更加的出彩,多找到自己的不足,才能更好的加强自己的能力。

转载于:https://www.cnblogs.com/04JC/p/5955717.html

【问题描述】 请根据给定的文法设计并实现词法分析程序,从源程序中识别出单词,记录其单词类别和单词值,输入输出及处理要求如下: (1)数据结构和与语法分析程序的接口请自行定义;类别码需按下表格式统一定义; (2)为了方便进行自动评测,输入的被编译源文件统一命名为testfile.txt(注意不要写错文件名);输出的结果文件统一命名为output.txt(注意不要写错文件名),结果文件中每行按如下方式组织: 单词类别码 单词的字符/字符串形式(中间仅用一个空格间隔) 单词的类别码请统一按如下形式定义: 单词名称 类别码 单词名称 类别码 单词名称 类别码 单词名称 类别码 标识符 IDENFR else ELSETK - MINU = ASSIGN 整形常量 INTCON switch SWITCHTK * MULT ; SEMICN 字符常量 CHARCON case CASETK / DIV , COMMA 字符串 STRCON default DEFAULTTK < LSS ( LPARENT const CONSTTK while WHILETK GRE [ LBRACK char CHARTK scanf SCANFTK >= GEQ ] RBRACK void VOIDTK printf PRINTFTK == EQL { LBRACE main MAINTK return RETURNTK != NEQ } RBRACE if IFTK + PLUS : COLON 【输入形式】testfile.txt中的符合文法要求的测试程序。 【输出形式】要求将词法分析结果输出至output.txt中。 【特别提醒】(1)读取的字符串要原样保留着便于输出,特别是数字,这里输出的并不是真正的单词值,其实是读入的字符串,单词值需另行记录。 (2)本次作业只考核对正确程序的处理,但需要为今后可能出现的错误情况预留接口。 (3)在今后的错误处理作业中,需要输出错误的行号,在词法分析的时候注意记录该信息。 (4)单词的类别和单词值以及其他关注的信息,在词法分析阶段获取后,后续的分析阶段会使用,请注意记录;当前要求的输出只是为了便于评测,完成编译器中无需出现这些信息,请设计为方便打开/关闭这些输出的方案。 【文法定义】请到“2020年文法定义(用于查看文法,不计入成绩)”作业中查看文法 【样例输入】 coNst int cONst1 = 001, const2 = -100; const char const3 = '_'; int change1; char change3; int gets1(int var1,int var2){ change1 = var1 + var2; return (change1); } void main(){ printf("Hello World"); printf(gets1(10, 20)); } 【样例输出】 CONSTTK coNst INTTK int IDENFR cONst1 ASSIGN = INTCON 001 COMMA , IDENFR const2 ASSIGN = MINU - INTCON 100 SEMICN ; CONSTTK const CHARTK char IDENFR const3 ASSIGN = CHARCON _ SEMICN ; INTTK int IDENFR change1 SEMICN ; CHARTK char IDENFR change3 SEMICN ; INTTK int IDENFR gets1 LPARENT ( INTTK int IDENFR var1 COMMA , INTTK int IDENFR var2 RPARENT ) LBRACE { IDENFR change1 ASSIGN = IDENFR var1 PLUS + IDENFR var2 SEMICN ; RETURNTK return LPARENT ( IDENFR change1 RPARENT ) SEMICN ; RBRACE } VOIDTK void MAINTK main LPARENT ( RPARENT ) LBRACE { PRINTFTK printf LPARENT ( STRCON Hello World RPARENT ) SEMICN ; PRINT
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值