词法分析程序实验报告

实验一、词法分析程序实验

专业:商软二班   姓名:朱小彬  学号:201506110050

一、实验目的 

编制一个词法分析程序。 

二、实验内容和要求

实验内容:输入一段字符串,从字符串表示的源程序中识别出具有独立意义的单词符号,根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

实验要求:输入:源程序字符串;

输出:二元组(种别,单词本身);

待分析语言的词法规则。 

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

1.      源程序名:cifafenxi.c

可执行程序名:cifafenxi.exe

2.      原理分析及流程图

设置3个初值变量和一个关键字表:

1) char  token[8] 用来存放构成单词符号的字符串;

2) double  sum  用来存放无符号整数或者浮点数;

3) int  syn      用来存放单词符号的种别码;

关键字表: char *rwtab[6]={“begin”,”if”,”then”,”while”,”do”,”end”};

设置重要的全局变量:

1) char  ch 用来存放当前镀金的源程序字符;

2) char  prog[80] 用来存放所有用户输入的字符;

3) int  isDecimal 是否为浮点数,值为1表示为浮点数,否则不是浮点数

4) double  decimal 双精度,浮点数的小数部分

5) int  isE 是否为指数形式表示的浮点数,值为1:表示是指数形式表示的浮点数

6) int  index 指数形式的幂

7) int  isNeg 是否为负数幂,值为1:表示为负数幂

设置关键的函数:

void  scanner() 词法扫描程序

getchar() 从控制台读取一个字符数据

int strcmp( char *str1,char *str2),字符串的比较

double pow( double x,double y) 计算x的y次幂

流程:

1) 记录下输入的源程序字符串

2) 调用scanner()函数对字符串进行各种关键字、运算符和界符、数字的扫描匹配,并且给出相应的种别码,输出单词二元组

3.      主要程序段及其解释:

1. getchar() 该函数用来接收用户输入:

借助do……while()循环来记录用户输入的源程序字符串

do{

           ch = getchar();  //将用户输入的字符读入到ch变量中

           prog[p++] = ch;  //将字符存于数组中

    }while(ch != ‘#’);  //当用户输入’#’号时,结束输入。

2. scanner() 该函数用来扫描源程序字符串并进行区别分类

1) 如果是字母字符,则进行关键字的匹配:

if(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))) //ch是字母字符

    {

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

           {

                  token[m++]=ch; //ch=>token 以便进行关键字的匹配

                  ch=prog[p++]; //读下一个字符

           }

           token[m++]='\0';

           p--; //回退一格

           syn=10; //标识符

 

           //判断是否是"begin","if","then","while","do","end"标识符中的一个

           for(n=0;n<6;n++)

                  if(strcmp(token,rwtab[n])==0)

                  {

                         syn=n+1;

                         break;

                  }

    }

 

2) 对数字进行判断,并且进行数值的计算:

else     if((ch>='0')&&(ch<='9')) //对数字进行识别

    {

IsNum: //在此处设置一个goto的标识符以便实现“数字识别代码段”的复用

   if(isSignal==1)

   {

       //token[m++]='-';

   }

           while((ch>='0')&&(ch<='9'))

           {

                  sum=sum*10+ch-'0'; //ch中数字本身是当做字符存放的

                  ch=prog[p++];

           }

           if(ch=='.')

           {

                  isDecimal=1;

                  ch=prog[p++];

                  while((ch>='0')&&(ch<='9'))

                  {

                         //pow(x,y)计算x的y次幂

                         temp=(ch-'0')*pow(0.1,++count);

                         decimal=decimal+temp;

                         //AddToDec();

                         ch=prog[p++];

                  }

                  sum=sum+decimal;

           }

           if(ch=='e'||ch=='E')

           {

                  isExp=1;

                  ch=prog[p++];

                  if(ch=='-')

                  {

                         isNegative=1;

                         ch=prog[p++];

                  }

                  while((ch>='0')&&(ch<='9'))

                  {

                         //指数

                         index=index*10+ch-'0';

                         ch=prog[p++];

                  }

                  //10的幂

                  //123e3代表123*10(3)

                  if(isNegative)

                         sum=sum*pow(0.1,index);

                  else

                         sum=sum*pow(10,index);

 

           }

           if(isSignal==1)

           {

                  sum=-sum;

                  isSignal=0;

           }

           p--;

           syn=11;

    }

 

3) 对界符和运算符进行判断:

else switch(ch)

    {

           case '<':

                  m=0;

                  token[m++]=ch;

                  ch=prog[p++];

                  if(ch=='>')

                  {

                         syn=21; //<>对应21

                         token[m++]=ch;

                  }

                  else if(ch=='=')

                  {

                         syn=22;

                         token[m++]=ch;

                  }

                  else

                  {

                         syn=20;

                         p--;

                  }

                  break;

 

           case '>':

                  m=0;

                  token[m++]=ch;

                  ch=prog[p++];

                  if(ch=='=')

                  {

                         syn=24;

                         token[m++]=ch;

                  }

                  else

                  {

                         syn=23;

                         p--;

                  }

                  break;

 

           case ':':

                  m=0;

                  token[m++]=ch;

                  ch=prog[p++];

                  if(ch=='=')

                  {

                         syn=18;

                         token[m++]=ch;

                  }

                  else

                  {

                         syn=17;

                         p--;

                  }

                  break;

 

           case '+':

                  temp2=prog[p];

                  if((temp2>='0')&&(temp2<='9'))

                  {

                         isSignal=2;

                         ch=prog[p++];

                         goto IsNum;

                  }

                  syn=13;

                  token[m++]=ch;

                  break;

           case '-':

                  temp2=prog[p];

                  if((temp2>='0')&&(temp2<='9'))

                  {

                         isSignal=1;

                         ch=prog[p++];

                         goto IsNum;  //转到数字的识别

                  }

                  syn=14;

                  token[m++]=ch;

                  break;

           case '*':

                  syn=15;

                  token[m++]=ch;

                  break;

           case '/':

                  syn=16;

                  token[m++]=ch;

                  break;

           case '=':

                  syn=25;

                  token[m++]=ch;

                  break;

           case ';':

                  syn=26;

                  token[m++]=ch;

                  break;

           case '(':

                  syn=27;

                  token[m++]=ch;

                  break;

           case ')':

                  syn=28;

                  token[m++]=ch;

                  break;

           case'#':

                  syn=0;

                  token[m++]=ch;

                  break;

           default:

                  syn=-1;

    }

}

4. 运行结果及分析 

符合实验内容以及要求,能识别出输入字符串所对应的单词符号。 

四、实验总结 

刚开始入门,对于程序不知道如何下手,好长时间都没有思路,后查询相关的资料以及相应的代码后,慢慢理解分析,最终写出实验报告。

 

 

 

 

 

 

 

 

 

 

posted @ 2016-10-09 16:02  050朱小彬  阅读(391)  评论(0编辑  收藏  举报