一个简单的C--词法分析器一、 实验目的
设计、编制并调试一个自定义语言C--的词法分析程序,加深对词法分析原理的理解。
二、 实验内容
2.1 自定义语言C--的词法系统
1)类型系统:支持int、char、void基本类型,分别用词法记号表示为关键字int、char和void。
2)常量:字符常量(用单引号括起来)、字符串常量(用双引号括起来)、八/十/六进制整数常量(0开头表示八进制,0x开头表示十六进制)。分别用词法记号表示为ch、str和num。
3)变量:与常量对应,使用标识符表示,词法记号表示为id。
4)表达式运算符:支持加减乘除、求余、取负、自增、自减算术运算,大于、大于等于、小于、小于等于、等于、不等于关系运算,与、或、非逻辑运算,表示为词法记号:‘+’,‘-’,‘*’,‘/’,‘%’,‘-’,‘++’,‘--’,‘>’,‘>=’,‘<’,‘<=’,‘==’,‘!=’,‘&&’,‘||’,‘!’。注意:取负运算和减法运算在词法分析器里是被看做是同一个词法记号。
5)语句:支持赋值语句、do-while、while、for循环语句,if-else、switch-case条件分之语句、函数调用、函数返回、跳转等语句。涉及的词法记号表示为赋值号‘=’,关键字do, while, for, if, else, switch, case, default, return ,break, continue。语句和函数体要求用大括号括起来,case和default后面需要跟冒号,因此需要包括各种分界符作为词法记号:‘{’,‘}’,‘;’,‘:’,‘(’,‘)’,‘,’。
#include
#include
#include
typedef struct Word
{
int num;/*词所属类型
1 -- 关键字
2 -- 变量
21 -- 字符
22 -- 字符串
3 -- 10进制
38 -- 8进制
316 -- 16进制
4 -- 运算符
5 -- 分界符
*/
char w[20];//词
}Word;
int main()
{
char ch,word_temp[20]="";
int i=0,j=0,k=0,key=0,chioce;
int n;
char ktt[43][20]={"int","char","void","if","else","switch","case","default","while","do","for","break","continue","return","main", "begin",
//关键字 0-15
",",":",";","(",")", "[","]","{","}",
//分界符 16-24
"+","-","*","/","%","++", "--","=", "!","&&","||",">",">=","<","<=","==","!="
//运算符 25-42
};
FILE *fp;
Word word[1000];
fp=fopen("example.c","r");
if(!fp)
{
printf("can't open file C_program.txt\n");
exit(1);
}
printf("源程序如下:\n");
while((ch=fgetc(fp))!=EOF)
{
putchar(ch);
}
fclose(fp);
printf("\n词法分析结果如下:\n");
fp=fopen("example.c","r");
n=0;
while((ch=fgetc(fp))!=EOF)
{
//n=0;
if(((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')||(ch=='\"')||(ch=='\''))&&(n==0||n==1))//
{
word_temp[key++]=ch;//连续几个字母的连成单词
word_temp[key]='\0';
n=1;
continue;
}
else if((ch=='+' || ch=='-' || ch=='>' || ch=='<' || ch=='=' || ch=='|'|| ch=='&')&&(n==0||n==2)){//
word_temp[key++]=ch;//连续几个运算符的连成单词
word_temp[key]='\0';
n=2;
continue;
}
else
{
if(strcmp(word_temp,"")!=0)
{
strcpy(word[i].w,word_temp);//将单词拷贝到结构数组中
strcpy(word_temp,"");
key=0;//回到临时数组的开始位置
i++;//结构数组的下标加1
n=0;
}
if(ch==' '||ch==10||ch==' ')//去掉空格、回车和tab键
{
n=0;
continue;
}
else
{
word_temp[0]=ch;
word_temp[1]='\0';//字符串结束符
strcpy(word[i].w,word_temp);//将非字母数字符号拷贝到结构数组中
strcpy(word_temp,"");
key=0;//回到临时数组的开始位置
i++;
n=0;
}
}
}
for(j=0;j=0&&k<16)
word[j].num=1;//关键字
else if(k>=16&&k<25)
word[j].num=5;//分界符
else if(k>=25&&k<43)
word[j].num=4;//运算符
break;
}
else if(word[j].w[0]>='1'&&word[j].w[0]<='9'){
word[j].num=3;//10进制
}
else if(word[j].w[0]=='0'&&word[j].w[1]==NULL){
word[j].num=3;//10进制
}
else if(word[j].w[0]=='0'&&word[j].w[1]=='x'){
word[j].num=316;//16进制
}
else if(word[j].w[0]=='0'&&word[j].w[1]!='x'&&word[j].w[1]!=NULL){
word[j].num=38;//8进制
}
else if(word[j].w[0]=='\''){
word[j].num=21;//字符
}
else if(word[j].w[0]=='\"'){
word[j].num=22;//字符串
}
else
word[j].num=2;//变量
}
}
for(j=0;j