【C语言/vs2010】词法分析器

       词法分析器又称扫描器。 词法分析是指将我们编写的文本代码流解析为一个一个的记号,分析得到的记号以供后续 语法分析使用。
词法分析器的工作是低级别的分析:将字符或者字符序列转化成记号.。在谈论词法分析时,使用术语“词法记号”(简称记号)、“模式”和“词法单元”表示特定的含义。
在分析时,一是把词法分析器当成语法分析的一部分,另一种是把词法分析器当成 编译程序的独立部分。在前一种情况下,词法分析器不断地被 语法分析器调用,每调用一次词法分析器将从 源程序的字符序列拼出一个单词,并将其Token值返回给语法分析器。后一种情况则不同,词法分析器不是被语法分析器不断地调用,而是一次扫描全部单词完成 编译器的独立一遍任务。
       词法分析器主要特点是不依靠语法,而只依靠词法,即处理一个单词时不依赖于外部单词的信息,因此词法分析器一般都很简单。当然,对某些语言在作词法分析时,在有些情况下不得不往前查看多个字符,有时还要做一些特殊处理,还有一些在 词法分析中处理不了的,要留到 语法分析中进行处理。
本算法主要利用状态转换图生成一个词法分析器,对输入的程序进行词法分析,并将分析得到的单词造表。其中关键字表和界限符表的大小是由高级语言的子集决定的,可以用 数组装载;而 标识符表和常数表的大小取决于输入的待分析程序中的变量、过程名、常数的个数,所以要用 指针组成 动态链表来装载。当然为了方便,我们也把它定义成数组处理。 语法分析时,调用词法分析器,根据已知 文法利用 递归向下分析,检查语法错误。


/* this is cifa-ana-program */
#include <stdio.h>
#include <ctype.h>
#define keywordSum 8
char *keyword[keywordSum]={"if","else","for","while","do","int","read","write"};//定义关键字串
char singleword[50]="+-*/(){};,:";//定义可能单独出现的运算符字串
char doubleword[10]="><=!";//定义可能成对或多个连续出现的运算符字串
extern char Scanin[300],Scanout[300];//声明全局变量输入输出
extern FILE *fin,*fout;//声明全局文件*fin,*fout
int TESTscan()  /* define cifa-fenxi-hanshu:TESTscan()*/
{
  char ch,token[40];
  int es=0,j,n;//es初始化
  printf("\n\n\n input the input-filename of before-analyse:");//输入要解析的文件名
  scanf("%s",Scanin);//将输入的文件绑定scanin
  printf("\n input the output-filename of after-analyse:");//输出解析后的文件名
  scanf("%s",Scanout);//将输出的文件名绑定scanout
  if ((fin=fopen(Scanin,"r"))==NULL)
    {printf("\n the input-filename error\n");//解析文件不存在,输出文件名错误
     return(1);}//返回一个大于0的es值
  if ((fout=fopen(Scanout,"w"))==NULL)
    {printf("\n the output-filename error\n");//解析后输出文件不存在。输出文件名错误
     return(2);//返回一个大于0的es值
    }
  ch=getc(fin);//从fin指向的文件中读取一个字符传递给ch
  while (ch!=EOF)//如果文件正确,开始解析


    {while (ch==' '||ch=='\n'||ch=='\t') ch=getc(fin);//如果ch为空或\n或\t,读取下一个字符,直到为非空字符为止
     if (isalpha(ch)) /*ch is a letter*/  //判断当前ch字符是否为英文字符
       {
  token[0]=ch;j=1;//将字符存入token,计数器j增长1
        ch=getc(fin);//读取下一个字符
        while (isalnum(ch))//判断当前ch字符是数字
         { token[j++]=ch;ch=getc(fin);}//读取完整整个已经识别了开头的那个英文字符串
        token[j]='\0';
        n=0;
        while ((n<keywordSum)&& strcmp(token,keyword[n])) n++;//解析关键字,将关键字与定义中keywo相对应,如识别for,n即为2
        if (n>=keywordSum)//判断字符时候在已经定义好的keyword中
          fprintf(fout,"%s\t%s\n","ID",token);//如果不在,输出ID token 的形式
        else fprintf(fout,"%s\t%s\n",token,token);//如果在。输出token token的形式
       }
     else if (isdigit(ch)) /*ch is a digit*/  //判断当前字符是否为数字
            { token[0]=ch;j=1;ch=getc(fin);
              while (isdigit(ch))
                { token[j++]=ch;ch=getc(fin);}
              token[j]='\0';
              fprintf(fout,"%s\t%s\n","NUM",token)
              ;//将数字以mun token的形式输入,识别方法与别英文字符串的方法相似
            }
          else if (strchr(singleword,ch)>0)//判断是否为singleword中关键字,识别方法与别英文字符串的方法相似
                  { token[0]=ch;token[1]='\0';ch=getc(fin);
                    fprintf(fout,"%s\t%s\n",token,token);
           }
               else if (strchr(doubleword,ch)>0)//判断是否为doubleword中关键字,识别方法与别英文字符串的方法相似
                      { token[0]=ch;ch=getc(fin);
                         if (ch=='=') {token[1]=ch;token[2]='\0';ch=getc(fin);}
                         else token[1]='\0';
                         fprintf(fout,"%s\t%s\n",token,token);
                      }




                    else if (ch=='/')//注释判断,如果为‘/’读取下一字符,下同
                           { ch=getc(fin);


                             if (ch=='*')
                               { char ch1;ch1=getc(fin);
                                 do {ch=ch1;ch1=getc(fin);}
                                 while ((ch!='*'||ch!='/')&& ch1!=EOF);//如果读取为/*或//
                          ch=getc(fin);
        }
                             else { token[0]='/';token[1]='\0';
                                    fprintf(fout,"%s\t%s\n",token,token);//如果识别不是/*或//,说明不是注释,可以输出
        }




             }
                         else { token[0]=ch;token[1]='\0';
                         ch=getc(fin);es=3;//es大于0
                                fprintf(fout,"%s\t%s\n","ERROR",token);
                       }
            }
                        fclose(fin);fclose(fout);
                 return(es);//返回es
      }


/* in under is cifa-analyse main program */
#include <stdio.h>
#include <ctype.h>
extern int TESTscan();
char Scanin[300],Scanout[300];
FILE *fin,*fout;
void main()
 {
   int es=0;
   es=TESTscan();//将函数返回值赋给es
   if (es>0) printf("\n cifa-analyse error to stop!\n");//如果es大于0,输出cifa-analyse error to stop!
   else  printf("\n cifa-analyse succeful!\n");//es小于等于0,解析成功
  }

注:编译原理词法分析器,生成成功,主函数前头文件为tc环境转换vs2010环境时产生的项目生成头文件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值