C++词法分析器

时间:2024.3.19

编译原理—词法分析器实验报告

一、实验目的

1.设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。

2.掌握在对程序设计语言的源程序扫描的过程中,将其分解后各类单词的语法分析方法。

二、实验要求:

1. 对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。

2. 本程序自行规定:

(1)关键字"begin","end","if","then","else","while","write","read",

"do", "call","const","char","until","procedure","repeat"

(2)运算符:"+","-","*","/","="

(3)界符:"{","}","[","]",";",",",".","(",")",":"

(4)其他标记 如字符串,表示以字母开头的标识符。
(5)空格、回车、换行符跳过。

在屏幕上显示如下:
( 1 , 无符号整数)

( begin , 关键字 )

( if , 关键字 )

( +, 运算符 )

( ; , 界符 )
( a , 普通标识符 )

三、使用环境:
Window vista 下的 Visual Studio 2008;

四、实验步骤

1.查询资料,了解词法分析器的工作过程与原理。

2.分析题目,整理出基本设计思路。

3.实践编码,将设计思想转换用c语言编码实现,编译运行。

4.测试功能,多次设置包含不同字符,关键字的待解析文件,仔细察看运行结果,检测该分析器的分析结果是否正确。通过最终的测试发现问题,逐渐完善代码中设置的分析对象与关键字表,拓宽分析范围提高分析能力。

五、流程图

五、调试程序:

1.举例说明

文件位置:C:\TEST.txt

目标程序如下:

Int  main() 

  {

i=10;

j=100;

n=1;

sum=0;

mult=1;

while (i>0) {n=n+1;i=i-1;}

if (j>=50) then sum=sum+j; else {mult=mult*(j+1);sum=sum+i;}

if (i<=10) then sum=sum-i; else mult=mult+i/2;

if (i==j) then sum=sum-j; else mult=mult-j/2;

if (n>1) then n=n-1; else n=n+1;

if (n<2) then n=n+2; else n=n-2;

}

2.运行结果:

六、程序源代码:

#include <iostream>

#include<string>

using namespace std;

#define  MAX 22         

char ch =' ';

string key[15]={"begin","end","if","then","else","while","write","read",

"do", "call","const","char","until","procedure","repeat"};

int Iskey(string c){         //关键字判断

   int i;

   for(i=0;i<MAX;i++) {

      if(key[i].compare(c)==0) return 1;

       }

    return 0;

}

int IsLetter(char c) {        //判断是否为字母

    if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1;

    else return 0;

}

int IsDigit(char c){          //判断是否为数字

     if(c>='0'&&c<='9') return 1;

     else return 0;

}

void analyse(FILE *fpin){

    string arr="";         

    while((ch=fgetc(fpin))!=EOF) {

            arr="";       

         if(ch==' '||ch=='\t'||ch=='\n'){}    

         else if(IsLetter(ch)){

                 while(IsLetter(ch)||IsDigit(ch)) {

                                if((ch<='Z')&&(ch>='A')) ch=ch+32;  

                             arr=arr+ch;

                    ch=fgetc(fpin);

                               }

                 fseek(fpin,-1L,SEEK_CUR);   

                 if (Iskey(arr)){cout<<arr<<"\t$关键字"<<endl;}    

                 else  cout<<arr<<"\t$普通标识符"<<endl;          

               }

     

            else if(IsDigit(ch)){

                  while(IsDigit(ch)||ch=='.'&&IsDigit(fgetc(fpin))){

                        arr=arr+ch;

                        ch=fgetc(fpin);

                       }

                  fseek(fpin,-1L,SEEK_CUR);

                  cout<<arr<<"\t$无符号实数"<<endl; 

             }

       else switch(ch){         

               case'+':

               case'-' :

               case'*' :

               case'=' :

               case'/' :cout<<ch<<"\t$运算符"<<endl;break;

               case'(' :

               case')' :

               case'[' :

               case']' :              

               case';' :

               case'.' :

               case',' :

               case'{' :

               case'}' :cout<<ch<<"\t$界符"<<endl;break;

               case':' :{ch=fgetc(fpin);

                        if(ch=='=') cout<<":="<<"\t$运算符"<<endl;

                        else {cout<<"="<<"\t$运算符"<<endl;;

                               fseek(fpin,-1L,SEEK_CUR);}

                        }break;

case'>' :{ch=fgetc(fpin);

                         if(ch=='=') cout<<">="<<"\t$运算符"<<endl;

                         if(ch=='>')cout<<">>"<<"\t$输入控制符"<<endl;

                         else {cout<<">"<<"\t$运算符"<<endl;

                             fseek(fpin,-1L,SEEK_CUR);}

                         }break;

               case'<' :{ch=fgetc(fpin);

                         if(ch=='=')cout<<"<="<<"\t$运算符"<<endl;

                         else if(ch=='<')cout<<"<<"<<"\t$输出控制符"<<endl;

                         else if(ch=='>') cout<<"<>"<<"\t$运算符"<<endl;

                         else{cout<<"<"<<"\t$运算符"<<endl;

                            fseek(fpin,-1L,SEEK_CUR);}

                        }break;

              default : cout<<ch<<"\t$无法识别字符"<<endl;

        }

    }

}

void main(){

   char in_fn[30];

   FILE * fpin;

   cout<<"请输入源文件名(包括路径和后缀名):";

   for(;;){

       cin>>in_fn;

       if((fpin=fopen(in_fn,"r"))!=NULL) break;

       else cout<<"文件路径错误!请输入源文件名(包括路径和后缀名):";

     }

   cout<<"\n********************分析如下*********************"<<endl;

   analyse(fpin);

   fclose(fpin);

   cout<<endl;

   cout<<"按任意键结束"<<endl;

   int a;

   cin>>a;

}

六、实验心得:

   通过此次实验,让我了解到如何设计、编制并调试词法分析程序,加深对词法分析原理的理解;熟悉了构造词法分析程序的手工方式的相关原理,使用某种高级语言(例如C++语言)直接编写此法分析程序。另外,也让我重新熟悉了C++语言的相关内容,加深了对C++语言的用途的理解。在本次实验中,我纠正了一个一直以来的概念错误:main不是关键字,它定义为程序的入口,是主函数!在本实验中,虽然我把main初始化在关键字表

(字符指针类型数组)*Key[10]中,当与该数组中字符串进行比较时,若与main匹配成功,则返回2,若为其他关键字则返回1,以此来把main从关键字中区别出来。

在本实验中的关键字表只初始化了几个常用的关键字,还可继续扩充(只需扩大数组,向其中补充要添加的关键字)。


第二篇:C语言词法分析器.doc


/**测试文件(将"x:=5;if(x>=0)then x:=2*x+1/3;else x:=2/x; for if(x<3) then yy:=100;邯郸市**#%#" 保存为 "源程序.txt" 文件)*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>FILE *fp=NULL;//源程序文件 FILE *fp1 = fopen("词法分析结果.txt","w");//把词法分析结果写到文件"分析结果.txt"中char temp[20];char str;char *keyWord[6] = {"for","if","then","else","while","do"};//关键字 1—6char *Others[] = {"+","-","*","/", ":", ":=","<>","<=",">",">=","=", ";" , "(",")","#"};//运算符,分隔符13-16 17-18 20-28 0void ClearTemp(){for(int i=0;i<20;i++){temp[i]=NULL;}}void NumberProcess(char str){char ch;int i=1;temp[0] = str;while(!feof(fp)){ch = fgetc(fp);if(isdigit(ch)){temp[i++] = ch;}else{ printf("(%d,%s)\n",11,temp);fprintf(fp1,"(%d,%s)\n",11,temp);break;} }fseek(fp,-1,SEEK_CUR);ClearTemp();}void LetterProcess(char str){char ch;int i=1;temp[0] = str;while(!feof(fp)){ch = fgetc(fp);if(isalpha(ch)||isdigit(ch)){temp[i++] = ch;}else{int j=0;for(j=0;j<6;j++){if(strcmp(temp,keyWord[j]) == 0){printf("(%d,%s)\n",j+1,temp);//fputs(temp,fp1);fprintf(fp1,"(%d,%s)\n",j+1,temp);break;} }if(j==6){//printf("(%s,%d)\n",p,j+1);printf("(%d,%s)\n",10,temp);//fputs(temp,fp1);fprintf(fp1,"(%d,%s)\n",10,temp);}fseek(fp,-1,SEEK_CUR);break;}}ClearTemp();}void OtherProcess(char str){switch(str)//{"+","-","*","/", ":", ":=","<>","<=",">",">=","=", ";" , "(",")","#"};//运算符,分隔符13-16 17-18 20-28 0{case '+': {printf("(%d,%c)\n",13,str);fprintf(fp1,"(%d,%c)\n",13,str);break;}case '-': {printf("(%d,%c)\n",14,str);fprintf(fp1,"(%d,%c)\n",14,str);break;}case '*':{printf("(%d,%c)\n",15,str);fprintf(fp1,"(%d,%c)\n",15,str);break;}case '/': {printf("(%d,%c)\n",16,str);fprintf(fp1,"(%d,%c)\n",16,str);break;}case ':':{char tp;tp = fgetc(fp);if(tp == '='){printf("(%d,%c%c)\n",18,str,tp);fprintf(fp1,"(%d,%c%c)\n",18,str,tp);break;}else{printf("(%d,%c%c)\n",17,str,tp);fprintf(fp1,"(%d,%c%c)\n",17,str,tp);fseek(fp,-1,SEEK_CUR);break;}}case '<': //"<","<>","<=",">",">=","=", ";" , "(",")","#"};//运算符,分隔符20-28 0{char tp;tp = fgetc(fp);if(tp == '>'){printf("(%d,%c%c)\n",21,str,tp);fprintf(fp1,"(%d,%c%c)\n",21,str,tp);break;}else if(tp == '='){printf("(%d,%c%c)\n",22,str,tp);fprintf(fp1,"(%d,%c%c)\n",22,str,tp);break;

}else{printf("(%d,%c)\n",20,str);fprintf(fp1,"(%d,%c%c)\n",20,str,tp);fseek(fp,-1,SEEK_CUR);break;}}case '>': //">",">=","=", ";" , "(",")","#"};//运算符,分隔符23-28 0{char tp;tp = fgetc(fp);if(tp == '='){printf("(%d,%c%c)\n",24,str,tp);fprintf(fp1,"(%d,%c%c)\n",24,str,tp);break;}else{printf("(%d,%c)\n",23,str);fprintf(fp1,"(%d,%c)\n",23,str);fseek(fp,-1,SEEK_CUR);break;}}//,"=", ";" , "(",")","#"};//运算符,分隔符25-28 0case '=': {printf("(%d,%c)\n",25,str);fprintf(fp1,"(%d,%c)\n",25,str);break;}case ';': {printf("(%d,%c)\n",26,str);fprintf(fp1,"(%d,%c)\n",26,str);break;}case '(': {printf("(%d,%c)\n",27,str);fprintf(fp1,"(%d,%c)\n",27,str);break;}case ')': {printf("(%d,%c)\n",28,str);fprintf(fp1,"(%d,%c)\n",28,str);break;}case '#': {printf("(%d,%c)\n",0,str);fprintf(fp1,"(%d,%c)\n",0,str);break;}default : if(!feof(fp)){printf("无法识别的字符\n");fprintf(fp1,"无法识别的字符\n");}break;}}int main(){//printf("词法分析结果如下:\n\n");if ((fp = fopen("源程序.txt","r")) == NULL)//打开文件{printf("can not open the file!\n");exit(0);//打不开文件,退出 }/*if ((fp1 = fopen("词法分析结果.txt","w")) == NULL)//打开文件{printf("can not open the file!\n");exit(0);//打不开文件,退出 }*//*char str;while(!feof(fp)){str = fgetc(fp);printf("%c",str);}*///str = fgetc(fp);while (!feof(fp))//文件中还有结束{str = fgetc(fp);//从文件中取出一个字符if (isalpha(str))//是英文字符{LetterProcess(str);//字母处理}else if (isdigit(str))//是数字{NumberProcess(str);//数字处理}else if(str == '\t' || str == ' '|| str == '\n'){;}else{OtherProcess(str);//其他字符处理}}printf("\n词法分析结束.词法分析结果已写入文件.\n");fclose(fp);//关闭文件fclose(fp1);system("pause");return 0;}

更多相关推荐:
词法分析小结

词法分析小结词法分析是编译器工作的第一阶段,它的工作就是从输入(源代码)中取得token,以作为parser(语法分析)的输入,一般在词法分析阶段都会把一些无用的空白字符(whitespace,即空格、tab和…

词法分析器

词法分析器学院:班级:学号:姓名:指导教师:词法分析器一.问题描述词法分析程序的功能:输入源程序,输出单词符号,如图所示:处理过程:在扫描源程序字符串时,一旦识别出关键字、分隔符、标识符、无符号常数中之一,即以…

词法分析器_实验报告

词法分析器实验报告实验目的设计编制调试一个词法分析子程序识别单词加深对词法分析原理的理解实验要求该程序要实现的是一个读单词过程从输入的源程序中识别出各个具有独立意义的单词即基本保留字标识符常数运算符分界符五大类...

词法分析器实验报告

词法分析一实验目的设计编制并调试一个词法分析程序加深对词法分析原理的理解二实验要求词法分析程序的功能输入所给文法的源程序字符串输出二元组syntoken或sum构成的序列其中syn为单词种别码token为存放的...

词法分析器实验报告

实验报告第1页共6页第2页共6页实验过程记录源程序测试用例测试结果及心得体会等1程序源代码includequotfstreamhquotincludequotiostreamhquotincludequotst...

词法分析器

编译原理课程实验报告课程实验题目词法分析器学院计算机科学与技术班级学姓号04113026名指导教师姓名完成时间一目的要求设计一个词法分析器并更好的理解词法分析实现原理掌握程序设计语言中各类单词的词法分析方法能就...

编译原理 简单样本语言的词法分析器

昆明理工大学信息工程与自动化学院学生实验报告20xx20xx学年第1学期课程名称编译原理开课实验室信自楼44年月日一实验目的及内容设计编制调试一个词法分析子程序识别单词加深对词法分析原理的理解二实验原理及基本技...

词法分析器生成器 lex 中文手册

Lex词法分析器生成器MELesk与ESchmidtBellLaboratoriesMurrayHillNewJersey07974译者声明译者对译文不做任何担保译者对译文不拥有任何权利并且不负担任何责任和义务...

c语言词法分析器

实验内容实现标准C语言词法分析器实验目的1掌握程序设计语言词法分析的设计方法2掌握DFA的设计与使用方法3掌握正规式到有限自动机的构造方法实验要求1单词种别编码要求基本字关键字运算符界符一符一种标识符变量名统一...

C语言词法分析器,内容说明注释完整,可运行代码

1实验目的及要求本次实验通过用C语言设计编制调试一个词法分析子程序识别单词实现一个C语言词法分析器经过此过程可以加深对编译器解析单词流的过程的了解运行环境硬件windowsxp软件visualc602实验步骤1...

基于LEX的C语言词法分析器

实验二C语言的词法分析器基于Lex1课程设计目标自动构造C语言的的词法分析器要求能够掌握编译原理的基本理论理解编译程序的基本结构掌握编译各阶段的基本理论和技术掌握编译程序设计的基本理论和步骤增强编写和调试高级语...

词法分析器

词法分析器报告一任务与目的任务1使用CC程序设计语言和递归下降子程序的方法编写该函数绘图语言的词法分析器并要求设计一个词法分析器的测试小程序来调用自己编写的词法分析器测试各种不同的输入2词法分析的任务是对输入的...

词法分析器总结(22篇)