C语言 词法分析器设计_编译原理
- 格式:doc
- 大小:131.00 KB
- 文档页数:7
词法分析器设计一、问题描述处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。
二、实验思路1、本实验思路很简单,就是逐个匹配测试文件的每个字符与程序中所标识的符号,总共分为几个比较模块,先是字母数字模块,可以识别出C语言程序中保留字,标识符和数字,其次是运算符和界符模块,可以识别出运算符和界符,最后一个模块就是未标识的符号,此时程序会报错,然后依次循环,直到文件结束。
2、采用结构体来存储符号的类型和符号本身:struct point{ char *kind;char value[10];};另外采用C语言文件指针和相关函数处理待测试文件以及测试结果文件。
3、程序中的函数名指示含义:keyword----保留字,Identifier---标识符,Digit---数字,CaculatorIdentifier---运算符,PatitionIdentifier---界符4、程序中所定义的符号采用char类型,只能对C语言中最常见的单字符的符号进行定义,如‘+’,‘<’,而对于“<=”,”>=”及“++”,“--”则不能处理。
因此本程序并不能实现对所有符号的归类。
三、实验代码#include <stdio.h>#include <string.h>char keywordtable[30][10]= {"int","char","float","double","signed","unsigned", "if","else","break","while","return","switch", "case","continue","for","default","void","const", "static","long","struct","auto","register","typedef", "enum","extern","short","goto","sizeof","do",};char caculatetable[15]={'+','-','*','/','%','(',')','=','>','<','#'};char partitiontable[10]={',',';','.',' ','{','}','"','[',']'};struct point{ char *kind;char value[10];};int IsLetter(char ch){ if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z') return 1;else return 0;}int IsDigit(char ch){if(ch>='0'&&ch<='9') return 1;else return 0;}int Reserve(char strToken[30]){for(int i=0;i<30;i++)if(strcmp(keywordtable[i],strToken)==0) return 1;return 0;}void operate(FILE *fp,struct point a){fp=fopen("d:测试结果.txt","a+");fprintf(fp,"< %s , %s >\n",a.kind,a.value);fclose(fp);}void Retract(FILE *fp)//顺序读写{ fseek(fp,-1L,1);}void Print(struct point a){ printf("< %s, \"%s\" >\n",a.kind,a.value);}int IsCaculator(char ch){int i;for(i=0;i<15;i++)if(caculatetable[i]==ch) return 1;return 0;}int IsPatition(char ch){ int i;for(i=0;i<10;i++)if(partitiontable[i]==ch) return 1;return 0;}int IsSpecial(char ch){if(ch=='+'||ch=='-'||ch=='/'||ch=='%'||ch=='>'||ch=='<'||ch=='*'||ch=='=') return 1;return 0;}int main(){int code;struct point result;char strToken[30];char ch;char *p;FILE *fp,*fq;fp=fopen("d:测试文件.txt","r");if(fp==NULL){ printf("file does not exit!!");return -1;}while(1){p=strToken;ch=fgetc(fp);if(feof(fp))//输入输出函数,检查文件是否结束,如结束,则返回非零值,否则返回0 break;if(ch==' ') continue;if(IsLetter(ch)){while(IsLetter(ch)||IsDigit(ch)){*p=ch;p++;*p='\0';ch=fgetc(fp);if(feof(fp))return -1;}Retract(fp);//顺序读取code=Reserve(strToken);if(code==1){ result.kind="keyword";//保留字strcpy(result.value,strToken);operate(fq,result);Print(result);}else{ result.kind="Identifier";//标识符strcpy(result.value,strToken);operate(fq,result);Print(result);}}else if(IsDigit(ch)){while(IsDigit(ch)){ *p=ch;p++;*p='\0';ch=fgetc(fp);if(feof(fp)) return -1;}Retract(fp);result.kind="Digit";//数字strcpy(result.value,strToken);operate(fq,result);Print(result);}else if(IsPatition(ch)||IsCaculator(ch)){ if(IsPatition(ch)){ result.kind="PatitionIdentifier";//界符*p=ch;p++;*p='\0';strcpy(result.value,strToken);operate(fq,result);Print(result);}if(IsCaculator(ch)){char ch2;ch2=fgetc(fp);if(!IsCaculator(ch2)) Retract(fp);result.kind="CaculatorIdentifier";//运算符*p=ch;p++;*p='\0';if(IsSpecial(ch)&&ch2=='='){ *p=ch2;p++;*p='\0';}if((ch=='>'||ch=='<'||ch=='+'||ch=='-')&&ch2==ch){ *p=ch2;p++;*p='\0';}strcpy(result.value,strToken);operate(fq,result);Print(result);}}else{ if(ch=='\n') continue;result.kind="Error!!";//其他未声明的均报错strcpy(result.value,strToken);operate(fq,result);//输出到测试结果文件printf("Error occurs! at %c\n",ch);}}return 1;}四、实验结果图1 实验结果测试文件:图2 测试文件测试结果文件:图3 测试结果文件五、实验总结本实验写的较为简单,只是表示了一些最常见的C语言符号,像是保留字,英文字母,数字,算术运算符和几个关系运算符,另外还有一些常见界符,如‘,’,‘;’,‘[’,‘]’,因为定义符号时采用char,这只适用单个字符的符号,而之后并没有再声明其他带有多个符号的符号,也就没有采用string类型或char[][]数组类型,所以像是测试文件中的注释符‘/*’,该程序就识别不出来,会提示报错;另外本实验在辨别符号时,采用穷举,没有用什么特别快捷的搜索方法,对一些较为简单的C语言程序,还是能识别出的。