⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccc.cpp

📁 词法分析器
💻 CPP
字号:
#include "stdafx.h"
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<iostream>
//****************************************
char * change(char *ps,char *pt);      //处理路径中的反斜杠问题。因为在字符串中要用\\表示\ 
int  searchkey(char *word,struct key tab[],int n);//关键字匹配函数
int  searchsymbol(char c,struct symbol tab[],int n);//符号匹配函数
void getword(char c,FILE * p);
void getnum(char c,FILE * p);
//****************************************
//用到的结构数组:
struct  key{          //关键字表
    char*   word;
    int     value;
}
keytab[] = {
         "else",  0, "if",    1,"for",   2, "return",3, "void",  4,
         "while", 5, "auto",  6,"struct",7, "char" , 8, "int"  , 9,
		 "long" , 10,"float" ,11, "double",12," signed", 13, "case",14,
		 "switch",15, "unsigned", 16,"sizeof", 17, "break", 18,"do", 19,
         "short",20, "printf",21 ,"scanf",22,"main",23
};
//*******************************
struct   symbol{        //符号表
      char  c;
      int   value;
}
symboltab[] = {
        '-', 0,  '/', 1,
		'*', 2,  '+', 3,
		'=', 4,  '<', 5,
	    '>', 6,  ';', 7,
		'(', 8,  ',', 9, 
		')', 10, '[', 11,
		']', 12, '{', 13, 
		'}', 14, '"', 15,
		'~', 16,  '|',17,
		'_', 18,  '&',19,
		'%',20 ,  '\\',21,
		'#',22  , ':', 23,
		'.', 24,
};
//*****************************************

//用到的常量
enum{MAX = 50,
     NKEYS = sizeof keytab / sizeof keytab[0],
     NSYMBOL = sizeof symboltab / sizeof symboltab[0]
};
//*****************************************

int flagnum = 0;  //用来防止出现10t这种情况被当作数字处理。这种情况flagnum=1程序报错
int countnum = 0;
int countid  = 0;  //标识符计数(标识符定义为:以字母开头的非关键字的字符串)
int countfault = 0;
int type[] = {0,1,2,3,4,5};            //词法分析中的类型  依次为 关键字-0,常数-1,标识符-2,算符-3,界符-4, 错误显示-5
char array[MAX];           //存放getword中的字符串,用于字符串类型判断

//*****************************************

main()
{
 char c;
 int flag;     //判断搜索函数是否成功返回
 char s[MAX];       //数组s,t用来存放读取文件的路径
 char t[2 * MAX];
 char *ps = s;
 char *pt = t;
    FILE * p = NULL;
    printf("输入你要的文件路径\n");
 scanf("%s",s);
    p = fopen( change(ps,pt),"r" );     //打开文件
    if( p == NULL ){                   //如果输入的文件路径不对或文件不存在,报错
        printf("打开失败输入 1 退出\n");
		scanf("%d",&c);
        exit(0);
    }  
 printf("词  \t (组号,组内类号)\n");
    while( ( c = fgetc(p) ) != EOF )
 {
if ( isspace(c) )       // 如果是空白字符
   continue;
  else if ( isalpha(c) )
                    //如果是字母开头
        getword(c,p);
               
  else if ( isdigit(c) ){         //如果是数字开头,判断是否数字或者错误输入
              getnum(c,p);
			 
       }
  else if ( ispunct(c) ){        //如果是符号
              flag = searchsymbol(c,symboltab,NSYMBOL);
     if ( flag <=6 )
        printf("%c\t(%4d,%5d)\n",c,type[3],flag);     //算符
     else if(flag>6)                
	 { printf("%c\t(%4d,%5d)\n",c,type[4],flag-7);}    //界符
	 else if(flag<0){
        printf("%c\t(%4d,%5d)   Unknow char\n",c,type[5],countfault++);  //出错处理
                 countfault ++;
     }
  }
  else{
   printf("%c\t(%4d,%5d)\n",c,type[5],countfault++);       //出错处理
   countfault ++;
  }
 }
  printf("任意输入,回车结束");
  scanf("%d",&c);
  
}
void getnum(char c,FILE * p)
{  int i =0;
   array[i]=c;
   flagnum=0;
   int flag;
	while( (c = fgetc(p)) != ' ' && c!= '\n'&&!ispunct(c)){   //数字后带字符,数字读取结束,循环结束
		    array[++i] = c; 
			if(isalpha(c)) flagnum=1;   //如果数字中有字母,报错,并且把后面的字母读完,存入array 缓冲
        }
	array[++i]='\0';
	if ( flagnum == 0 )
               printf("%s\t(%4d,%5d)\n",array,type[1],countnum++);   //输出数字,数字计数vountnum自加+
             else
                 printf("%s\t(%4d,%5d)\t 错误的数字输入 \n",array,type[5],countfault++);   //错误号countfault自加1
	if(ispunct(c))        
		  { flag = searchsymbol(c,symboltab,NSYMBOL);       //判断数字后面跟的字符类型
            if ( flag <= 6 )
               printf("%c\t(%4d,%5d)\n",c,type[3],flag);
			else if(flag>6)
				printf("%c\t(%4d,%5d)\n",c,type[4],flag-7);
            else if(flag<0){
               printf("%c\t(%4d,%5d) 没有这个字符\n",c,type[5],countfault);  //出错处理
                 countfault ++;
	           }
	        }
}
void getword(char c,FILE * p)
{ int i = 0;
  int flag;
  array[i] = c;
 while( (c = fgetc(p)) != ' ' && c != '\n'&&!ispunct(c)){   //字母后面跟字符,退出循环
	 array[++i] = c;
    }
 
array[++i]='\0';
flag=searchkey(array,keytab,NKEYS);
 if ( flag >= 0 )                      //如果是关键字
              printf("%s\t(%4d,%5d)\n",array,type[0],flag);
    else if(flag<0) {                 //如果以字母开头,但不是关键字,则判断为标识符
                    printf("%s\t(%4d,%5d)\n",array,type[2],countid);
                     countid ++;
                }
 	   if(ispunct(c)) 
	    {   flag = searchsymbol(c,symboltab,NSYMBOL);
         if ( flag <= 6 )
         printf("%c\t(%4d,%5d)\n",c,type[3],flag);
		 else if(flag>6)
			 printf("%c\t(%4d,%5d)\n",c,type[4],flag-7);
          else if(flag<0){
          printf("%c\t(%4d,%5d) 没有这个字符 \n",c,type[5],countfault++);  //出错处理
          countfault ++;
	         }
	}
}
//*******************************************
char * change(char *ps,char *pt)     //处理反斜杠的问题
{
 char *p = pt;
 char c;
 while( (c = *pt++ = *ps++) != '\0' )
  if( c == '\\' )
   *pt = '\\';
 return p;
}
//******************************************
int  searchkey(char *word,struct key tab[],int n)  // 匹配关键字
{
 int cond;
 int i;
 for(i=0;i<n;i++)
 {cond = strcmp(word,tab[i].word);
  if ( cond== 0 )
     return i;
   }
 return -1;
}

//**********************************************
int  searchsymbol(char c,struct symbol tab[],int n)   // 匹配符号
{
  int i;
  for(i=0;i<n;i++)
  {  if(c==tab[i].c)
      return i;   
  }
    return -1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -