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

📄 main.c

📁 词法分析器(编译原理) Java语言词法分析器的设计与实现
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "stdio.h"
#include "string.h"

struct stream {                 //属性字流 
       char attribute[6];
       int site;
};
struct stream flow;
 
char buf[31];
char buf1[16];    //第一缓冲区,存放被覆盖的前半区的字符 
char buf2[16];    //第二缓冲区,存放被覆盖的后半区的字符
int count1,count2;        //count1指向缓冲区里的当前字符,count2表示不是关键字的标识符的个数 
int count3,count4,count5,count6,count7;        //指向变量表和错误的单词表,变量值表,注释表,字符串表 
int index1; //指示第二缓冲区是否有内容 
int row,line1,line2,linetotal,total; 
char inkey[20],ininden[20],innum[14],instring[50];
char character;            //存储第一次扫描的字符 
char numstring[4];         //存储字符数,行号,列号转换的字符串 

char keyword[50][13] = {
         "abstract","boolean","break","byte","case","catch","char","class",
         "const","continue","default","do","double","else","extends","false",
         "final","finally","float","for","goto","if","implements","import",
         "instanceof","int","interface","long","native","new","null","package",
         "private","protected","public","return","short","static","super","switch",
         "synchronized","this","throw","throws","transient","true","try","void",
         "volatile","while"
};
char words[50][13];        //变量表 
char value[50][13];        //变量或常量的值 
char note[80][20] = {"//","/*","*/"};                           //注释表 
char op[50][5] = {                                //运算符表 
         "==","=","++","+=","+","--","-=","-","*=","*","/=",
         "/","%=","%","^=","^","&=","&","|=","|","!=","!","&&","||",
         ">",">=",">>",">>=",">>>",">>>=","<","<=","<<","<<=",
         "?",":","~","[","]","(",")",".",",","{","}",";"," "
         };
char strings[50][50] = {"\""}; //存放字符串中单词的表 
char inerror[50][50];      //错误单词表 

