词法分析器的工作是低级别的分析:将字符或者字符序列转化成记号.。在谈论词法分析时,使用术语“词法记号”(简称记号)、“模式”和“词法单元”表示特定的含义。
在分析时,一是把词法分析器当成语法分析的一部分,另一种是把词法分析器当成
编译程序的独立部分。在前一种情况下,词法分析器不断地被
语法分析器调用,每调用一次词法分析器将从
源程序的字符序列拼出一个单词,并将其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)//如果文件正确,开始解析
#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环境时产生的项目生成头文件