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

📄 jiandandecifafenxiqi.txt

📁 一个简单的词法分析器
💻 TXT
字号:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>             
#include <stdlib.h>
#define KEYWORDSUM 12
#define FUHAOSUM 6
#define BEGIN 1
#define END   2
#define IF    3
#define THEN 4
#define ELSE 5
#define ID    6
#define CONST 7
#define LT    8
#define LE    9
#define EQ    10
#define NE    11
#define GT    12
#define GE    13
#define FOR   14
#define WHILE 15
#define DO    16
#define MAIN 17
#define PROCEDURE 18
#define ADD   19
#define SUB 20
#define MUL   21
#define LP 22
#define RP 23
#define LC 24
#define RC 25
#define SEMI   26
#define DOUH   27
#define COLON   28
#define FUZH   29
#define QUF   30
#define YINH 31
#define INT   32
#define XIEG 33
#define ERROR 34
#define INCLU 35
#define DIAN 36
#define PERCE 37
#define PRINTF 38
#define SCANF 39
#define ADDA    40
#define SUBS    41
#define JINGH   42


char constant[50][20];      /*常量定义*/
char id[50][20];       /*变量定义 */
char *keyword[KEYWORDSUM+1]={"include","printf","scanf","end","main","then","if","else","for","while","do","int"};/*关键字自定义*/
char singleword[50]="*(){};,:.%#";                          /*符号定义 */
char doubleword1[FUHAOSUM+1]="><=!+-";                     /*单符定义*/
char *doubleword2[FUHAOSUM+1]={">=","<=","!=","==","++","--"}; /*双符定义 */
extern FILE * fin,* fout;                  /*定义文件指针 */
void read_file();           /*读文件函数 */
extern int testscan();     /*输出测试*/
int length1,length2;    /*length1记录常数的个数length2记录变量的个数 */


void read_file(int io)
{
FILE *fp;
char ch;
if(io==0)                       /*为什么定义io ???、、*/
{
if((fp=fopen("D:\\DOS\\Win-TC\\projects\\bs.txt","r"))==NULL)
{
    printf("\nOPEN ERROR!\n");
    return;
}
}
else
{
if((fp=fopen("D:\\DOS\\Win-TC\\projects\\bss.txt","r"))==NULL)
{
    printf("\nOPEN ERROR!\n");
    return;
}
}
printf("\nthe file saved is as following!\n");
ch=fgetc(fp);
while(ch!=EOF)
{
   putchar(ch);                                    /*在屏幕上显示所得文件*/
   ch=fgetc(fp);
}
fclose(fp);
}


int testscan()
{
char ch,ch1,token[40];
int es=0;
int i,j,k,n,m;     /*n记录关键字的个数,j标记当前所指字符在文件中的位置,k记录变量个数 ,i循环变量 ,m记录所得数字的个数*/
long constant1;
m=0;
i=0;
k=0;
if((fin=fopen("D:\\DOS\\Win-TC\\projects\\bs.txt","r"))==NULL)
{
printf("\nopen infile error!\n");
return(1);
}
if((fout=fopen("D:\\DOS\\Win-TC\\projects\\bss.txt","w"))==NULL)
{
printf("\n create new outfile error!\n");
return(2); 
}
ch=getc(fin);
while(ch!=EOF)
{
while(ch==' '||ch=='\n'||ch=='\t') ch=getc(fin);
if(isalpha(ch))                        /*是字母返回非0值,否则返回0 */
{
   token[0]=ch;
   j=1;
   ch=getc(fin);
   while(isalnum(ch))                      /*若是字母或数字则返回非 0否则返回0*/
   {
    token[j++]=ch;
    ch=getc(fin);
   }
   token[j]='\0';
   n=0;
   while((n<KEYWORDSUM)&&strcmp(token,keyword[n])) n++; /*如果是关键字则加n1否则跳出循环*/
   if(n>=KEYWORDSUM)     /*如果n超出关键字的个数,则将该串字符存入变量表中 */
   {
    strcpy(id[k],token);
    length2=k;
    fprintf(fout,"<%d , %s>\n",ID,token);       /*将ID,token的值在建的文件中显示*/
    k++;
   }
   else                                            /*是关键字则将相应字符在建的文件夹里写出来 */
   {
     for(i=0;(i<KEYWORDSUM)&&(strcmp(token,keyword[i])!=0);i++) ;         /* ???? */
       switch(i)
        {
            case 0: fprintf(fout,"<%d , >\n",INCLU);break;
            case 1: fprintf(fout,"<%d , >\n",PRINTF);break;
            case 2: fprintf(fout,"<%d , >\n",SCANF);break;
            case 3: fprintf(fout,"<%d , >\n",END);break;
            case 4: fprintf(fout,"<%d , >\n",MAIN);break;
            case 5: fprintf(fout,"<%d , >\n",THEN);break;
            case 6: fprintf(fout,"<%d , >\n",IF);break;
            case 7: fprintf(fout,"<%d , >\n",ELSE);break;
            case 8: fprintf(fout,"<%d , >\n",FOR);break;
            case 9: fprintf(fout,"<%d , >\n",WHILE);break;
            case 10:fprintf(fout,"<%d , >\n",DO);break;
            case 11:fprintf(fout,"<%d , >\n",INT);break;
               default:return(1);                                 /*为什么返回1 ???? */

         }

   }
}
   else if(isdigit(ch)) /*是数字则将该数转换成二进制并在文件中显示出来*/
   {

    token[0]=ch;
    j=1;
    ch=getc(fin);
    while(isdigit(ch))
    {
     token[j++]=ch;
     ch=getc(fin);
    }
    token[j]='\0';
    constant1=atol(token);         /*将数组里的数字变成长整型并用constant1记录 */
    ultoa(constant1,constant[m],2); /*将该数变为二进制数,得到的字符串用 constant[m]记录*/
    fprintf(fout,"<%d , %s>\n",CONST,constant[m]);
    length1=m;
    m++;
   }
   else if(strchr(singleword,ch)>0)    /*是符号则在所建文件里写出对应编号和符号 */
    {
      token[0]=ch;
      token[1]='\0';
      switch(ch)
     {
           case '*':fprintf(fout,"<%d , %s>\n",MUL,token); break;
           case '(':fprintf(fout,"<%d , %s>\n",LP,token); break;
           case ')':fprintf(fout,"<%d , %s>\n",RP,token); break;
           case '{':fprintf(fout,"<%d , %s>\n",LC,token); break;
           case '}':fprintf(fout,"<%d , %s>\n",RC,token); break;
           case ';':fprintf(fout,"<%d , %s>\n",SEMI,token); break;
           case ',':fprintf(fout,"<%d , %s>\n",DOUH,token); break;
           case ':':fprintf(fout,"<%d , %s>\n",COLON,token); break;
           case '#':fprintf(fout,"<%d , %s>\n",JINGH,token); break;
           case '.':fprintf(fout,"<%d , %s>\n",DIAN,token); break;
           case '%':fprintf(fout,"<%d , %s>\n",PERCE,token); break;
             default:return(3);
     }
     ch=getc(fin);
    }
   else if(strchr(doubleword1,ch)>0) /*扫描逻辑符号数组若当前所指的是逻辑符号则执行*/
   {
      token[0]=ch;
      ch=getc(fin);
      token[1]=ch;            /*存的是什么? */
      token[2]='\0';          /*?????为什么 */
     for(i=0;(i<FUHAOSUM)&&(strcmp(token,doubleword2[i])!=0);i++);   /*如果单符后面还是符号即是双符符号则在所建文件里写出对应编号和符号 */
       switch(i)
       {
          case 0:fprintf(fout,"<%d , %s>\n",LE,token); break;
          case 1:fprintf(fout,"<%d , %s>\n",GE,token); break;
          case 2:fprintf(fout,"<%d , %s>\n",EQ,token); break;
          case 3:fprintf(fout,"<%d , %s>\n",NE,token); break;
          case 4:fprintf(fout,"<%d , %s>\n",ADDA,token); break;
          case 5:fprintf(fout,"<%d , %s>\n",SUBS,token); break;
           default:{                                                 /*否则是运算符,在新建文件中写出*/
                     fseek(fin,-1,1); /*将文件指针后退一个字节的位置*/
                     token[1]='\0';
                     switch(token[0])
                     {
                      case '+':fprintf(fout,"<%d , %s>\n",ADD,token); break;
                      case '-':fprintf(fout,"<%d , %s>\n",SUB,token); break;
                      case '<':fprintf(fout,"<%d , %s>\n",LT,token); break;
                      case '>':fprintf(fout,"<%d , %s>\n",GT,token); break;
                      case '=':fprintf(fout,"<%d , %s>\n",FUZH,token); break;
                      case '!':fprintf(fout,"<%d , %s>\n",QUF,token); break;
                      default:return(1);
                     }
                   }
       }
       ch=fgetc(fin);
    }
    
    /*分别处理余下的几种符号,将它们分别在文件中写出*/
    else if(ch=='"')
    {
     token[0]=ch;
     token[1]='\0';
     fprintf(fout,"<%d , %s>\n",YINH,token);
     ch=fgetc(fin);
    }
   else if(ch=='/')      /*判断是否是否是注释,是则跳过*/
   {
    ch=getc(fin);
    if(ch=='*')
    {
     ch1=getc(fin);
     do
     {
      ch=ch1;
      ch1=getc(fin);
     }while((ch!='*'||ch1!='/')&&ch1!=EOF);
     ch=getc(fin);
    }
    else              /*否则将斜杠在文件中写出 */
    {
     token[0]='/';
     token[1]='\0';
     fprintf(fout,"<%d , %s>\n",XIEG,token);
    }
   }
   else           /*其余则认为错误 ,在文件中写出错误*/
   {
    token[0]=ch;
    token[1]='\0';
    ch=getc(fin);
    es=3;
    fprintf(fout,"<%d , %s>\n",ERROR,token);
   }
}
fclose(fin);
fclose(fout);
return(es);
}                    /*读写文件结束 ,将结果返回*/

#include<stdio.h>
#include<ctype.h>
extern int testscan();
FILE *fin ,*fout;
void main()
{
int io=0;
int es=0;
int i=0;
read_file(io);
getch();                 /*从键盘读入字符,不显示;*/
es=testscan();
if(es>0) printf("\nerror\n");    /*三类es的值各是是什么类型的错????*/
else
{
   printf("\n\n\n\nbianyi success!\n");
   printf("--------------------------\n");
   printf("chang shu biao:\n");
   for(i=0;i<=length1;i++)
    printf("constant[%d]=%s\n",i,constant[i]);
     getch();
   printf("--------------------------\n");
   printf("bian liang biao:\n");
   for(i=0;i<=length2;i++)
   printf("id[%d]=%s\n",i,id[i]);
}
io=1;                    /*标识读文件是测试文件还是新建的文件*/
getch();                  /*按任意键进入读所建文件*/
read_file(io);
getch();                     /*完成返回 */
}
 

⌨️ 快捷键说明

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