FILE *fp,*fp1;
long int offset; 
//读取字符到缓冲区前半区 
void readin1() {
     char ch,ch1;
     char filename[10] ={"a.txt"}; 
     int i = 15;                    
     fp = fopen(filename,"r");
     fseek(fp,offset,0);                    //定位指针的位置 
     while(1) {
          ch = fgetc(fp);
          buf[i++] = ch;
          if(i == 30) break;
     }
     buf[i] = '\0';
     offset = ftell(fp);                //保存当前指针 
     fclose(fp);
}
//把后半区的内容送到前半区 
void readin2() {
     int i;
     for(i = 0; i < 15; i++) {       //把后半区的字符送给前半区 
           buf1[i] = buf[i];
           buf[i] = buf[i+15];
     } 
}
//把第二缓冲区的内容送到后半区 
void readin3() {
     int i;
     for(i = 0; i < 15; i++) {       //把后半区的字符送给前半区 
           buf[i+15] = buf2[i];
     } 
     index1 = 0; 
}
//从缓冲区中读取一个字符 
char readchar() {
     char ch; 
     if(count1 == 15) {               //读字符到缓冲区中间,则重新读入字符到缓冲区 
           if(index1 == 1) {          //第二缓冲区里有字符 
                   readin2();
                   readin3();
           }
           else {
                readin2(); 
                readin1();
           }           
           count1 = 0;
     }
     ch = buf[count1];
     count1++; 
     return ch;
} 
//回退一个字符 
void untread() {
     char ch; 
     int i; 
     count1--;
     
     if(count1 < 0) {      //若正好在第一个字符,则把第一缓冲区的内容送到前半区 
         for(i = 0; i < 15; i++) {
             buf2[i] = buf[i+15]; 
             buf[i+15] = buf[i]; 
             buf[i] = buf1[i];
         }
         index1 = 1;          //表示第二缓冲区有内容 
         count1 = 14; 
     } 
} 
//清inkey和ininden,innum 
void clean() {
     int i;
     for(i = 0; i < 14; i++) {
           inkey[i] = '\0';
           ininden[i] = '\0';
           innum[i] = '\0'; 
     }
}
//初始化 
void initi() {
    int i;
    for(i = 0; i < 31; i++) {
          buf[i] = '#';
    }
    count1 = 0;
    count2 = 0; 
    count3 = 0;
    count4 = 0; 
    count5 = 0; 
    count6 = 3;
    count7 = 1; 
    index1 = 0;
    offset = 0L; 
    row = 1;
    line1 = 0;
    line2 = 0;
    total = 0; 
    linetotal = 0; 
} 
//把整数转换为字符串,即行号和列号 
void change(int a) {
     int i; 
     if(a < 10) {          
          numstring[2] = a + 48;
          numstring[1] = ' ';
          numstring[0] = ' '; 
     } 
     else if(a < 100) { 
         i = a % 10;
         numstring[2] = i + 48;
         a = a / 10;
         numstring[1] = a + 48;
         numstring[0] = ' ';
     }
     else if(a < 1000) { 
         i = a % 10;
         numstring[2] = i + 48;
         a = a / 10;
         i = a % 10; 
         numstring[1] = i + 48;
         a = a / 10;
         numstring[0] = a + 48;
     }
     numstring[3] = '\0'; 
} 
//把属性字流信息写进文件里 
void writefile() {
     char filename[20] ={"scanner_output.txt"},ch,string[3];  
     fp1 = fopen(filename,"a");                               
     
     change(total);                  //总字数 
     fputs(numstring,fp1);
     ch = ':';
     fputc(ch,fp1);
     change(linetotal);              //每行的字数 
     fputs(numstring,fp1);
     ch = ' ';
     fputc(ch,fp1);
     ch = '(';
     fputc(ch,fp1); 
     change(row);                    //单词的位置 
     fputs(numstring,fp1);
     ch = ',';
     fputc(ch,fp1); 
     change(line2); 
     fputs(numstring,fp1);
     ch = ')';
     fputc(ch,fp1);
     ch = ';';
     fputc(ch,fp1); 
     ch = '(';
     fputc(ch,fp);
     
     strcpy(string,flow.attribute);              //字符的属性     
     fputs(string,fp1);
     
     ch = ',';
     fputc(ch,fp1);      
     ch = flow.attribute[3];
     if(ch == '0') { 
         ch = flow.attribute[4];
         switch (ch) {                               //从各个表中读入字符流的值 
              case '0': 
                 strcpy(string,inerror[flow.site]);         //
                 fputs(string,fp1);
                 break;
              case '1': 
                 strcpy(string,note[flow.site]);         //
                 fputs(string,fp1);
                 break;
              case '2':  
                 strcpy(string,op[flow.site]);         //
                 fputs(string,fp1);
                 break;
              case '3':  
                 strcpy(string,keyword[flow.site]);         //
                 fputs(string,fp1);
                 break;
              case '4':  
                 strcpy(string,words[flow.site]);         //
                 fputs(string,fp1);
                 break;
              case '5':  
                 strcpy(string,keyword[flow.site]);         //
                 fputs(string,fp1);
                 break;
              case '6': 
                 strcpy(string,instring);         //
                 fputs(string,fp1);
                 break;
              case '7':  
                 strcpy(string,value[flow.site]);         //
                 fputs(string,fp1);
                 break;
              case '8':
                 strcpy(string,value[flow.site]);         //
                 fputs(string,fp1);
                 break;
              case '9': 
                 strcpy(string,strings[flow.site]);         //
                 fputs(string,fp1);
                 break;
         }
     }
     else {
         strcpy(string,op[flow.site]);         //
         fputs(string,fp1); 
     } 
     ch = ')';
     fputc(ch,fp1); 
     ch = '\n';
     fputc(ch,fp1); 
     fclose(fp1);
}     
//扫描到错误的单词 
void error(char *string) {
     char ch,*sp;
     int i = 0;
     
     while(*string != '\0') {            //把错误的字符之前的字符传递给错误的单词表 
             inerror[count3][i] = *string;
             i++;
             string++;
     }
     
     ch = readchar();                                              //继续读入错误的单词 
     while( ch != ' ' && ch != '\n' && ch != EOF) {                            //
            if(ch == '/') {
                   character = ch; 
                   ch = readchar();
                   if(ch != '/' && ch != '*') {                                //
                        inerror[count3][i++] = character; 
                        inerror[count3][i] = ch;
                        ch = readchar();
                        i++;
                        line1++;
                   }
                   else break;                            //遇到注释停止 
            }
            else { 
                inerror[count3][i] = ch;
                ch = readchar();
                i++;
                line1++;
            }
     }
     sp = "0x100";
     strcpy(flow.attribute,sp);
     flow.site = count3;
     count3++;
     linetotal++;
     total++; 
     writefile();
}
//扫描标识符 
void identifier() {
     char ch,*sp;
     int i = count2,j = 0; 
     ch = character;                    //第一个字符保存在character,则不用回退 
     line1++;
     line2 = line1;
     line2 -= count2; 
     
     while ( (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '$' || ch == '_') {
           ininden[i++] = ch; 
           ch = readchar(); 
           if(i == 19) break; 
     }
     if(i == count2) { i = 0;}
     else { ininden[i] = '\0';}
     line1 = line1 + i - 1;
     if(i < 19) {             //扫描结束, 
          for(j = 0; j < count4; j++) {
                if(strcmp(ininden,words[j]) == 0) {       //判断标识符是否已存在 
                    sp = "0x104"; 
                    strcpy(flow.attribute,sp); 
                    flow.site = j;
                    total++; 
                    linetotal++; 
                    writefile();
                    break;
                }
          }
          if(j == count4) {                    //不存在则写进变量表 
              strcpy(words[count4],ininden); 
              sp = "0x104"; 
              strcpy(flow.attribute,sp); 
              flow.site = j;
              total++; 
              linetotal++; 
              writefile();
              count4++;                         
          } 
     }               
     else {                //大于12个字符为错误单词 
          sp = ininden;
          untread(); 
          error(sp); 
     }
     clean(); 
     count2 = 0; 
}
//识别关键字 
void key() {
     char ch,*sp;
     int i = 0; 

⌨️ 快捷键说明

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