Chinaunix首页 | 论坛 | 博客
  • 博客访问: 250301
  • 博文数量: 34
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 961
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-11 17:19
个人简介

没有最好的语言,只有最适合的语言。

文章分类

全部博文(34)

文章存档

2016年(2)

2013年(32)

我的朋友

分类: C/C++

2013-07-11 18:48:52

C语言实现的词法分析器

该词法分析器,不是一个完美的词法分析器,但实现了其中的主体功能。可供借鉴

#include
#include
#include

#define MAXSIZE 255   //设置字符串的最长的长度
#define $ID 1         //已插入符号表的返回值
#define $code 2        //返回该值表示是保留字
#define $ASSIGN 3     //返回该值表示是一个 =
#define $PLUS 4       //返回该值表示是一个 +
#define $POWER 5      //返回该值表示是一个 非*
#define $STAR 6      //返回该值表示是一个 *
#define $SEMICOLON 7  //返回该值表示是一个 ;
#define $LPAR 8       //返回该值表示是一个 (
#define $RPAR 9       //返回该值表示是一个 )
#define $LBRACE 10    //返回该值表示是一个 {
#define $RBRACE 11    //返回该值表示是一个 }
#define $INT 12       //返回该值表示是一个int型


char ch;                      //字符变量,存放最新读进的源程序字符
char strToken[MAXSIZE];       //字符数组,存放构成单词符号的字符串
FILE *fp;                     //读取源文件内容的指针
FILE *fReserve;               //读取保留字表文件的指针
FILE *fId;                    //读取含有标识符的文件的指针
FILE *fConst;                 //读取含有常数表文件的指针
int index1;                    //字符数组的下标


int judgeString();   //判断当前读入的字符串
void GetChar();   //读入一个字符到ch中,搜索指示器前移
void GetBC();     //检查ch是否为一个空白。若是,则调用GetChar()直至ch中读入一个非空字符
void Concat();    //链接字符串,对strToken操作
int IsLetter();  //是否是字母
int IsDigit();   //是否是数字
int Reserve();    //是否是保留字
void Retract();   //搜索指示器回调,ch置空
int InsertId();  //插入符号栈
int InsertConst();      //插入常数栈
void ProcError();          //错误处理


int main()
{
   char fidName[MAXSIZE];
   char filename[MAXSIZE];
   char fconstName[MAXSIZE];
   printf("请输入要分析的源文件的文件名:");
   gets(filename);
   fp = fopen(filename,"rt");
   if(fp == NULL)
   {
       printf("\n打开文件失败,%s可能不存在\n",filename);
       return 0;
   }
   strcpy(fidName,filename);
   strcpy(fconstName,filename);
   strcat(fidName,"id.txt");
   strcat(fconstName,"const.txt");
   fId = fopen(fidName,"at+");
   if(fId == NULL)
   {
       printf("无法操作标识符文件\n");
       return 0;
   }
   fConst = fopen(fconstName,"at+");
   if(fConst == NULL)
   {
       printf("无法操作常量文件!\n");
       return 0;
   }
   while(fgetc(fp) != -1)   //从文件中取中一个字符 判断是否读取文件结束了
   {
       Retract();           //读取文件指针前移一位
       judgeString();       

   }
   fclose(fp);
   fclose(fId);
   fclose(fConst);
   return 1;
}

int judgeString()
{
   int code;
   int value;
   memset(strToken,0,sizeof(strToken));
   index1 = 0;
   GetChar();
   GetBC();
   if(IsLetter()== 1)
   {
       while(IsLetter() == 1|| IsDigit()== 1)
       {
           Concat();
           GetChar();
       }
       Retract();
       code=Reserve();
       if(code == 0)
       {
           value = InsertId(strToken);
           return $ID;
       }
       else{
           return code;
       }
   }else if(IsDigit() == 1){
       while(IsDigit() == 1){
           Concat();
           GetChar();
       }
       Retract();
       value = InsertConst(strToken);
       return $INT;
   }else if(ch == '='){
       return $ASSIGN;
   }else if(ch == '+'){
       return $PLUS;
   }else if(ch == '*'){
       GetChar();
       if(ch = '*') return $POWER;
       Retract();
       return $STAR;
   }else if(ch == ';'){
       return $SEMICOLON;
   }else if(ch =='('){
       return $LPAR;
   }else if(ch == '{'){
       return $LBRACE;
   }else if(ch == '}'){
       return $RBRACE;
   }else
       ProcError();
}


/*
*读取一个字符,指示器前移
* */
void GetChar()
{
   ch = fgetc(fp);
//    printf("%c",ch);
}

/*
*检查ch是否为空,为空就调用GetChar(),直到取到非空字符
* */
void GetBC()
{
   while(ch == ' ')
       GetChar();
}

/*
*连接字符
* */
void Concat()
{
   strToken[index1] = ch;
   index1++;
}    

/*
*判断是否是字母
* */
int IsLetter()
{
   if((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
       return 1;
   else
       return 0;
}

/*
*判断是否是数字
* */
int IsDigit()
{
   if(ch >= '0' && ch <='9')
       return 1;
   else
       return 0;
}


int Reserve()
{
   char data[MAXSIZE];
   fReserve = fopen("Reserve.txt","rt");
   if(fReserve == NULL)
   {
       printf("打开文件失败!!!!!!!!!!!!!!!\n");
       return -1;
   }
   while(fscanf(fReserve,"%s ",data)!=EOF)
   {
   //    printf("%s\n",data);
       if(strcmp(strToken,data) == 0)
       {
           printf("%s是保留字\n",data);
           return -2;
       }
   }
   return 0;
}

void Retract()
{
   fseek(fp,-1,SEEK_CUR);
   ch = ' ';
}

int InsertId()
{
   fprintf(fId,"%s\n",strToken);
   return 1;
}

int InsertConst()
{
   fprintf(fConst,"%s\n",strToken);
   return 1;
}

void ProcError()
{
   printf("%c是未知词\n",ch);
}

阅读(9016) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~