C语言词法分析器 源代码 风君版
- 格式:doc
- 大小:69.50 KB
- 文档页数:22
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#define SPACE 0x20 //空格键#define CHANGE 'c' //转义字符#define STRING 'S' //引号里的字符串#define BOUNDARY 'B' //界符#define OPERATION 'O' //运算符#define WORD 'I' //标识符#define KEY_WORD 'K' //关键字#define DIGIT 'n' //数字,包括小数#define DOTH 'd' //头文件,“.h”文件#define INT 't'#define VOID 'v'#define IF 'f'#define ELSE 'e'#define WHILE 'w'#define FOR 'r'#define MAIN 'm'#define PRINTF 'p'#define INCLUDE 'u'#define FLOAT 'l'#define KEYNUM 10#define BOUNDNUM 8#define OPERNUM 7#define V ALUENUM 100/************************************************************************/ /* data type */ /************************************************************************/ struct bianliang{int id;char name[20];int value;};struct changliang{int data;};KeyWord[KEYNUM][8]={"int","void","if","else","while","for","main","printf","include","float"} ;char Boundary[BOUNDNUM]={'"',';',',','(',')','#','{','}'};char Operation[OPERNUM]={'+','-','*','/','=','<','>'};charLogogram[KEYNUM]={INT,VOID,IF,ELSE,WHILE,FOR,MAIN,PRINTF,INCLUDE,FLOAT};char Value[V ALUENUM][8];int Value_n=0;int ErrorLine=0;int QuotationCount=0; //计算引号的数量int QuotationFlag=0; //引号数量为奇数时为1,偶数时为0char LastOpera=0; //用于判断"=="号存前一个"="号/************************************************************************//* function describe *//************************************************************************/int isKeyWord(char* s) //是关键字返回1,否则返回0{int i;for (i=0;i<KEYNUM;i++){if (strcmp(KeyWord[i],s)==0){return i+1;}}return 0;}int isBoundary(char ch) //是界符{int i;for (i=0;i<BOUNDNUM;i++){if (Boundary[i]==ch){return i+1;}}return 0;}int isOperation(char ch) //是运算符int i;for (i=0;i<OPERNUM;i++) {if (Operation[i]==ch){return i+1;}}return 0;}int isDigit(char *s) //是数字{int i,l=strlen(s);for (i=0;i<l;i++){if (!isdigit(s[i])){break;}}if (i>=l){return 1;}else{if ('.'==s[i]){i++;for (;i<l;i++){if (!isdigit(s[i])){break;}}}else{return 0;}if (i>=l)return 1;elsereturn 0;}}int isDotH(char *s) //是头文件{int i,l=strlen(s);for (i=0;i<l;i++){if (!isalpha(s[i])){break;}}if (i>=l){return 0;}else{if ('.'==s[i]){i++;if(s[i]=='h')return 1;elsereturn 0;}elsereturn 0;}}int isWord(char *s) //是标识符{int i=0,l=strlen(s);if (isalpha(s[i])){i++;for (;i<l;i++){if (!isalnum(s[i])){break;}}}if (i>=l){return 1;}elsereturn 0;}void isWhat(int *i,char *str,FILE *fileOutput,FILE *fileOutput2) //判断字符串,并把相应类型存入文件{int n;struct bianliang temp;struct changliang t;FILE *file=fopen("num.txt","ab");if(1!=*i){str[--(*i)]='\0';if(n=isKeyWord(str)){fputs(str,fileOutput);fputc('\t',fileOutput);fputc(KEY_WORD,fileOutput);fputc('\t',fileOutput);if(isKeyWord(str)>9)fputc(isKeyWord(str)+'a'-10,fileOutput);elsefputc(isKeyWord(str)+'0',fileOutput);fputc('\t',fileOutput);fputc(Logogram[n-1],fileOutput);fputc('\n',fileOutput);}else if(isWord(str)){fputs(str,fileOutput);fputc('\t',fileOutput);fputc(WORD,fileOutput);fputc('\t',fileOutput);for(n=0;n<Value_n;n++){if(0==strcmp(Value[n],str))break;}if(n==Value_n){n=++Value_n;strcpy(Value[n-1],str);temp.id=n-1;strcpy(,str);temp.value=0;fwrite(&temp,sizeof(struct bianliang),1,fileOutput2); fputc('0'+n,fileOutput);}else{fputc('0'+n+1,fileOutput);}fputc('\t',fileOutput);fputc('i',fileOutput);fputc('\n',fileOutput);}else if (isDotH(str)){fputs(str,fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc(DOTH,fileOutput);fputc('\n',fileOutput);}else if (isDigit(str)){fputs(str,fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc(DIGIT,fileOutput);fputc('\n',fileOutput);t.data=atoi(str);fwrite(&t,sizeof(struct changliang),1,file);}(*i)=0;}fclose(file);}void writeMessage(FILE *f){fputs("字符\t类型\t附加值\t缩写\n",f);}void error(){printf("%d line error!\n",ErrorLine);exit(1);}/************************************************************************/ /* main */ /************************************************************************/ void main(){FILE*fileInput;FILE*fileOutput;FILE*fileOutput2;char ch,qtemp;char str[20];int i;int flag=0;fileInput=fopen("1.cpp","r");fileOutput=fopen("object.txt","w");fileOutput2=fopen("variable.txt","w");writeMessage(fileOutput);if (NULL!=fileInput){i=0;do{ch=fgetc(fileInput);str[i++]=ch;if(isBoundary(ch)){if(1==isBoundary(ch)){QuotationCount++;if (0==QuotationCount%2){QuotationFlag=0;}elseQuotationFlag=1;}isWhat(&i,str,fileOutput,fileOutput2);fputc(ch,fileOutput);fputc('\t',fileOutput);fputc('B',fileOutput);fputc('\t',fileOutput);if(isBoundary(ch)>9)fputc(isBoundary(ch)+'a'-10,fileOutput); elsefputc(isBoundary(ch)+'0',fileOutput);fputc('\t',fileOutput);fputc(Boundary[isBoundary(ch)-1],fileOutput); fputc('\n',fileOutput);i=0;}else if(isOperation(ch)){if(0==QuotationCount%2){isWhat(&i,str,fileOutput,fileOutput2);if ('='==ch){qtemp=fgetc(fileInput);if ('='==qtemp){fputc('=',fileOutput);fputc('=',fileOutput);flag=1;}else{fputc('=',fileOutput);fseek(fileInput,-1,SEEK_CUR);flag=0;}}elsefputc(ch,fileOutput);fputc('\t',fileOutput);fputc(OPERA TION,fileOutput);fputc('\t',fileOutput);if(isOperation(ch)>9)fputc(isOperation(ch)+'a'-10,fileOutput);elsefputc(isOperation(ch)+'0',fileOutput);fputc('\t',fileOutput);if (flag){fputc('q',fileOutput);}elsefputc(Operation[isOperation(ch)-1],fileOutput); fputc('\n',fileOutput);i=0;}else{fputc(ch,fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc('c',fileOutput);fputc('\n',fileOutput);i=0;}}else if('\n'==ch){isWhat(&i,str,fileOutput,fileOutput2); ErrorLine++;i=0;}else if(SPACE==ch||'\t'==ch){if(1<i)isWhat(&i,str,fileOutput,fileOutput2); elsei=0;}else if ('\\'==ch){if (1==QuotationFlag){if (1!=i){str[--i]='\0';fputs(str,fileOutput);fputc('\t',fileOutput);fputc(STRING,fileOutput);fputc('\n',fileOutput);i=0;}ch=fgetc(fileInput);if ('t'==ch){fputc('\\',fileOutput);fputc('t',fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc(CHANGE,fileOutput);fputc('\n',fileOutput);i=0;}else if('b'==ch){fputc('\\',fileOutput);fputc('b',fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc(CHANGE,fileOutput);fputc('\n',fileOutput);}else if ('n'==ch){fputc('\\',fileOutput);fputc('b',fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc('\t',fileOutput);fputc(CHANGE,fileOutput);fputc('\n',fileOutput);i=0;}}else error();}else if (1==QuotationFlag){continue;}else if (isalnum(ch)||ch=='.'){}else if (EOF!=ch){error();}}while(EOF!=ch);printf("词法分析完毕\n");fclose(fileInput);}fclose(fileOutput);fclose(fileOutput2);}/****************************************************/ /* 1.cpp 例子文件*/#include <stdio.h>{int i;int j;int m;m=1;for(i=0;i<5;i=i+1) {printf("\t",i);for(j=0;j<i;j=j+1) {printf("\b",i);}for(j=0;j<m;j=j+1) {printf("*",i);}printf("\n",i);m=m+2;}}。
编译原理----词法分析程序----C语⾔版#include<stdio.h>#include<string.h>#include<stdlib.h>char KeyWord[20][100]={"begin","end","if","while","var","procedure","else","for","do","int","read","write"};char yunsuanfu[]="+-*/<>%=";char fenjiefu[]=",;(){}:";int main(){char test[]="var a=10;\nvar b,c;\nprocedure p; \n\tbegin\n\t\tc=a+b\n\tend\n";int len_yunsuanfu=strlen(yunsuanfu);int len_fenjiefu=strlen(fenjiefu);puts(test);int length=strlen(test),i,j,k;for(i=0;i<length;i++){if(test[i]==' '||test[i]=='\n'||test[i]=='\t')continue;int tag=0;for(j=0;j<len_fenjiefu;j++){if(fenjiefu [j]==test[i]){printf("分界符\t%c\n",test[i]);tag=1;break;}}if(tag==1)continue;tag=0;for(j=0;j<len_yunsuanfu;j++){if(yunsuanfu[j]==test[i]){printf("运算符\t%c\n",test[i]);tag=1;break;}}if(tag==1)continue;if(test[i]>='0'&&test[i]<='9'){printf("数字\t");while(test[i]>='0'&&test[i]<='9'){printf("%c",test[i]);i++;}printf("\n");continue;}char temp[100];j=0;while(test[i]>='0'&&test[i]<='9'||test[i]>='a'&&test[i]<='z'||test[i]>='A'&&test[i]<='Z'||test[i]=='_') {temp[j++]=test[i];i++;}i--;temp[j++]='\0';tag=0;for(j=0;j<20;j++){if(strcmp(temp,KeyWord[j])==0){tag=1;printf("关键字\t%s\n",temp);break;}}if(tag==0)printf("标识符\t%s\n",temp);}}。
词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。
(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。
空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。
2.2 各种单词符号对应的种别码:输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
3.1 主程序示意图:主程序示意图如图3-1所示。
其中初始包括以下两个方面:⑴关键字表的初值。
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,};图3-1(2)程序中需要用到的主要变量为syn,token和sum3.2 扫描子程序的算法思想:首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。
词法分析器源代码#include <iostream> #include <vector> #include <string> #include<fstream>/*单词种别码*/#define _CHAR 1 #define _INT 2#define _SHORT 3 #define _LONG 4 #define _SIGNED 5 #define _UNSIGNED 6 #define _FLOAT 7 #define _DOUBLE 8 #define _CONST 9 #define _VOID 10 #define _VOLATILE 11 #define _ENUM 12 #define _STRUCT 13 #define _UNION 14 #define _TYPEDEF 15 #define _AUTO 16 #define _EXTERN 17 #define_STATIC 18 #define _REGISTER 19 #define _IF 20#define _ELSE 21 #define _SWITCH 22 #define _CASE 23 #define_DEFAULT 24 #define _WHILE 25 #define _DO 26#define _FOR 27 #define _BREAK 28 #define _CONTINUE 29 #define _GOTO 30 #define _RETURN 31 #define _SIZEOF 32 #define _INCLUDE 33 #define_DEFINE 34 /*以上为关键字的种别码*/#define _ID 40 //标识符#define _NUM 50 //数#define _AS 51 //= #define _PLUS 52 //+ #define _SUB 53 //- #define _TIMES 54 // * #define _DIV 55 // / #define _LP 56 // ( #define _RP 57 // ) #define _LB1 58 // [ #define _RB1 59 // ] #define _LB2 60 //{ #define _RB2 61 // } #define _COM 62 // , #define _COL 63 // : #define_SEM 64 // #define _POINT 65 // . #define _LG 66 // > #define _LT 67 // < #define _ME 68 // >= #define _LE 69 // <= #define _EQ 70 // == #define _NE 71 // != #define _A 72 // >> #define _B 73 // >>= #define _C 74 // << #define _D 75 // <<= #define _E 76 // & #define _F 76 // && #define _G 77 // &= #define _H 78 // | #define _I 79 // || #define _J 80 // |= #define _K 81 // ~ #define _L 82 // ++ #define _M 83 // -- #define _N 84 // -> #define _O 85 // += #define _P 86 // -= #define _Q 87 // *=#define _R 88 // /= #define _S 89 // %=#define _T 90 // ^=#define _U 91 // %#define _V 92 // "#define _W 93 // '#define _X 94 // ?#define _EROOR -1 // 错误using namespace std;int ERROR_NUM=0; //记载词法编译错误个数bool isnum(string str) //判断是不是合法的数字{int y;int i;int j=0;int k=0;for(i=0;i<str.size();i++){if(!(str[i]<='9'&&str[i]>='0')){k++;if((k-j)>1){cout<<"数字串"<<str<<"出现词法错误~"<<endl;return false;} if(str[i]=='.') {j++;if(j>1) {cout<<"数字串"<<str<<"出现词法错误~"<<endl;return false;} }else if((str[i]=='E'||str[i]=='e')&&(str[i-1]<='9'&&str[i-1]>='0')&&((str[i+1]<='9'&&str[i+1]>='0')||(y=i+1)==str.size())) continue;else{cout<<"数字串"<<str<<"出现词法错误~"<<endl;return false;} }}return true;}/*该函数用来略过空格和换行符,找到有效字符的位置第一个参数为目标字符串,第二个参数为开始位置返回值为连续的空格和换行后的第一个有效字符在字符串的位置*/int valuable(string str,int i) {while(true){if(str[i]!=' '&&str[i]!='\n')return i;i++;}}int isexp(string str,int i) {if(str[i]=='/'&&str[i+1]=='/'){while(str[i]!='\n'){i++;}}return i;}int iskey(string str) //判断是不是关键字{stringp[34]={"char","int","short","long","signed","unsigned","float","double", "const","void","volatile","enum","struct","union","typedef","auto"," extern","static","register","if","else","switch","case","default","while","do", "for","break","continue","goto","return","size of","#include","#define"};vector<string> ppp(p,p+34); int u;for(u=0;u<ppp.size();u++)if(!pare(ppp[u]))return u+1;return 0;}vector<pair<int,string> > scan(vector<string> vec)//本次程序的主要分析程序 {vector<pair<int,string> > temp;int i;for(i=0;i<vec.size();i++){if(vec[i].size()==1){if(vec[i]==">"){if(vec[i+1]=="="){string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_ME,jk);temp.push_back(pp);continue;}else if(vec[i+1]==">"&&vec[i+2]!="=") { string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_A,jk);temp.push_back(pp);continue; }else if(vec[i+1]==">"&&vec[i+2]=="="){ string jk=vec[i];jk.append(vec[++i],0,1);jk.append(vec[++i],0,1);pair<int,string> pp(_B,jk);temp.push_back(pp);continue;}else {pair<int,string> pp(_LG,vec[i]);//标识符temp.push_back(pp);}}else if(vec[i]=="<") {if(vec[i+1]=="=") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_LE,jk);temp.push_back(pp);continue; }else if(vec[i+1]=="<"&&vec[i+2]!="=") { string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_C,jk);temp.push_back(pp);continue;}else if(vec[i+1]=="<"&&vec[i+2]=="=") { string jk=vec[i];jk.append(vec[++i],0,1);jk.append(vec[++i],0,1);pair<int,string> pp(_D,jk);temp.push_back(pp);continue; }else {pair<int,string> pp(_LT,vec[i]);//标识符temp.push_back(pp);}}else if(vec[i]=="!") {if(vec[i+1]=="=") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_LE,jk);temp.push_back(pp);continue;}else {pair<int,string> pp(_NE,vec[i]);//标识符temp.push_back(pp);}else if(vec[i]=="=") {if(vec[i+1]=="="){string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_EQ,jk);temp.push_back(pp);continue; }else {pair<int,string> pp(_AS,vec[i]);//标识符temp.push_back(pp); }}else if(vec[i]=="&") {if(vec[i+1]=="&") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_F,jk);temp.push_back(pp);continue;}else if(vec[i+1]=="=") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_G,jk);temp.push_back(pp);continue;}else {pair<int,string> pp(_E,vec[i]);//标识符temp.push_back(pp);}}else if(vec[i]=="|"){if(vec[i+1]=="|") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_I,jk);temp.push_back(pp);continue;}else if(vec[i+1]=="="){string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_J,jk);temp.push_back(pp);continue;}else {pair<int,string> pp(_H,vec[i]);//标识符temp.push_back(pp);}}else if(vec[i]=="(") {{pair<int,string> pp(_LP,vec[i]);//标识符temp.push_back(pp);}}else if(vec[i]==")"){{pair<int,string> pp(_RP,vec[i]);//标识符temp.push_back(pp); }}else if(vec[i]=="["){{pair<int,string> pp(_LB1,vec[i]);//标识符temp.push_back(pp); } }else if(vec[i]=="]") {{pair<int,string> pp(_RB1,vec[i]);//标识符temp.push_back(pp); } }else if(vec[i]=="~") {{pair<int,string> pp(_K,vec[i]);//标识符temp.push_back(pp); } }else if(vec[i]==",") {{pair<int,string> pp(_COM,vec[i]);//标识符temp.push_back(pp); } }else if(vec[i]=="{") {{pair<int,string> pp(_LB2,vec[i]);//标识符temp.push_back(pp);} }else if(vec[i]==":") {{pair<int,string> pp(_COL,vec[i]);//标识符temp.push_back(pp); } }else if(vec[i]==";") {{pair<int,string> pp(_SEM,vec[i]);//标识符temp.push_back(pp); } }else if(vec[i]=="}") {{pair<int,string> pp(_RB2,vec[i]);//标识符temp.push_back(pp); } }else if(vec[i]=="*") {if(vec[i+1]=="="){string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_Q,jk);temp.push_back(pp);continue; }else {pair<int,string> pp(_TIMES,vec[i]);//标识符temp.push_back(pp); } }else if(vec[i]=="/") {if(vec[i+1]=="=") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_R,jk);temp.push_back(pp);continue; }else if(vec[i+1]=="*") {i=i+4;while(i<vec.size()&&(vec[i-1]!="*"||vec[i]!="/"))i++; cont inue; }else {pair<int,string> pp(_DIV,vec[i]);//标识符temp.push_back(pp); }}else if(vec[i]=="%") {if(vec[i+1]=="=") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_S,jk);temp.push_back(pp);continue; }else {pair<int,string> pp(_U,vec[i]);//标识符temp.push_back(pp); } }else if(vec[i][0]=='"') {pair<int,string> pp(_V,vec[i]);//标识符temp.push_back(pp);}else if(vec[i][0]=='\'') {pair<int,string> pp(_W,vec[i]);//标识符temp.push_back(pp);}else if(vec[i][0]=='?'){pair<int,string> pp(_X,vec[i]);//标识符temp.push_back(pp); }else if(vec[i]=="+") {if(vec[i+1]=="=") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_O,jk);temp.push_back(pp);continue; }else if(vec[i+1]=="+") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_L,jk);temp.push_back(pp);continue; }else if((vec[i-1]=="="||vec[i-1]=="(")&&isnum(vec[i+1])) {string jk=vec[i]; jk.append(vec[++i]);pair<int,string> pp(_NUM,jk);temp.push_back(pp);continue; }else{pair<int,string> pp(_PLUS,vec[i]);//标识符temp.push_back(pp); } }else if(vec[i]=="-"){if(vec[i+1]=="=") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_P,jk);temp.push_back(pp);continue;}else if(vec[i+1]=="-") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_M,jk);temp.push_back(pp);continue; }else if(vec[i+1]==">") {string jk=vec[i];jk.append(vec[++i],0,1);pair<int,string> pp(_N,jk);temp.push_back(pp);continue;} else if((vec[i-1]=="="||vec[i-1]=="(")&&isnum(vec[i+1])) { string jk=vec[i]; jk.append(vec[++i]);pair<int,string> pp(_NUM,jk);temp.push_back(pp);continue; }else {pair<int,string> pp(_SUB,vec[i]);//标识符temp.push_back(pp);}}else if(vec[i][0]<='9'&&vec[i][0]>='0'){pair<int,string> pp(_NUM,vec[i]);temp.push_back(pp);}else{pair<int,string> pp(_ID,vec[i]);//标识符temp.push_back(pp);}}else if((vec[i][0]<='9'&&vec[i][0]>='0')||vec[i][0]=='.'){if(!isnum(vec[i]))ERROR_NUM++;else if((vec[i+1][0]=='+'||vec[i+1][0]=='-')&&isnum(vec[i+2])) { string jk=vec[i];jk.append(vec[++i]);jk.append(vec[++i]);pair<int,string> pp(_NUM,jk);temp.push_back(pp);continue;}else{pair<int,string> pp(_NUM,vec[i]);temp.push_back(pp);}}else if(iskey(vec[i])){pair<int,string> pp(iskey(vec[i]),vec[i]);temp.push_back(pp);}else{pair<int,string> pp(_ID,vec[i]);temp.push_back(pp);}}return temp;}void OutFile(vector<pair<int,string> > v) {int i;for(i=0;i<v.size();i++)outfile<<"<"<<v[i].first<<" , \""<<v[i].second<<"\">"<<endl; return;}。
1.实验目的及要求设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
2.实验要求一、词法分析程序的功能:二、输入:所给文法的源程序字符串。
三、输出:二元组(syn,token或sum)构成的序列。
四、其中:syn为单词种别码;五、token为存放的单词自身字符串;六、sum为整型常数。
各种单词符号对应的种别码单词符号种别码单词符号种别码begin 1 : 17if 2 := 18then 3 > 20while 4 <> 21do 5 <= 22end 6 < 23 letter(letter| digit)* 10 >= 24 digit digit * 11 = 25 * 13 ; 26/ 14 ( 27+ 15 ) 28- 16 # 03源代码#include<stdio.h>#include<string.h>#include<iostream.h>char prog[80],token[8];char ch;int syn,p,m=0,n,row,sum=0;char *rwtab[6]={"begin","if","then","while","do","end"};void scaner(){for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++];while(ch==' '){ch=prog[p];p++;}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){m=0;while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}else if((ch>='0'&&ch<='9')){{sum=0;while((ch>='0'&&ch<='9')){sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=11;if(sum>32767)syn=-1;}else switch(ch){case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else{syn=23;p--;}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24;token[m++]=ch;}else{syn=20;p--;}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18;token[m++]=ch;}else{syn=17;p--;}break;case'*':syn=13;token[0]=ch;break; case'/':syn=14;token[0]=ch;break; case'+':syn=15;token[0]=ch;break; case'-':syn=16;token[0]=ch;break; case'=':syn=25;token[0]=ch;break; case';':syn=26;token[0]=ch;break; case'(':syn=27;token[0]=ch;break; case')':syn=28;token[0]=ch;break;case'#':syn=0;token[0]=ch;break;case'\n':syn=-2;break;default: syn=-1;break;}}void main(){p=0;row=1;cout<<"请输入字符串:"<<endl;do{cin.get(ch);prog[p++]=ch;}while(ch!='#');p=0;do{scaner();switch(syn){case 11: cout<<"("<<syn<<","<<sum<<")"<<endl; break;case -1: cout<<"Error in row "<<row<<"!"<<endl; break;case -2: row=row++;break;default: cout<<"("<<syn<<","<<token<<")"<<endl;break;}}while (syn!=0);}4 结果验证给定源程序begin x:=12; if x>0 then x:=3-4*2+3/2; end#源程序(包括上式未有的while、do以及判断错误语句):begin x<=$; while a<0 do b<..>9-x; end#5 心得体会通过此次实验,我更加深入的了解了词法构造,词法分析编制程序并调试,熟悉了构造词法分析程序的手工方式的相关原理,还有特别要注意种别码不能写错,必须一一对应,否则会很难检查出来。
《C语言词法分析器》开发文档Powered By 萌萌的玉雪一、实验题目编制并调试C词法分析程序。
二、实验目的全面深入理解高级语言程序设计知识,掌握应用技巧,提高应用与分析能力。
三、主要函数四、设计1.主函数void main ( )2. 初始化函数void load ( )3. 保留字及标识符判断函数void char_search(char *word)4. 整数类型判断函数void inta_search(char *word)5. 浮点类型判断函数void intb_search(char *word)6. 字符串常量判断函数void cc_search(char *word)7. 字符常量判断函数void c_search(char *word)同4、5函数图8.主扫描函数void scan ( )五、关键代码#include <stdio.h>#include <string.h>#include <stdlib.h>char *key0[]={" ","auto","break","case","char","const","continue","default","do","double","else","enum","extern","float","for","goto","if" ,"int","long","register","return","short","signed","sizeof","static","struct","switch","typedef","_Complex","_Imaginary"," union","unsigned","void","volatile","while"};/*保留字表*/char *key1[]={" ","(",")","[","]","{","}",",",";","'"};/*分隔符表*/char *key2[]={" ","+","-","*","/","%","<",">","==",">=","<=","!=","!","&&","||","<<",">>","~","|","^","&","=","?:","->","++","--",".","+ =","-=","*=","/="};/*运算符表*/int xx0[35],xx1[10],xx2[31];int temp_key3=0,temp_c40=0,temp_c41=0,temp_c42=0,temp_c43=0; /******* 初始化函数*******/void load(){int mm;for (mm=0;mm<=34;mm++){xx0[mm]=0;}for (mm=0;mm<=9;mm++){xx1[mm]=0;}for (mm=0;mm<=30;mm++){xx2[mm]=0;}FILE *floading;if ((floading=fopen("key0.txt","w"))==NULL){printf("Error! Can't create file : key0.txt");return;}fclose (floading);/*建立保留字表文件:key0.txt*/if ((floading=fopen("key1.txt","w"))==NULL){printf("Error! Can't create file : key1.txt");return;}/*建立分隔符表文件:key1.txt*/if ((floading=fopen("key2.txt","w"))==NULL){printf("Error! Can't create file : key2.txt");return;}fclose(floading);/*建立运算符表文件:key2.txt*/if ((floading=fopen("key3.txt","w"))==NULL){printf("Error! Can't create file : key3.txt");return;}fclose (floading);/*建立标识符表文件:key3.txt*/if ((floading=fopen("c40.txt","w"))==NULL){printf("Error! Can't create file : c40.txt");return;}fclose (floading);/*建立整数类型常量表文件:c40.txt*/if ((floading=fopen("c41.txt","w"))==NULL){printf("Error! Can't create file : c41.txt");return;}fclose (floading);/*建立浮点类型常量表文件:c41.txt*/if ((floading=fopen("c42.txt","w"))==NULL){printf("Error! Can't create file : c42.txt");return;}fclose (floading);/*建立字符类型常量表文件:c42.txt*/if ((floading=fopen("c43.txt","w"))==NULL){printf("Error! Can't create file : c43.txt");return;}fclose (floading);/*建立字符串类型常量表文件:c43.txt*/if ((floading=fopen("defination.txt","w"))==NULL) {printf("Error! Can't create file : defination.txt");return;}fclose (floading);/*建立注释文件:defination.txt*/if ((floading=fopen("output.txt","w"))==NULL) {printf("Error! Can't create file : output.txt");return;}fclose (floading);/*建立内部码文件:output.txt*/if ((floading=fopen("temp_key1","w"))==NULL) {printf("Error! Can't create file : temp_key1");return;}fclose (floading);/*建立保留字临时表文件:temp_key1*/if ((floading=fopen("temp_key3","w"))==NULL) {printf("Error! Can't create file : temp_key3");return;}fclose (floading);/*建立标识符临时文件:temp_key3*/if ((floading=fopen("temp_c40","w"))==NULL){printf("Error! Can't create file : temp_c40");return;}fclose (floading);/*建立整数类型常量临时文件:temp_c40*/if ((floading=fopen("temp_c41","w"))==NULL){printf("Error! Can't create file : temp_c41");return;}fclose (floading);/*建立浮点类型常量临时文件:temp_c41*/if ((floading=fopen("temp_c42","w"))==NULL){printf("Error! Can't create file : temp_c42");return;}fclose (floading);/*建立字符类型常量临时文件:temp_c42*/if ((floading=fopen("temp_c43","w"))==NULL){printf("Error! Can't create file : temp_c43");return;}fclose (floading);/*建立字符串类型常量临时文件:temp_c43*/ }/******* 保留字及标识符判断函数*******/void char_search(char *word){int m,line=0,csi=0;int value=0;int value2=0;char c,cs[100];FILE *foutput,*finput;for (m=1;m<=34;m++){if (strcmp(word,key0[m])==0){value=1;break;}}if (value==1){if (xx0[m]==0){foutput=fopen("key0.txt","a");fprintf(foutput,"0\t%d\t\t%s\n",m,word);fclose(foutput);xx0[m]=1;}foutput=fopen("output.txt","a");fprintf(foutput,"0\t%d\t\t%s\n",m,word);fclose(foutput);}else{if (temp_key3==0){foutput=fopen("temp_key3","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_key3++;foutput=fopen("key3.txt","a");fprintf(foutput,"3\t1\t\t%s\n",word);fclose(foutput);}finput=fopen("temp_key3","r");c=fgetc(finput);while (c!=EOF){while (c!='\n'){cs[csi++]=c;c=fgetc(finput);}cs[csi]='\0';csi=0;line++;if ((strcmp(cs,word))==0){value2=1;break;}else{value2=0;c=fgetc(finput);}}fclose(finput);if (value2==1){foutput=fopen("output.txt","a");fprintf(foutput,"3\t%d\t\t%s\n",line,word);fclose(foutput);}else{foutput=fopen("temp_key3","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_key3++;foutput=fopen("output.txt","a");fprintf(foutput,"3\t%d\t\t%s\n",temp_key3,word);fclose(foutput);foutput=fopen("key3.txt","a");fprintf(foutput,"3\t%d\t\t%s\n",temp_key3,word);fclose(foutput);}}}/******* 整数类型判断函数*******/void inta_search(char *word){FILE *foutput,*finput;char c;char cs[100];int csi=0;int line=0;int value2=0;if (temp_c40==0)foutput=fopen("temp_c40","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c40++;foutput=fopen("c40.txt","a");fprintf(foutput,"4\t0\t1\t%s\n",word);fclose(foutput);}finput=fopen("temp_c40","r");c=fgetc(finput);while (c!=EOF){while (c!='\n'){cs[csi++]=c;c=fgetc(finput);}cs[csi]='\0';csi=0;line++;if (strcmp(cs,word)==0){value2=1;break;}c=fgetc(finput);}fclose(finput);if (value2==1){foutput=fopen("output.txt","a");fprintf(foutput,"4\t0\t%d\t%s\n",line,word);fclose(foutput);}else{foutput=fopen("temp_c40","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c40++;foutput=fopen("output.txt","a");fprintf(foutput,"4\t0\t%d\t%s\n",temp_c40,word);fclose(foutput);foutput=fopen("c40.txt","a");fprintf(foutput,"4\t0\t%d\t%s\n",temp_c40,word);fclose(foutput);}/******* 浮点类型判断函数*******/void intb_search(char *word){FILE *foutput,*finput;char c;char cs[100];int csi=0;int line=0;int value2=0;if (temp_c41==0){foutput=fopen("temp_c41","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c41++;foutput=fopen("c41.txt","a");fprintf(foutput,"4\t1\t1\t%s\n",word);fclose(foutput);}finput=fopen("temp_c41","r");c=fgetc(finput);while (c!=EOF){while (c!='\n'){cs[csi++]=c;c=fgetc(finput);}cs[csi]='\0';csi=0;line++;if (strcmp(cs,word)==0){value2=1;break;}c=fgetc(finput);}fclose(finput);if (value2==1){foutput=fopen("output.txt","a");fprintf(foutput,"4\t1\t%d\t%s\n",line,word);fclose(foutput);}else{foutput=fopen("temp_c41","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c41++;foutput=fopen("output.txt","a");fprintf(foutput,"4\t1\t%d\t%s\n",temp_c41,word);fclose(foutput);foutput=fopen("c40.txt","a");fprintf(foutput,"4\t1\t%d\t%s\n",temp_c41,word);fclose(foutput);}}/******* 字符串常量判断函数*******/void cc_search(char *word){FILE *foutput,*finput;char c;char cs[100];int csi=0;int line=0;int value2=0;if (temp_c43==0){foutput=fopen("temp_c43","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c43++;foutput=fopen("c43.txt","a");fprintf(foutput,"4\t3\t1\t%s\n",word);fclose(foutput);}finput=fopen("temp_c43","r");c=fgetc(finput);while (c!=EOF){while (c!='\n'){cs[csi++]=c;c=fgetc(finput);}cs[csi]='\0';csi=0;line++;if (strcmp(cs,word)==0){value2=1;break;}c=fgetc(finput);}fclose(finput);if (value2==1){foutput=fopen("output.txt","a");fprintf(foutput,"4\t3\t%d\t%s\n",line,word);fclose(foutput);}else{foutput=fopen("temp_c43","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c43++;foutput=fopen("output.txt","a");fprintf(foutput,"4\t3\t%d\t%s\n",temp_c43,word);fclose(foutput);foutput=fopen("c43.txt","a");fprintf(foutput,"4\t3\t%d\t%s\n",temp_c43,word);fclose(foutput);}}/******* 字符常量判断函数*******/void c_search(char *word){FILE *foutput,*finput;char c;char cs[100];int csi=0;int line=0;int value2=0;if (temp_c42==0){foutput=fopen("temp_c42","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c42++;foutput=fopen("c42.txt","a");fprintf(foutput,"4\t2\t1\t%s\n",word);fclose(foutput);}finput=fopen("temp_c42","r");c=fgetc(finput);while (c!=EOF){while (c!='\n'){cs[csi++]=c;c=fgetc(finput);}cs[csi]='\0';csi=0;line++;if (strcmp(cs,word)==0){value2=1;break;}c=fgetc(finput);}fclose(finput);if (value2==1){foutput=fopen("output.txt","a");fprintf(foutput,"4\t2\t%d\t%s\n",line,word);fclose(foutput);}else{foutput=fopen("temp_c42","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c42++;foutput=fopen("output.txt","a");fprintf(foutput,"4\t2\t%d\t%s\n",temp_c42,word);fclose(foutput);foutput=fopen("c42.txt","a");fprintf(foutput,"4\t2\t%d\t%s\n",temp_c42,word);fclose(foutput);}}/******* 主扫描函数*******/void scan(){int count;char chin;FILE *fin;FILE *fout;char filename[50];char temp[100];char target[3]="'";printf("请输入文件名:");scanf("%s",filename);if ((fin=fopen(filename,"r"))==NULL){printf("Error! Can't open file : %s\n",filename);return;}chin=fgetc(fin);while (chin!=EOF){/*对文件包含、宏定义进行处理*/if (chin=='#'){while (chin!='>')chin=fgetc(fin);/*chin=fgetc(fin);*/}/*对空格符、水平制表符进行处理*/else if ((chin==' ')||(chin=='\t')){;}/*对回车符进行处理*/else if (chin=='\n'){;}/*对单引号内的字符常量进行处理*/else if (chin==target[0]){if (xx1[9]==0){fout=fopen("key1.txt","a");fprintf(fout,"1\t9\t\t%c\n",target[0]);fclose(fout);xx1[9]=1;}temp[0]=chin;chin=fgetc(fin);temp[1]=chin;chin=fgetc(fin);if (chin!=target[0]){temp[2]=chin;chin=fgetc(fin);temp[3]=chin;temp[4]='\0';}else{temp[2]=chin;temp[3]='\0';}c_search(temp);}/*对双引号内的字符串常量进行处理*/else if (chin=='"'){int i=0;temp[i++]='"';chin=fgetc(fin);while (chin!='"'){temp[i++]=chin;chin=fgetc(fin);}temp[i]='"';temp[i+1]='\0';cc_search(temp);}/*对保留字、标识符进行处理*/else if (((chin>='A')&&(chin<='Z'))||((chin>='a')&&(chin<='z'))||(chin=='_')){int i=0;while(((chin>='A')&&(chin<='Z'))||((chin>='a')&&(chin<='z'))||(chin=='_')||((chin>='0')&&(chin<='9'))) {temp[i++]=chin;chin=fgetc(fin);}temp[i]='\0';char_search(temp);if (chin!=EOF)fseek (fin,-1L,SEEK_CUR);}/*对整型、浮点型数据进行处理*/else if ((chin>='0')&&(chin<='9')){int dotcount=0;int i=0;while (((chin>='0')&&(chin<='9'))||(chin=='.')) {if (chin=='.')dotcount++;if (dotcount==2)break;temp[i++]=chin;chin=fgetc(fin);}temp[i]='\0';if (dotcount==1)intb_search(temp);elseinta_search(temp);if (chin!=EOF)fseek (fin,-1L,SEEK_CUR);}/*对注释进行处理*/else if (chin=='/'){chin=fgetc(fin);if (chin=='='){fout=fopen("output.txt","a");fprintf(fout,"2\t30\t\t/=\n");fclose(fout);}else if (chin!='*'){fout=fopen("output.txt","a");fprintf(fout,"2\t4\t\t/\n");fclose(fout);fseek(fin,-1L,SEEK_CUR);}else if (chin=='*'){count=0;chin=fgetc(fin);fout=fopen("defination.txt","a");fprintf(fout,"/*");while (count!=2){count=0;while (chin!='*'){fprintf(fout,"%c",chin);chin=fgetc(fin);}count++;fprintf(fout,"%c",chin);chin=fgetc(fin);if (chin=='/'){count++;fprintf(fout,"%c\n",chin);}else{fprintf(fout,"%c",chin);chin=fgetc(fin);}}}}/*对运算符、分隔符进行处理*/else{int time=0;int firstblood=0;temp[0]=chin;chin=fgetc(fin);if (chin!=EOF){temp[1]=chin;temp[2]='\0';for (time=1;time<=30;time++){if (strcmp(temp,key2[time])==0){firstblood=1;if (xx2[time]==0){fout=fopen("key2.txt","a");fprintf(fout,"2\t%d\t\t%s\n",time,temp);fclose(fout);xx2[time]=1;}fout=fopen("output.txt","a");fprintf(fout,"2\t%d\t\t%s\n",time,temp);fclose(fout);break;}}if (firstblood!=1){fseek(fin,-1L,SEEK_CUR);temp[1]='\0';for (time=1;time<=9;time++){if (strcmp(temp,key1[time])==0){if (xx1[time]==0){fout=fopen("key1.txt","a");fprintf(fout,"1\t%d\t\t%s\n",time,temp);fclose(fout);xx1[time]=1;}fout=fopen("output.txt","a");fprintf(fout,"1\t%d\t\t%s\n",time,temp);fclose(fout);break;}}for (time=1;time<=30;time++){if (strcmp(temp,key2[time])==0){if (xx2[time]==0){fout=fopen("key2.txt","a");fprintf(fout,"2\t%d\t\t%s\n",time,temp);fclose(fout);xx2[time]=1;}fout=fopen("output.txt","a");fprintf(fout,"2\t%d\t\t%s\n",time,temp);fclose(fout);break;}}}}}chin=fgetc(fin);}fout=fopen("output.txt","a");fprintf(fout,"1\t6\t\t}\n");fclose(fout);}/******* Main函数*******/void main(){FILE *fread;char charin;char command='Q';printf("\n");printf("******************** C语言词法分析工具********************\n");printf("* *\n");printf("* *\n");printf("* 命令如下:*\n");printf("* 0 --> 查看保留字表文件*\n");printf("* 1 --> 查看分隔符表文件*\n");printf("* 2 --> 查看运算符表文件*\n");printf("* 3 --> 查看标识符表文件*\n");printf("* 4 --> 查看整数类型常量表*\n");printf("* 5 --> 查看浮点类型常量表*\n");printf("* 6 --> 查看字符类型常量表*\n");printf("* 7 --> 查看字符串类型常量表*\n");printf("* 8 --> 查看注释文件*\n");printf("* 9 --> 查看内部码文件*\n");printf("* -------------------------- *\n");printf("* Q --> 退出*\n");printf("***************************************************************\n");printf("\n");load();scan();printf("\n");printf("分析完成!\n");getchar();printf("\n");printf("请输入命令:");command=getchar();while ((command!='Q')&&(command!='q')){switch (command){case '0':{printf("*************************\n");printf("\n");fread=fopen("key0.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '1':{printf("*************************\n");printf("\n");fread=fopen("key1.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '2':{printf("*************************\n");printf("\n");fread=fopen("key2.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '3':{printf("*************************\n");printf("\n");fread=fopen("key3.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '4':{printf("*************************\n");printf("\n");fread=fopen("c40.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '5':{printf("*************************\n");printf("\n");fread=fopen("c41.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");21printf("请输入命令:");break;}case '6':{printf("*************************\n");printf("\n");fread=fopen("c42.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '7':{printf("*************************\n");printf("\n");fread=fopen("c43.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '8':{printf("*************************\n");printf("\n");fread=fopen("defination.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);22}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '9':{printf("*************************\n");printf("\n");fread=fopen("output.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}}command=getchar();}}23。
词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。
二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。
(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。
空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。
2.2 各种单词符号对应的种别码:表2.1 各种单词符号对应的种别码单词符号种别码单词符号种别码bgin 1 :17If 2 := 18Then 3 < 20wile 4 <> 21do 5 <= 22end 6 > 23lettet(letter|digit)* 10 >= 24 dight dight* 11 = 25 + 13 ;26—14 ( 27* 15 ) 28/ 16 # 02.3 词法分析程序的功能:输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。
其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。
例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
3.1 主程序示意图:主程序示意图如图3-1所示。
#include <stdio.h>#include <string.h>#include <stdlib.h>char *key0[]={" ","auto","break","case","char","const","continue","default","do","double","else" ,"enum","extern","float","for","goto","if","int","long","register","return","sho rt","signed","sizeof","static","struct","switch","typedef","_Complex","_Imaginar y","union","unsigned","void","volatile","while"};/*保留字表*/char *key1[]={" ","(",")","[","]","{","}",",",";","'"};/*分隔符表*/char *key2[]={" ","+","-","*","/","%","<",">","==",">=","<=","!=","!","&&","||","<<",">>","~","| ","^","&","=","?:","->","++","--",".","+=","-=","*=","/="};/*运算符表*/int xx0[35],xx1[10],xx2[31];int temp_key3=0,temp_c40=0,temp_c41=0,temp_c42=0,temp_c43=0;/******* 初始化函数 *******/void load(){int mm;for (mm=0;mm<=34;mm++){xx0[mm]=0;}for (mm=0;mm<=9;mm++){xx1[mm]=0;}for (mm=0;mm<=30;mm++){xx2[mm]=0;}FILE *floading;if ((floading=fopen("key0.txt","w"))==NULL){printf("Error! Can't create file : key0.txt");return;}fclose (floading);/*建立保留字表文件:key0.txt*/if ((floading=fopen("key1.txt","w"))==NULL){printf("Error! Can't create file : key1.txt");return;}/*建立分隔符表文件:key1.txt*/if ((floading=fopen("key2.txt","w"))==NULL){printf("Error! Can't create file : key2.txt");return;}fclose(floading);/*建立运算符表文件:key2.txt*/if ((floading=fopen("key3.txt","w"))==NULL){printf("Error! Can't create file : key3.txt");return;}fclose (floading);/*建立标识符表文件:key3.txt*/if ((floading=fopen("c40.txt","w"))==NULL){printf("Error! Can't create file : c40.txt");return;}fclose (floading);/*建立整数类型常量表文件:c40.txt*/if ((floading=fopen("c41.txt","w"))==NULL){printf("Error! Can't create file : c41.txt");return;}fclose (floading);/*建立浮点类型常量表文件:c41.txt*/if ((floading=fopen("c42.txt","w"))==NULL){printf("Error! Can't create file : c42.txt");return;}fclose (floading);/*建立字符类型常量表文件:c42.txt*/if ((floading=fopen("c43.txt","w"))==NULL){printf("Error! Can't create file : c43.txt");return;}fclose (floading);/*建立字符串类型常量表文件:c43.txt*/if ((floading=fopen("defination.txt","w"))==NULL) {printf("Error! Can't create file : defination.txt");return;}fclose (floading);/*建立注释文件:defination.txt*/if ((floading=fopen("output.txt","w"))==NULL){printf("Error! Can't create file : output.txt");return;}fclose (floading);/*建立内部码文件:output.txt*/if ((floading=fopen("temp_key1","w"))==NULL){printf("Error! Can't create file : temp_key1");return;}fclose (floading);/*建立保留字临时表文件:temp_key1*/if ((floading=fopen("temp_key3","w"))==NULL){printf("Error! Can't create file : temp_key3");return;}fclose (floading);/*建立标识符临时文件:temp_key3*/if ((floading=fopen("temp_c40","w"))==NULL){printf("Error! Can't create file : temp_c40");return;}fclose (floading);/*建立整数类型常量临时文件:temp_c40*/if ((floading=fopen("temp_c41","w"))==NULL){printf("Error! Can't create file : temp_c41");return;}fclose (floading);/*建立浮点类型常量临时文件:temp_c41*/if ((floading=fopen("temp_c42","w"))==NULL){printf("Error! Can't create file : temp_c42");return;}fclose (floading);/*建立字符类型常量临时文件:temp_c42*/if ((floading=fopen("temp_c43","w"))==NULL){printf("Error! Can't create file : temp_c43");return;}fclose (floading);/*建立字符串类型常量临时文件:temp_c43*/}/******* 保留字及标识符判断函数 *******/void char_search(char *word){int m,line=0,csi=0;int value=0;int value2=0;char c,cs[100];FILE *foutput,*finput;for (m=1;m<=34;m++){if (strcmp(word,key0[m])==0){value=1;break;}}if (value==1){if (xx0[m]==0){foutput=fopen("key0.txt","a");fprintf(foutput,"0\t%d\t\t%s\n",m,word);fclose(foutput);xx0[m]=1;}foutput=fopen("output.txt","a");fprintf(foutput,"0\t%d\t\t%s\n",m,word);fclose(foutput);}else{if (temp_key3==0){foutput=fopen("temp_key3","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_key3++;foutput=fopen("key3.txt","a");fprintf(foutput,"3\t1\t\t%s\n",word);fclose(foutput);}finput=fopen("temp_key3","r");c=fgetc(finput);while (c!=EOF){while (c!='\n'){cs[csi++]=c;c=fgetc(finput);}cs[csi]='\0';csi=0;line++;if ((strcmp(cs,word))==0){value2=1;break;}else{value2=0;c=fgetc(finput);}}fclose(finput);if (value2==1){foutput=fopen("output.txt","a");fprintf(foutput,"3\t%d\t\t%s\n",line,word);fclose(foutput);}else{foutput=fopen("temp_key3","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_key3++;foutput=fopen("output.txt","a");fprintf(foutput,"3\t%d\t\t%s\n",temp_key3,word);fclose(foutput);foutput=fopen("key3.txt","a");fprintf(foutput,"3\t%d\t\t%s\n",temp_key3,word);fclose(foutput);}}}/******* 整数类型判断函数 *******/void inta_search(char *word){FILE *foutput,*finput;char c;char cs[100];int csi=0;int line=0;int value2=0;if (temp_c40==0){foutput=fopen("temp_c40","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c40++;foutput=fopen("c40.txt","a");fprintf(foutput,"4\t0\t1\t%s\n",word);fclose(foutput);}finput=fopen("temp_c40","r");c=fgetc(finput);while (c!=EOF){while (c!='\n'){cs[csi++]=c;c=fgetc(finput);}cs[csi]='\0';csi=0;line++;if (strcmp(cs,word)==0){value2=1;break;}c=fgetc(finput);}fclose(finput);if (value2==1){foutput=fopen("output.txt","a");fprintf(foutput,"4\t0\t%d\t%s\n",line,word);fclose(foutput);}else{foutput=fopen("temp_c40","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c40++;foutput=fopen("output.txt","a");fprintf(foutput,"4\t0\t%d\t%s\n",temp_c40,word);fclose(foutput);foutput=fopen("c40.txt","a");fprintf(foutput,"4\t0\t%d\t%s\n",temp_c40,word);fclose(foutput);}}/******* 浮点类型判断函数 *******/void intb_search(char *word){FILE *foutput,*finput;char c;char cs[100];int csi=0;int line=0;int value2=0;if (temp_c41==0){foutput=fopen("temp_c41","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c41++;foutput=fopen("c41.txt","a");fprintf(foutput,"4\t1\t1\t%s\n",word);fclose(foutput);}finput=fopen("temp_c41","r");c=fgetc(finput);while (c!=EOF){while (c!='\n'){cs[csi++]=c;c=fgetc(finput);}cs[csi]='\0';csi=0;line++;if (strcmp(cs,word)==0){value2=1;break;}c=fgetc(finput);}fclose(finput);if (value2==1){foutput=fopen("output.txt","a");fprintf(foutput,"4\t1\t%d\t%s\n",line,word);fclose(foutput);}else{foutput=fopen("temp_c41","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c41++;foutput=fopen("output.txt","a");fprintf(foutput,"4\t1\t%d\t%s\n",temp_c41,word);fclose(foutput);foutput=fopen("c40.txt","a");fprintf(foutput,"4\t1\t%d\t%s\n",temp_c41,word);fclose(foutput);}}/******* 字符串常量判断函数 *******/void cc_search(char *word){FILE *foutput,*finput;char c;char cs[100];int csi=0;int line=0;int value2=0;if (temp_c43==0){foutput=fopen("temp_c43","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c43++;foutput=fopen("c43.txt","a");fprintf(foutput,"4\t3\t1\t%s\n",word);fclose(foutput);}finput=fopen("temp_c43","r");c=fgetc(finput);while (c!=EOF){while (c!='\n'){cs[csi++]=c;c=fgetc(finput);}cs[csi]='\0';csi=0;line++;if (strcmp(cs,word)==0){value2=1;break;}c=fgetc(finput);}fclose(finput);if (value2==1){foutput=fopen("output.txt","a");fprintf(foutput,"4\t3\t%d\t%s\n",line,word);fclose(foutput);}else{foutput=fopen("temp_c43","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c43++;foutput=fopen("output.txt","a");fprintf(foutput,"4\t3\t%d\t%s\n",temp_c43,word);fclose(foutput);foutput=fopen("c43.txt","a");fprintf(foutput,"4\t3\t%d\t%s\n",temp_c43,word);fclose(foutput);}}/******* 字符常量判断函数 *******/void c_search(char *word){FILE *foutput,*finput;char c;char cs[100];int csi=0;int line=0;int value2=0;if (temp_c42==0){foutput=fopen("temp_c42","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c42++;foutput=fopen("c42.txt","a");fprintf(foutput,"4\t2\t1\t%s\n",word);fclose(foutput);}finput=fopen("temp_c42","r");c=fgetc(finput);while (c!=EOF){while (c!='\n'){cs[csi++]=c;c=fgetc(finput);}cs[csi]='\0';csi=0;line++;if (strcmp(cs,word)==0){value2=1;break;}c=fgetc(finput);}fclose(finput);if (value2==1){foutput=fopen("output.txt","a");fprintf(foutput,"4\t2\t%d\t%s\n",line,word);fclose(foutput);}else{foutput=fopen("temp_c42","a");fprintf(foutput,"%s\n",word);fclose(foutput);temp_c42++;foutput=fopen("output.txt","a");fprintf(foutput,"4\t2\t%d\t%s\n",temp_c42,word);fclose(foutput);foutput=fopen("c42.txt","a");fprintf(foutput,"4\t2\t%d\t%s\n",temp_c42,word);fclose(foutput);}}/******* 主扫描函数 *******/void scan(){int count;char chin;FILE *fin;FILE *fout;char filename[50];char temp[100];char target[3]="'";printf("请输入文件名:");scanf("%s",filename);if ((fin=fopen(filename,"r"))==NULL){printf("Error! Can't open file : %s\n",filename);return;}chin=fgetc(fin);while (chin!=EOF){/*对文件包含、宏定义进行处理*/if (chin=='#'){while (chin!='>')chin=fgetc(fin);/*chin=fgetc(fin);*/}/*对空格符、水平制表符进行处理*/else if ((chin==' ')||(chin=='\t')){;}/*对回车符进行处理*/else if (chin=='\n'){;}/*对单引号内的字符常量进行处理*/else if (chin==target[0]){if (xx1[9]==0){fout=fopen("key1.txt","a");fprintf(fout,"1\t9\t\t%c\n",target[0]);fclose(fout);xx1[9]=1;}temp[0]=chin;chin=fgetc(fin);temp[1]=chin;chin=fgetc(fin);if (chin!=target[0]){temp[2]=chin;chin=fgetc(fin);temp[3]=chin;temp[4]='\0';}else{temp[2]=chin;temp[3]='\0';}c_search(temp);}/*对双引号内的字符串常量进行处理*/else if (chin=='"'){int i=0;temp[i++]='"';chin=fgetc(fin);while (chin!='"'){temp[i++]=chin;chin=fgetc(fin);}temp[i]='"';temp[i+1]='\0';cc_search(temp);}/*对保留字、标识符进行处理*/else if (((chin>='A')&&(chin<='Z'))||((chin>='a')&&(chin<='z'))||(chin=='_')) {int i=0;while(((chin>='A')&&(chin<='Z'))||((chin>='a')&&(chin<='z'))||(chin=='_')||((chin>='0 ')&&(chin<='9'))){temp[i++]=chin;chin=fgetc(fin);}temp[i]='\0';char_search(temp);if (chin!=EOF)fseek (fin,-1L,SEEK_CUR);}/*对整型、浮点型数据进行处理*/else if ((chin>='0')&&(chin<='9')){int dotcount=0;int i=0;while (((chin>='0')&&(chin<='9'))||(chin=='.')) {if (chin=='.')dotcount++;if (dotcount==2)break;temp[i++]=chin;chin=fgetc(fin);}temp[i]='\0';if (dotcount==1)intb_search(temp);elseinta_search(temp);if (chin!=EOF)fseek (fin,-1L,SEEK_CUR);}/*对注释进行处理*/else if (chin=='/'){chin=fgetc(fin);if (chin=='='){fout=fopen("output.txt","a");fprintf(fout,"2\t30\t\t/=\n");fclose(fout);}else if (chin!='*'){fout=fopen("output.txt","a");fprintf(fout,"2\t4\t\t/\n");fclose(fout);fseek(fin,-1L,SEEK_CUR);}else if (chin=='*'){count=0;chin=fgetc(fin);fout=fopen("defination.txt","a");fprintf(fout,"/*");while (count!=2){count=0;while (chin!='*'){fprintf(fout,"%c",chin);chin=fgetc(fin);}count++;fprintf(fout,"%c",chin);chin=fgetc(fin);if (chin=='/'){count++;fprintf(fout,"%c\n",chin);}else{fprintf(fout,"%c",chin);chin=fgetc(fin);}}}}/*对运算符、分隔符进行处理*/else{int time=0;int firstblood=0;temp[0]=chin;chin=fgetc(fin);if (chin!=EOF){temp[1]=chin;temp[2]='\0';for (time=1;time<=30;time++){if (strcmp(temp,key2[time])==0){firstblood=1;if (xx2[time]==0){fout=fopen("key2.txt","a");fprintf(fout,"2\t%d\t\t%s\n",time,temp);fclose(fout);xx2[time]=1;}fout=fopen("output.txt","a");fprintf(fout,"2\t%d\t\t%s\n",time,temp);fclose(fout);break;}}if (firstblood!=1){fseek(fin,-1L,SEEK_CUR);temp[1]='\0';for (time=1;time<=9;time++){if (strcmp(temp,key1[time])==0){if (xx1[time]==0){fout=fopen("key1.txt","a");fprintf(fout,"1\t%d\t\t%s\n",time,temp);fclose(fout);xx1[time]=1;}fout=fopen("output.txt","a");fprintf(fout,"1\t%d\t\t%s\n",time,temp);fclose(fout);break;}}for (time=1;time<=30;time++){if (strcmp(temp,key2[time])==0){if (xx2[time]==0){fout=fopen("key2.txt","a");fprintf(fout,"2\t%d\t\t%s\n",time,temp);fclose(fout);xx2[time]=1;}fout=fopen("output.txt","a");fprintf(fout,"2\t%d\t\t%s\n",time,temp);fclose(fout);break;}}}}}chin=fgetc(fin);}fout=fopen("output.txt","a");fprintf(fout,"1\t6\t\t}\n");fclose(fout);}/******* Main函数 *******/void main(){FILE *fread;char charin;char command='Q';printf("\n");printf("******************** C语言词法分析工具********************\n");printf("* *\n");printf("* *\n");printf("* 命令如下: *\n");printf("* 0 --> 查看保留字表文件 *\n");printf("* 1 --> 查看分隔符表文件 *\n");printf("* 2 --> 查看运算符表文件 *\n");printf("* 3 --> 查看标识符表文件 *\n");printf("* 4 --> 查看整数类型常量表 *\n");printf("* 5 --> 查看浮点类型常量表 *\n");printf("* 6 --> 查看字符类型常量表 *\n");printf("* 7 --> 查看字符串类型常量表 *\n");printf("* 8 --> 查看注释文件 *\n");printf("* 9 --> 查看内部码文件 *\n"); printf("* -------------------------- *\n"); printf("* Q --> 退出 *\n"); printf("***************************************************************\n"); printf("\n");load();scan();printf("\n");printf("分析完成!\n");getchar();printf("\n");printf("请输入命令:");command=getchar();while ((command!='Q')&&(command!='q')){switch (command){case '0':{printf("*************************\n");printf("\n");fread=fopen("key0.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '1':{printf("*************************\n");printf("\n");fread=fopen("key1.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '2':{printf("*************************\n");printf("\n");fread=fopen("key2.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '3':{printf("*************************\n");printf("\n");fread=fopen("key3.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '4':{printf("*************************\n");printf("\n");fread=fopen("c40.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '5':{printf("*************************\n");printf("\n");fread=fopen("c41.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '6':{printf("*************************\n");printf("\n");fread=fopen("c42.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '7':{printf("*************************\n");printf("\n");fread=fopen("c43.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '8':{printf("*************************\n");printf("\n");fread=fopen("defination.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}case '9':{printf("*************************\n");printf("\n");fread=fopen("output.txt","r");charin=fgetc(fread);while (charin!=EOF){putchar(charin);charin=fgetc(fread);}printf("\n");printf("*************************\n");printf("\n");printf("请输入命令:");break;}}command=getchar();}}。