C语言词法分析器_源代码_风君版
- 格式:doc
- 大小:72.00 KB
- 文档页数: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各种单词符号对应的种别码单词符号种别码单词符号种别码bgin1:17If2: =18Then3<20wile4<>21do5<=22end6>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<stdlib.h>#include "ctype.h"#include "string.h"/**************************************判断字符区域*开始********************************************/int characters_exist=0; /*用来判断是否是纯数字*/int countoffinal=0; /*finalresult函数执行的次数*/int word( char ch) /*判断是否为字母*/{int ch_exist=0;if(isalpha(ch)){ch_exist=1;characters_exist=1;}return(ch_exist);}int digit(char ch) /*判断是否为数字*/{int dig_exist=0;if(isdigit(ch))dig_exist=1;return (dig_exist);}int delimiter(char ch) /*判断是否是分界符*/{int del_exist=0;int i;char delimiters[14]={'+','-','*','/',';','(',')','{','}','<','>','!','=',' '};for(i=0;i<14;i++){if(ch==delimiters[i]){del_exist=1;break;}}return(del_exist);}int keywordcompare(char key[],char keyword[]) /*比较关键字*/ {int m=0;int equal=1;while(keyword[m]!='#'){if(key[m]==keyword[m]) m++;else{equal=0;break;}}return(equal);}int keyword(char key[]) /*判断是否是关键字*/{char ifkeyword[3]={'i','f','#'};char elsekeyword[5]={'e','l','s','e','#'};char thenkeyword[5]={'t','h','e','n','#'};char forkeyword[4]={'f','o','r','#'};char whilekeyword[6]={'w','h','i','l','e','#'};char dokeyword[3]={'d','o','#'};char andkeyword[4]={'a','n','d','#'};char notkeyword[4]={'n','o','t','#'};char orkeyword[3]={'o','r','#'};int keyword_exist=0;if(keywordcompare(key,ifkeyword)||keywordcompare(key,elsekeyword)||keywordcompare(key,then keyword)||keywordcompare(key,forkeyword)||keywordcompare(key,whilekeyword)||keywordcom pare(key,dokeyword)||keywordcompare(key,andkeyword)||keywordcompare(key,notkeyword)||key wordcompare(key,orkeyword))keyword_exist=1;return(keyword_exist);}/**************************************判断字符区域*结束********************************************//**************************************写入文件区域*开始********************************************/void writetofile(char cha[]) /*将数组cha[]写入文件Dualistic_formula*/{int i=0;int numberofspace=0; /*用来实现写入文件时跳过过多的空格*/FILE * fpa;if((fpa=fopen("Dualistic_formula","a"))==NULL){printf("cannot open file Dualistic_formula\n");exit(0);}while(cha[i]!='#'&&numberofspace<=1) /*数组不结束且连续空格数最多为2时满足循环条件*/{if(cha[i]==' ') numberofspace++;elsenumberofspace=0;fputc(cha[i],fpa);i++;}fclose(fpa);}void keywordtofile(char cha[]) /*将关键字写入文件keyword*/{int i=0;int numberofspace=0; /*用来实现写入文件时跳过过多的空格*/FILE * fpa;if((fpa=fopen("keyword","a"))==NULL)printf("cannot open file keyword\n");exit(0);}while(cha[i]!='#'&&numberofspace<=1) /*数组不结束且连续空格数最多为2时满足循环条件*/{if(cha[i]==' ') numberofspace++;elsenumberofspace=0;fputc(cha[i],fpa);i++;}fclose(fpa);}void wordstofile(char cha[]) /*将标识符写入文件words*/{int i=0;int numberofspace=0; /*用来实现写入文件时跳过过多的空格*/FILE * fpa;if((fpa=fopen("words","a"))==NULL){printf("cannot open file words\n");exit(0);}while(cha[i]!='#'&&numberofspace<=1) /*数组不结束且连续空格数最多为2时满足循环条件*/{if(cha[i]==' ') numberofspace++;elsenumberofspace=0;fputc(cha[i],fpa);i++;}fclose(fpa);}void digittofile(char cha[]) /*将数字写入文件{int i=0;int numberofspace=0; /*用来实现写入文件时跳过过多的空格*/FILE * fpa;if((fpa=fopen("digit","a"))==NULL){printf("cannot open file digit\n");exit(0);}while(cha[i]!='#'&&numberofspace<=1) /*数组不结束且连续空格数最多为2时满足循环条件*/{if(cha[i]==' ') numberofspace++;elsenumberofspace=0;fputc(cha[i],fpa);i++;}fclose(fpa);}void singletofile(char cha[]) /*将单分界符写入文件single*/{int i=0;int numberofspace=0; /*用来实现写入文件时跳过过多的空格*/FILE * fpa;if((fpa=fopen("single","a"))==NULL){printf("cannot open file single\n");exit(0);}while(cha[i]!='#'&&numberofspace<=1) /*数组不结束且连续空格数最多为2时满足循环条件*/{if(cha[i]==' ') numberofspace++;elsenumberofspace=0;fputc(cha[i],fpa);}fclose(fpa);}void doubletofile(char cha[]) /*将双分界符写入文件double*/{int i=0;int numberofspace=0; /*用来实现写入文件时跳过过多的空格*/FILE * fpa;if((fpa=fopen("double","a"))==NULL){printf("cannot open file double\n");exit(0);}while(cha[i]!='#'&&numberofspace<=1) /*数组不结束且连续空格数最多为2时满足循环条件*/{if(cha[i]==' ') numberofspace++;elsenumberofspace=0;fputc(cha[i],fpa);i++;}fclose(fpa);}void errortofile(char cha[]) /*将非法字符写入文件error*/{int i=0;FILE * fpa;if((fpa=fopen("error","a"))==NULL){printf("cannot open file error\n");exit(0);}while(cha[i]!='#'){fputc(cha[i],fpa);}fclose(fpa);}/**************************************写入文件区域*结束********************************************//************************************显示及数组处理区域*结束*****************************************/void displayw(char ch,char cha[]) /*立即显示遇到的字符*/{if(ch=='y'||ch=='Y'){int i=0;while(cha[i]!='#'){printf("%c",cha[i]);i++;}printf("\n");}}void finalresult(int df,char filen[],FILE *fpp,FILE *fpt) /*显示统计信息并将二元式写入文件Dualistic_formula*/{int i,j,k,n,mj,equ,spa;char cha=' ';char Dua_form[]="\n\n\n\n二元式:\n ";char resultofsat[]="统计结果:\n ";char memory[50][15];char temp[15];countoffinal++;for(j=0;j<50;j++)for(i=0;i<15;i++){memory[j][i]=' ';temp[i]=' ';}i=0;j=0;k=0;n=0;mj=0,spa=0;rewind(fpp);while(!feof(fpp)){cha=fgetc(fpp);equ=0;if(cha!=' '&&cha!=EOF){temp[i]=cha;i++;spa=0;}elseif(i==0&&spa!=1){cha=fgetc(fpp);if(cha!=EOF){temp[i]=cha;i++;}elsebreak;}else{if((cha==' '||cha==EOF)&&spa!=1){spa=1;for(j=0;j<50;j++){if(n==i&&memory[j-1][i+1]==' '){equ=1;break;}if(memory[j][0]==' ') break;n=0;for(k=0;k<i;k++)if(temp[k]==memory[j][k]&&temp[k]!=' ')n++;}n=0;if(equ!=1){for(k=0;k<i;k++){memory[mj][k]=temp[k];}mj++;}}for(i=0;i<15;i++)temp[i]=' ';i=0;}}if(df==0){if(countoffinal==1)writetofile(resultofsat);writetofile(filen);for(j=0;j<50;j++){if(memory[j][0]==' ') break;for(i=0;i<15;i++){if(i==0||memory[j][i]!=' ')putchar(memory[j][i]);}printf(" ");}for(j=0;j<50;j++){if(memory[j][0]==' ') break;writetofile(memory[j]);}}if(df>0){if(countoffinal==0||countoffinal==7)writetofile(Dua_form);for(j=0;j<50;j++){if(memory[j][0]==' ') break;writetofile(filen);writetofile(memory[j]);}}}void cleararray(int n,char cha[]) /*清空数组*/{int i;for(i=0;i<n;i++)cha[i]=' ';}/************************************显示及数组处理区域*结束*****************************************//**************************************主函数区域**开始********************************************/void main(){/**/FILE *fpw;FILE *fpr;FILE *fpkey;FILE *fpwords;FILE *fpdigit;FILE *fpsinglew;FILE *fpdoublew;FILE *fperrorw;/*相关数组*/char words[21]={' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#'};char number[16]={' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','#'};char singleword[3]={' ',' ','#'};char doubleword[4]={' ',' ',' ','#'};char error[3]={' ',' ','#'};char filen1[]={10,13,'K','e','y','W','o','r','d','-','>',':','#'};char filen2[]={10,13,'W','o','r','d','-','>',':','#'};char filen3[]={10,13,'D','i','g','i','t','-','>',':','#'};char filen4[]={10,13,'S','i','n','g','l','e','W','o','r','d','-','>',':','#'};char filen5[]={10,13,'D','o','u','b','l','e','W','o','r','d','-','>',':','#'};char filen6[]={10,13,'E','R','R','O','R','-','>',':','#'};/*相关变量*/char ch; /*接受从文件中读出的单个字符*/int unknown=0; /*判断是否出现无法识别的字符*/int numofword=0; /*字母数组中的字母个数*/int numofdigit=0; /*数字数组中的数字个数*/int numofsingle=0; /*连续出现的单分界符个数*/int catchdoubleword=0; /*是否出现双分界符*/int enddelimit=10; /*末尾是否存在分界符*/int numofspace=0; /*限制遇到过多的空格*/char yorn=' '; /*是否单独显示结果,接受输入的Y或N*/char totalyorn=' '; /*是否统计显示结果,接受输入的Y或N*/fpw=fopen("Dualistic_formula","w"); /*存放二元式的文件Dualistic_formula*/fpkey=fopen("keyword","w+");fpwords=fopen("words","w+");fpdigit=fopen("digit","w+");fpsinglew=fopen("single","w+");fpdoublew=fopen("double","w+");fperrorw=fopen("error","w+");if((fpr=fopen("sourcecode.txt","r"))==NULL) /*打开存放待分析程序的文件sourcecode*/{printf("cannot open file\n");exit(0);}printf("Print legal characters immediately when this program is reading them(Y/N).\n");printf("If you entered a wrong word carelessly, you should carry on.\n");printf("是否在程序读到合法字符时立即显示它们?(Y/N):");scanf("%c",&yorn);if(yorn!='y'&&yorn!='Y'&&yorn!='n'&&yorn!='N') printf("如果不小心输入出错,请继续输入:");while(yorn!='y'&&yorn!='Y'&&yorn!='n'&&yorn!='N')scanf("%c",&yorn);while(!feof(fpr)) /*逐个读字符*/ {ch=fgetc(fpr);if(word(ch)||digit(ch)) /*遇到字母或数字*/{if(numofsingle==1&&catchdoubleword!=1) /*写入单分界符*/{singletofile(singleword); /*写入单分界符到文件single*/if(yorn=='y'||yorn=='Y')printf("SingleWord:");displayw(yorn,singleword); /*遇到合法字符则立即显示*/}words[numofword]=ch;numofword++;enddelimit=0;if(digit(ch)) /*遇到数字*/{number[numofdigit]=ch;numofdigit++;enddelimit=1;}cleararray(2,singleword); /*遇到标识符后,清空暂存分界符的数组*/cleararray(3,doubleword);numofsingle=0;catchdoubleword=0;}elseif(delimiter(ch)) /*遇到分界符*/{enddelimit=2;/*enddualist=2表示存在分界符*/if(ch==' ') numofspace+=1; /*记录连续出现的空格数量*/elsenumofspace=0;if(unknown==0) /*判断标识符是否与无法识别的字符混杂一起*/{if(characters_exist==0&&number[0]!=' '){digittofile(number); /*写入数字到文件digit*/if(yorn=='y'||yorn=='Y')printf("Digit:");displayw(yorn,number); /*遇到合法字符则立即显示*/}elseif(word(words[0])){if(keyword(words)){keywordtofile(words); /*写入关键字到文件keyword*/if(yorn=='y'||yorn=='Y')printf("KeyWord:");displayw(yorn,words); /*遇到合法字符则立即显示*/}else{wordstofile(words); /*写入普通字符到文件words*/if(yorn=='y'||yorn=='Y')printf("Word:");displayw(yorn,words); /*遇到合法字符则立即显示*/}}}cleararray(20,words); /*遇到分界符后,清空暂存其它字符的数组*/cleararray(15,number);numofword=0; /*遇到分界符后,其它类型的字符个数复位0*/numofdigit=0;characters_exist=0;unknown=0;if(numofspace<=1) /*遇到连续空格时,只处理第一个,其它跳过*/{singleword[numofsingle]=ch; /*暂时存放单分界符*/doubleword[numofsingle]=ch;numofsingle++;if(numofsingle==2){if((doubleword[0]=='>'||doubleword[0]=='<'||doubleword[0]=='!'||doubleword[0]=='=')&&double word[1]=='=') /*判断是否满足双分界符*/{doubletofile(doubleword);if(yorn=='y'||yorn=='Y')printf("DoubleWord:");displayw(yorn,doubleword);doubleword[0]=doubleword[1];numofsingle=1; /*仍然需要判断两者中的后一个是否在将来可以满足双分界符*/catchdoubleword=1; /*成功分析到一个双分界符*/}elseif(catchdoubleword!=1) /*当前字符的前两个字符不满足双分界符*/{char singlesecond=singleword[1];singleword[1]=' ';singletofile(singleword); /*写入单分界符到文件single*/if(yorn=='y'||yorn=='Y')printf("SingleWord:");displayw(yorn,singleword); /*遇到合法字符则立即显示*/singleword[0]=singlesecond;doubleword[0]=doubleword[1];numofsingle=1; /*两者中的后一个是否在将来可以满足双分界符*/}elseif(catchdoubleword==1) /*当前字符的前两个字符满足双分界符*/{doubleword[0]=doubleword[1];singleword[0]=singleword[1];singleword[1]=' ';numofsingle=1;catchdoubleword=0;}}}}else{unknown+=1;error[0]=ch;errortofile(error); /*写入无法识别的字符到文件error*/if(numofsingle==1&&catchdoubleword!=1) /*写入单分界符到文件single*/{singletofile(singleword);if(yorn=='y'||yorn=='Y')printf("SingleWord:");displayw(yorn,singleword); /*遇到合法字符则立即显示*/}numofsingle=0;catchdoubleword=0;cleararray(2,singleword); /*清空暂时存放字符的数组*/cleararray(3,doubleword);}}/*while循环语句结束*/if(enddelimit!=2&&unknown==1) /*末尾无分界符时,记录标识符;文件结束符是不可识别的,故这里unknown==1*/{if(word(words[0])){if(keyword(words)){keywordtofile(words); /*写入关键字到文件keyword*/if(yorn=='y'||yorn=='Y')printf("KeyWord:");displayw(yorn,words); /*遇到合法字符则立即显示*/}else{wordstofile(words); /*写入普通标识符到文件words*/if(yorn=='y'||yorn=='Y')printf("Word:");displayw(yorn,words); /*遇到合法字符则立即显示*/}}else{digittofile(number); /*写入数字到文件digit*/if(yorn=='y'||yorn=='Y')printf("Digit:");displayw(yorn,number); /*遇到合法字符则立即显示*/}}printf("\n词法分析完毕...\n");printf("\n");printf("统计结果如下:");printf("\n");/*显示结果及二元式的写入*/printf("\nKeyWord:");finalresult(0,filen1,fpkey,fpr);printf("\nWord:");finalresult(0,filen2,fpwords,fpr);printf("\nDigit:");finalresult(0,filen3,fpdigit,fpr);printf("\nSingleWord:");finalresult(0,filen4,fpsinglew,fpr);printf("\nDoubleWord:");finalresult(0,filen5,fpdoublew,fpr);printf("\nERROR:");finalresult(0,filen6,fperrorw,fpr);printf("\n");finalresult(1,filen1,fpkey,fpr);finalresult(1,filen2,fpwords,fpr);finalresult(1,filen3,fpdigit,fpr);finalresult(1,filen4,fpsinglew,fpr);finalresult(1,filen5,fpdoublew,fpr);finalresult(1,filen6,fperrorw,fpr);printf("\n程序结束!\n");printf("\n二元式已经写入文件Dualistic_formula\n");printf("\n");fclose(fpr);fclose(fpw);fclose(fpkey);fclose(fpwords);fclose(fpdigit);fclose(fpsinglew);fclose(fpdoublew);fclose(fperrorw);}/**************************************主函数区域**结束********************************************/。
词法分析器源代码#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;}。
#include <stdio.h>#include <stdlib.h>#include <string.h>#define NORW 13 /* of reserved words */#define TXMAX 100 /* length of identifier table */#define NMAX 14 /* max number of digits in numbers */#define AL 10 /* length of identifiers */#define AMAX 2047 /* maxinum address */#define LEVMAX 3 /* max depth of block nesting */#define CXMAX 200 /* size of code array */#define STACKSIZE 500char *symbol[32]= {"nul","ident","number","plus","minus","times","slash","oddsym","eql","neq","lss","leq","gtr","geq","lparen","rparen","comma","semicolon","period","becomes","beginsym","endsym","ifsym","thensym","whilesym","writesym","readsym","dosym","callsym","constsym","varsym","procsym"}; /* type of symbols */c har *word[NORW]={"begin","call","const","do","end","if","odd","procedure","read","then","var","while","write"}; /* table of reserved words */ char *wsym[NORW]={ "beginsym","callsym","constsym","dosym","endsym","ifsym", "oddsym","procsym","readsym","thensym","varsym","whilesym","writesym"};char *mnemonic[8]= {"lit","opr","lod","sto","cal","ini","jmp","jpc"};char ch; /* last char read */char id[AL+1]; /*last identifier read */char sym[10]; /* last symbol read */char line[81];char a[AL+1],fname[AL+1];enum object{constant,variable,procedur};enum object kind;enum fct{lit,opr,lod,sto,cal,ini,jmp,jpc};enum listswitcher{false,true}; /*true set list object code */enum listswitcher listswitch;FILE *fa;FILE *fa1, *fa2;FILE *fin, *fout;int num; /* last number read */int cc; /* character count */int ll; /* line length */int cx; /* code allocation index */int err;int lev=0,tx=0,dx=3;int linecnt=0;struct instruction{enum fct f; /* function code */int l; /* level */int a; /* displacement addr */}; /* lit 0,a: load constant aopr 0,a: execute opr alod l,a: load variable 1, asto l,a: store variable 1, acal l,a: call procedure a at level 1int 0,a: increment t-register by ajmp 0,a: jump to ajpc 0,a: jump conditional to a */ struct instruction code[CXMAX+1];struct table1{char name[AL+1];enum object kind;int val,level,adr,size;};struct table1 table[TXMAX+1];struct node{c har *pa[32];}*declbegsys,*statbegsys,*facbegsys,*tempsetsys; int in(str, set)char *str;struct node *set;{i nt i=0;w hile(set->pa[i]!=NULL){if(strcmp(str,set->pa[i])==0)return( 1 );elsei++;}r eturn( 0 );}struct node *add(set1,set2)struct node *set1,*set2;{i nt i=0,j=0,k=0,cnt;s truct node *pt;p t=(struct node *)malloc(sizeof(struct node));f or(cnt=0; cnt < 32; cnt++)pt->pa[cnt]=(char*)malloc(10*sizeof(char));w hile(set1->pa[i]!=NULL)strcpy(pt->pa[j++],set1->pa[i++]);w hile(set2->pa[k]!=NULL){if (in(set2->pa[k],set1)==0)strcpy(pt->pa[j++],set2->pa[k++]);elsek++;}p t->pa[j]=NULL;r eturn( pt );}error(int n){i nt i;p rintf ("***");f puts ("***", fa1);f or (i=0;i<cc;i++){printf (" ");}f or (i=0;i<cc;i++){fputs (" ",fa1);}p rintf ("error%d\n",n);f printf (fa1, "error%d\n",n);e rr=err+1;}void get_ch( ){i f (cc==ll+1){if (feof(fin)){printf ("program incomplete");}ll= 0;cc= 0;while ((!feof(fin)) && ((ch=fgetc(fin))!='\n')){putchar(ch);fputc(ch,fa1);line[ll++]=ch;}printf ("\n");line[ll]=ch;fprintf (fa1,"\n");}c h=line[cc++];}void getsym( ){i nt i,j,k;w hile(ch==' '||ch=='\t'||ch=='\n')get_ch( );i f (ch>='a'&&ch<='z'){ /* id or reserved word */k=0;do {if(k<AL){a[k]=ch;k=k+1;}get_ch( );}while((ch>='a'&&ch<='z')||(ch>='0'&&ch<='9'));a[k]='\0';strcpy(id,a);i=0;j=NORW-1;do { /* look up reserved words by binary search */k=(i+j)/2;if (strcmp(id,word[k])<=0) j=k-1;if (strcmp(id,word[k])>=0) i=k+1;}while (i<=j);if (i-1>j) strcpy(sym,wsym[k]);else strcpy(sym,"ident");}e lse if (ch>='0'&&ch<='9'){ /* number */k=0;num=0;strcpy(sym,"number");do {num=10*num+(int)ch-'0';k=k+1;get_ch( );}while(ch>='0'&&ch<='9');if(k>NMAX) error(30);}e lse if (ch==':'){get_ch( );if (ch=='='){strcpy(sym,"becomes");get_ch( );}else strcpy(sym,"nul");}e lse if (ch=='<'){get_ch( );if (ch=='='){strcpy(sym,"leq");get_ch( );}else strcpy(sym,"lss");}e lse if (ch=='>'){get_ch( );if (ch=='='){strcpy(sym,"geq");get_ch( );}else strcpy(sym,"gtr");}e lse {switch(ch){case '+': strcpy(sym,"plus");break;case '-': strcpy(sym,"minus");break;case '*': strcpy(sym,"times");break;case '/': strcpy(sym,"slash");break;case '(': strcpy(sym,"lparen");break;case ')': strcpy(sym,"rparen");break;case '=': strcpy(sym,"eql");break;case ',': strcpy(sym,"comma");break;case '.': strcpy(sym,"period");break;case '#': strcpy(sym,"neq");break;case ';': strcpy(sym,"semicolon");break;}get_ch( );}}void gen(x,y,z)enum fct x;int y,z;{i f (cx>CXMAX){printf("program too long");}c ode[cx].f=x;c ode[cx].l=y;c ode[cx].a=z;c x++;}void test(s1,s2,n)struct node *s1,*s2;int n;{i f (in(sym,s1)==0){error(n);s1=add(s1,s2);while(in(sym,s1)==0) getsym( );}}void enter(k) /* enter object into table */ enum object k;{t x=tx+1;s trcpy(table[tx].name,id);t able[tx].kind=k;s witch(k){case constant:if (num>NMAX){error(31);num=0;}table[tx].val=num;break;case variable:table[tx].level=lev;table[tx].adr=dx;dx++;break;case procedur:table[tx].level=lev;break;}}int position(id) /* find identifier in table */ char id[10];{i nt i;s trcpy(table[0].name,id);i=tx;w hile (strcmp(table[i].name,id)!=0)i--;r eturn i;}void constdeclaration( ){i f (strcmp(sym,"ident")==0){getsym( );if (strcmp(sym,"eql")==0||strcmp(sym,"becomes")==0){if (strcmp(sym,"becomes")==0) error(1);getsym( );if (strcmp(sym,"number")==0){enter(constant);getsym( );}else error(2);}else error(3);}e lse error(4);}void vardeclaration( ){i f (strcmp(sym,"ident")==0){enter(variable);getsym( );}e lse error(4);}void listcode(int cx0) /* list code generated for this block */ {i nt i;i f (listswitch==true){for(i=cx0;i<=cx-1;i++){printf("%2d %5s %3d %5d\n",i,mnemonic[(int)code[i].f],code[i].l,code[i].a);fprintf(fa,"%2d %5s %3d %5d\n",i,mnemonic[(int)code[i].f],code[i].l,code[i].a);}}}void factor(fsys)struct node *fsys;{v oid expression( );i nt m=0,n=0,i;c har *tempset[ ]={"rparen",NULL};s truct node *temp;t emp=(struct node *)malloc(sizeof(struct node));w hile(tempset[m]!=NULL)temp->pa[n++]=tempset[m++];t emp->pa[n]=NULL;t est(facbegsys,fsys,24);w hile(in(sym,facbegsys)==1){if (strcmp(sym,"ident")==0){i=position(id);if (i==0) error(11);else switch(table[i].kind){case constant: gen(lit,0,table[i].val);break; /*some thing error here(lev)*/ case variable: gen(lod,lev-table[i].level,table[i].adr);/*must use para pass in*/break;case procedur: error(21);break;}getsym( );}else if (strcmp(sym,"number")==0){if (num>AMAX){error(31);num=0;}gen(lit,0,num);getsym( );}else if (strcmp(sym,"lparen")==0){getsym( );expression(add(temp,fsys));if (strcmp(sym,"rparen")==0) getsym( );else error(22);}test(fsys,facbegsys,23);}}void term(fsys)struct node *fsys;{i nt i=0,j=0;c har mulop[10];c har *tempset[ ]={"times","slash",NULL};s truct node *temp;t emp=(struct node *)malloc(sizeof(struct node));w hile(tempset[i]!=NULL)temp->pa[i++]=tempset[j++];t emp->pa[i]=NULL;f actor(add(temp,fsys));w hile (in(sym,temp)==1){strcpy(mulop,sym);getsym( );factor(add(temp,fsys));if (strcmp(mulop,"times")==0) gen(opr,0,4);else gen(opr,0,5);}}void expression(fsys)struct node *fsys;{i nt m=0,n=0;c har addop[10];c har *tempset[ ]={"plus","minus",NULL};s truct node *temp;t emp=(struct node *)malloc(sizeof(struct node));w hile(tempset[m]!=NULL)temp->pa[n++]=tempset[m++];t emp->pa[n]=NULL;i f(in(sym,temp)==1){strcpy(addop,sym);getsym( );term(add(fsys,temp));if (strcmp(addop,"minus")==0) gen(opr,0,1);}e lse term(add(fsys,temp));w hile (in(sym,temp)==1){strcpy(addop,sym);getsym( );term(add(fsys,temp));if (strcmp(addop,"plus")==0) gen(opr,0,2);else gen(opr,0,3);}}void condition(fsys)struct node *fsys;{i nt i=0,j=0;c har relop[10];c har *tempset[ ]={"eql","neq","lss","leq","gtr","geq",NULL}; s truct node *temp;t emp=(struct node *)malloc(sizeof(struct node));w hile(tempset[i]!=NULL)temp->pa[j++]=tempset[i++];t emp->pa[j]=NULL;i f (strcmp(sym,"oddsym")==0){getsym( );expression(fsys);gen(opr,0,6);}e lse {expression(add(temp,fsys));if (in(sym,temp)==0) error(20);else {strcpy(relop,sym);getsym( );expression(fsys);if(strcmp(relop,"eql")==0) gen(opr,0,8);if(strcmp(relop,"neq")==0) gen(opr,0,9);if(strcmp(relop,"lss")==0) gen(opr,0,10);if(strcmp(relop,"geq")==0) gen(opr,0,11);if(strcmp(relop,"gtr")==0) gen(opr,0,12);if(strcmp(relop,"leq")==0) gen(opr,0,13);}}}void statement(fsys,plev)struct node *fsys;int plev;{i nt i,cx1,cx2,m=0,n=0;c har *tempset1[ ]={"rparen","comma",NULL};c har *tempset2[ ]={"thensym","dosym",NULL};c har *tempset3[ ]={"semicolon","endsym",NULL};c har *tempset4[ ]={"semicolon",NULL};c har *tempset5[ ]={"dosym",NULL};c har *tempset6[ ]={NULL};s truct node *temp1,*temp2,*temp3,*temp4,*temp5,*temp6; t emp1=(struct node *)malloc(sizeof(struct node));t emp2=(struct node *)malloc(sizeof(struct node));t emp3=(struct node *)malloc(sizeof(struct node));t emp4=(struct node *)malloc(sizeof(struct node));t emp5=(struct node *)malloc(sizeof(struct node));t emp6=(struct node *)malloc(sizeof(struct node));w hile(tempset1[m]!=NULL)temp1->pa[n++]=tempset1[m++];t emp1->pa[n]=NULL;m=0;n=0;w hile(tempset2[m]!=NULL)temp2->pa[n++]=tempset2[m++];t emp2->pa[n]=NULL;m=0;n=0;w hile(tempset3[m]!=NULL)temp3->pa[n++]=tempset3[m++];t emp3->pa[n]=NULL;m=0;n=0;w hile(tempset4[m]!=NULL)temp4->pa[n++]=tempset4[m++];t emp4->pa[n]=NULL;m=0;n=0;w hile(tempset5[m]!=NULL)temp5->pa[n++]=tempset5[m++];t emp5->pa[n]=NULL;m=0;n=0;w hile(tempset6[m]!=NULL)temp6->pa[n++]=tempset6[m++];t emp6->pa[n]=NULL;m=0;n=0;i f (strcmp(sym,"ident")==0){i=position(id);if (i==0)error(11);else {if (table[i].kind!=variable){error(12);i=0;}}getsym( );if (strcmp(sym,"becomes")==0) getsym( );else error(13);expression(fsys);if (i!=0)gen(sto,plev-table[i].level,table[i].adr);}e lse if (strcmp(sym,"readsym")==0){getsym( );if (strcmp(sym,"lparen")!=0) error(24);else {do{getsym( );if (strcmp(sym,"ident")==0) i=position(id);else i=0;if (i==0) error(35);else {gen(opr,0,16);gen(sto,plev-table[i].level,table[i].adr);}getsym( );}while(strcmp(sym,"comma")==0);}if (strcmp(sym,"rparen")!=0) {error(22);while(in(sym,fsys)==0) getsym( );}else getsym( );}e lse if (strcmp(sym,"writesym")==0){getsym( );if (strcmp(sym,"lparen")==0){do{getsym( );expression(add(temp1,fsys));gen(opr,0,14);}while(strcmp(sym,"comma")==0);if (strcmp(sym,"rparen")!=0) error(33);else getsym( );}gen(opr,0,15);}e lse if (strcmp(sym,"callsym")==0){getsym( );if (strcmp(sym,"ident")!=0) error(14);else {i=position(id);if (i==0) error(11);else {if (table[i].kind==procedur)gen(cal,plev-table[i].level,table[i].adr);else error(15);}getsym( );}}e lse if (strcmp(sym,"ifsym")==0){getsym( );condition(add(temp2,fsys));if (strcmp(sym,"thensym")==0) getsym( );else error(16);cx1=cx;gen(jpc,0,0);statement(fsys,plev);code[cx1].a=cx;}e lse if (strcmp(sym,"beginsym")==0){getsym( );statement(add(temp3,fsys),plev);while(in(sym,add(temp4,statbegsys))==1){if (strcmp(sym,"semicolon")==0) getsym( );else error(10);statement(add(temp3,fsys),plev);}if (strcmp(sym,"endsym")==0) getsym( );else error(17);}e lse {if (strcmp(sym,"whilesym")==0){cx1=cx;getsym( );condition(add(temp5,fsys));cx2=cx;gen(jpc,0,0);if (strcmp(sym,"dosym")==0) getsym( );else error(18);statement(fsys,plev);gen(jmp,0,cx1);code[cx2].a=cx;}}t est(fsys,temp6,19);}void block(plev,fsys)int plev;struct node *fsys;{i nt m=0,n=0;i nt dx0=3; /* data allocation index */ i nt tx0; /* initial table index */i nt cx0; /* initial code index */c har *tempset1[ ]={"semicolon","endsym",NULL};c har *tempset2[ ]={"ident","procsym",NULL};c har *tempset3[ ]={"semicolon",NULL};c har *tempset4[ ]={"ident",NULL};c har *tempset5[ ]={NULL};s truct node *temp1,*temp2,*temp3,*temp4,*temp5;t emp1=(struct node *)malloc(sizeof(struct node));t emp2=(struct node *)malloc(sizeof(struct node));t emp3=(struct node *)malloc(sizeof(struct node));t emp4=(struct node *)malloc(sizeof(struct node));t emp5=(struct node *)malloc(sizeof(struct node));w hile(tempset1[m]!=NULL)temp1->pa[n++]=tempset1[m++];t emp1->pa[n]=NULL;m=0;n=0;w hile(tempset2[m]!=NULL)temp2->pa[n++]=tempset2[m++];t emp2->pa[n]=NULL;m=0;n=0;w hile(tempset3[m]!=NULL)temp3->pa[n++]=tempset3[m++];t emp3->pa[n]=NULL;m=0;n=0;w hile(tempset4[m]!=NULL)temp4->pa[n++]=tempset4[m++];t emp4->pa[n]=NULL;m=0;n=0;w hile(tempset5[m]!=NULL)temp5->pa[n++]=tempset5[m++];t emp5->pa[n]=NULL;m=0;n=0;l ev=plev;t x0=tx;t able[tx].adr=cx;g en(jmp,0,1);i f (plev>LEVMAX) error(32);d o{if (strcmp(sym,"constsym")==0){getsym( );do{constdeclaration( );while(strcmp(sym,"comma")==0){getsym( );constdeclaration( );}if (strcmp(sym,"semicolon")==0) getsym( );else error(5);}while(strcmp(sym,"ident")==0);}if (strcmp(sym,"varsym")==0){getsym( );do{dx0++;vardeclaration( );while (strcmp(sym,"comma")==0){getsym( );dx0++;vardeclaration( );}if (strcmp(sym,"semicolon")==0) getsym( );else error(5);}while(strcmp(sym,"ident")==0);}while (strcmp(sym,"procsym")==0){getsym( );if (strcmp(sym,"ident")==0){enter(procedur);getsym( );}else error(4);if (strcmp(sym,"semicolon")==0) getsym( );else error(5);block(plev+1,add(temp3,fsys));lev=lev-1;if (strcmp(sym,"semicolon")==0){getsym( );test(add(statbegsys,temp2),fsys,6);}else error(5);}test(add(statbegsys,temp4),declbegsys,7);}while(in(sym,declbegsys)==1);c ode[table[tx0].adr].a=cx;t able[tx0].adr=cx;t able[tx0].size=dx0;c x0=cx;g en(ini,0,dx0);s tatement(add(temp1,fsys),plev);g en(opr,0,0);t est(fsys,temp5,8);l istcode(cx0);}int base(l,b,s)int l;int *b;int s[STACKSIZE];{int b1;b1=*b; /*find base l level down */ while(l>0){b1=s[b1];l=l-1;}return b1;}void interpret( ){i nt p=0; /* p:program register*/ i nt b=1; /* b:base register*/i nt t=0; /* t:topstack registers */ s truct instruction i;i nt s[STACKSIZE]; /* datastore */p rintf("start pl0\n");s[0]=0;s[1]=0;s[2]=0;s[3]=0;d o{i=code[p];p=p+1;switch(i.f){case lit: t=t+1;s[t]=i.a;break;case opr:switch(i.a){ /*operator*/case 0: t=b-1; /*return*/p=s[t+3];b=s[t+2];break;case 1: s[t]=-s[t];break;case 2: t=t-1; /*plus*/s[t]=s[t]+s[t+1];break;case 3: t=t-1; /*minus*/s[t]=s[t]-s[t+1];break;case 4: t=t-1; /*times*/s[t]=s[t]*s[t+1];break;case 5: t=t-1;s[t]=s[t]/s[t+1];break;case 6: if (s[t]%2==0) s[t]=0;else s[t]=1;break;case 8: t=t-1;if (s[t]==s[t+1]) s[t]=1;else s[t]=0;break;case 9: t=t-1;if (s[t]==s[t+1]) s[t]=0;else s[t]=1;break;case 10:t=t-1;if (s[t]<s[t+1]) s[t]=1;else s[t]=0;break;case 11:t=t-1;if (s[t]>=s[t+1]) s[t]=1;else s[t]=0;break;case 12:t=t-1;if (s[t]>s[t+1]) s[t]=1;else s[t]=0;break;case 13:t=t-1;if (s[t]<=s[t+1]) s[t]=1;else s[t]=0;break;case 14:printf("%d",s[t]);fprintf(fa2,"%d",s[t]);t=t-1;break;case 15:printf("\n");fprintf(fa2,"\n");break;case 16:t=t+1;printf("?");fprintf(fa2,"?");scanf("%d",&s[t]);fprintf(fa2,"%d",s[t]);break;}break;case lod: t=t+1;s[t]=s[base(i.l,&b,s)+i.a];break;case sto: s[base(i.l,&b,s)+i.a]=s[t]; /*ptrintf("%d",s[t])*/t=t-1;break;case cal: s[t+1]=base(i.l,&b,s); /*generate new block mark */ s[t+2]=b;s[t+3]=p;b=t+1;p=i.a;break;case ini:t=t+i.a;break;case jmp:p=i.a;break;case jpc:if (s[t]==0) p=i.a;t=t-1;break;}}while(p!=0);f close(fa2);}main( ){i nt m=0,n=0;c har *declbeg[ ]={"constsym","varsym","procsym",NULL};c har *statbeg[ ]={"beginsym","callsym","ifsym","whilesym",NULL};c har *facbeg[ ]={"ident","number","lparen",NULL};c har *tempset[ ]={"period","constsym","varsym","procsym",NULL};d eclbegsys=(struct node *)malloc(sizeof(struct node));s tatbegsys=(struct node *)malloc(sizeof(struct node));f acbegsys=(struct node *)malloc(sizeof(struct node));t empsetsys=(struct node *)malloc(sizeof(struct node));w hile(declbeg[m]!=NULL)declbegsys->pa[n++]=declbeg[m++];d eclbegsys->pa[n]=NULL;m=0;n=0;w hile(statbeg[m]!=NULL)statbegsys->pa[n++]=statbeg[m++];s tatbegsys->pa[n]=NULL;m=0;n=0;w hile(facbeg[m]!=NULL)facbegsys->pa[n++]=facbeg[m++];f acbegsys->pa[n]=NULL;m=0,n=0;w hile(tempset[m]!=NULL)tempsetsys->pa[n++]=tempset[m++];t empsetsys->pa[n]=NULL;i f((fa1=fopen("fa1.txt","w"))==NULL){printf("Cannot open file\n");exit( 0 );}p rintf("Input file?\n");f printf(fa1,"Input file?\n");s canf("%s",fname);f printf(fa1,"%s",fname);i f((fin=fopen(fname,"r"))==NULL){printf("Cannot open file according to given filename\n");exit( 0 );}p rintf("list object code?\n");s canf("%s",fname);f printf(fa1,"list object code?\n");i f (fname[0]=='y')listswitch=true;e lselistswitch=false;e rr=0;c c=1; cx=0; ll=0;c h=' ';g etsym( );i f((fa=fopen("fa.txt","w"))==NULL){printf("Cannot open fa.txt file\n");exit( 0 );}i f((fa2=fopen("fa2.txt","w"))==NULL){printf("Cannot open fa2.txt file\n");exit( 0 );}b lock(0,add(statbegsys,tempsetsys));f close(fa);f close(fa1);i f (strcmp(sym,"period")!=0)error(9);i f (err==0)interpret( );elseprintf("%d errors in PASCAL program\n",err);f close (fin);}。
编译原理实验(一)——词法分析器一.实验描述运行环境:vc++2008对某特定语言A ,构造其词法规则。
该语言的单词符号包括:12状态转换图3程序流程:词法分析作成一个子程序,由另一个主程序调用,每次调用返回一个单词对应的二元组,输出标识符表、常数表由主程序来完成。
二.实验目的通过动手实践,使学生对构造编译系统的基本理论、编译程序的基本结构有更为深入的理解和掌握;使学生掌握编译程序设计的基本方法和步骤;能够设计实现编译系统的重要环节。
同时增强编写和调试程序的能力。
三.实验任务编制程序实现要求的功能,并能完成对测试样例程序的分析。
四.实验原理char set[1000],str[500],strtaken[20];//set[]存储代码,strtaken[]存储当前字符char sign[50][10],constant[50][10];//存储标识符和常量定义了一个Analyzer类class Analyzer{public:Analyzer(); //构造函数 ~Analyzer(); //析构函数int IsLetter(char ch); //判断是否是字母,是则返回 1,否则返回 0。
int IsDigit(char ch); //判断是否为数字,是则返回 1,否则返回 0。
void GetChar(char *ch); //将下一个输入字符读到ch中。
void GetBC(char *ch); //检查ch中的字符是否为空白,若是,则调用GetChar直至ch进入一个非空白字符。
void Concat(char *strTaken, char *ch); //将ch中的字符连接到strToken之后。
int Reserve(char *strTaken); //对strTaken中的字符串查找保留字表,若是一个保留字返回它的数码,否则返回0。
void Retract(char *ch) ; //将搜索指针器回调一个字符位置,将ch置为空白字符。
#include<stdio.h>#include<string.h>#include<stdlib.h>void init();void getsym();enum symbol{nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,procsym,programsym,};#define norw 14#define al 10#define nmax 10char word [norw][al];char ch;enum symbol sym;enum symbol wsym[norw];enum symbol ssym[256];FILE *fin,*fout;void main(){printf("please input outfile's name:\n"); //词法分析之后的结果要输出到的文件char outname[30],inname[30];scanf("%s",outname);if((fout=fopen(outname,"w"))==NULL){printf("cannot open output file!");exit(0);}printf("please input infile's name:\n"); //需要词法分析的源程序scanf("%s",inname);if((fin=fopen(inname,"r"))==NULL){printf("cannot open file!\n");exit(0);}ch=fgetc(fin);while(ch!=EOF){getsym();}}//读取源文件void getsym(){long m;char id[al+1],a[al+1];int i,k;init();if(ch==' '||ch==10||ch==9){ch=fgetc(fin);}else{if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'){k=0;do{if(k<al){a[k]=ch;k++;}ch=fgetc(fin);}while((ch>='a'&&ch<='z'||ch>='0'&&ch<='9')||(ch>='A'&&ch<='Z'||ch>='0'&&ch<='9'));a[k]=0;strcpy(id,a);for(i=0;i<norw;i++){if(strcmp(id,word[i])==0){sym=wsym[i];printf("%s %ssym\n",id,id);fprintf(fout,"%s %ssym\n",id,id);break;}else{if(i==(norw-1)){sym=ident;printf("%s ident\n",id);fprintf(fout,"%s ident\n",id);}}}else{if(ch>='0'&&ch<='9'){k=0;m=0;sym=number;do{m=10*m+ch-'0';k++;ch=getc(fin);}while(ch>='0'&&ch<='9');if(k>=nmax){printf(" error!数值太大!\n");//exit(0);}printf("%d number\n",m);fprintf(fout,"%d number\n",m);}else{if(ch==':'){ch=getc(fin);if(ch=='='){sym=becomes;printf(":= becomes\n");fprintf(fout,":= becomes\n");ch=fgetc(fin);}else{sym=nul;printf(": nul\n");fprintf(fout,": nul\n");}}{if(ch=='<'){ch=fgetc(fin);if(ch=='='){sym=leq;printf("<= lep\n");fprintf(fout,"<= lep\n");ch=fgetc(fin);}else{sym=lss;printf("< lss\n");fprintf(fout,"< lss\n");}}else{if(ch=='>'){ch=fgetc(fin);if(ch=='='){sym=geq;printf(">= geq\n");fprintf(fout,">= geq\n");ch=fgetc(fin);}else{sym=gtr;printf("> gtr\n");fprintf(fout,"> gtr\n");}}else{sym=ssym[ch];if(ch=='+'){printf("+ plus\n");fprintf(fout,"+ plus\n");ch=fgetc(fin);}elseif(ch=='-'){printf("- minus\n");fprintf(fout,"- minus\n");ch=fgetc(fin);}elseif(ch=='*'){printf("* times\n");fprintf(fout,"* times\n");ch=fgetc(fin);}elseif(ch=='/'){printf("/ slash\n");fprintf(fout,"/ slash\n");ch=fgetc(fin);}elseif(ch=='('){printf("( lparen\n");fprintf(fout,"( lparen\n");ch=fgetc(fin);}elseif(ch==')'){printf(") rparen\n");fprintf(fout,") rparen\n");ch=fgetc(fin);}elseif(ch=='='){printf("= eql\n");fprintf(fout,"= eql\n");ch=fgetc(fin);}elseif(ch==','){printf(", comma\n");fprintf(fout,", comma\n");ch=fgetc(fin);}elseif(ch=='#'){printf("# neq\n");fprintf(fout,"# neq\n");ch=fgetc(fin);}elseif(ch=='.'){printf(". period\n");fprintf(fout,". period\n");ch=fgetc(fin);}elseif(ch==';'){printf("; semicoln\n");fprintf(fout,"; semicoln\n");ch=fgetc(fin);}else{printf("%c nul\n",ch);fprintf(fout,"%c nul\n",ch);ch=fgetc(fin);}}}}}}}}//对关键字等实现初始化void init(){int i;for(i=0;i<=255;i++){ssym[i]=nul;}ssym['+']=plus;ssym['-']=minus;ssym['*']=times;ssym['/']=slash;ssym['(']=lparen;ssym[')']=rparen;ssym['=']=eql;ssym[',']=comma;ssym['.']=period;ssym['#']=neq;ssym[';']=semicolon;strcpy(&(word[0][0]),"begin");strcpy(&(word[1][0]),"call");strcpy(&(word[2][0]),"const");strcpy(&(word[3][0]),"do");strcpy(&(word[4][0]),"end");strcpy(&(word[5][0]),"if");strcpy(&(word[6][0]),"odd");strcpy(&(word[7][0]),"procedure");strcpy(&(word[8][0]),"read");strcpy(&(word[9][0]),"program");strcpy(&(word[10][0]),"var");strcpy(&(word[11][0]),"whlie");strcpy(&(word[12][0]),"write");strcpy(&(word[13][0]),"then");wsym[0]=beginsym;wsym[1]=callsym;wsym[2]=constsym;wsym[3]=dosym;wsym[4]=endsym;wsym[5]=ifsym;wsym[6]=oddsym;wsym[7]=procsym;wsym[8]=readsym;wsym[9]=programsym;wsym[10]=varsym;wsym[11]=whilesym;wsym[12]=writesym;wsym[13]=thensym;}。
词法分析实验报告一、实验目的与要求:1、了解字符串编码组成的词的内涵,感觉一下字符串编码的方法和解读2、了解和掌握自动机理论和正规式理论在词法分析程序和控制理论中的应用二、实验内容:构造一个自己设计的小语言的词法分析器:1、这个小语言能说明一些简单的变量识别诸如begin,end,if,while等保留字;识别非保留字的一般标识符(有下划线、字符、数字,且第一个字符不能是数字)。
识别数字序列(整数和小数);识别:=,<=,>=之类的特殊符号以及;,(,)等界符。
2、相关过程(函数):Scanner()词法扫描程序,提取标识符并填入display表中3、这个小语言有顺序结构的语句4、这个小语言能表达分支结构的语句5、这个小语言能够输出结果总之这个小语言词法分析器能提供以上所说明到的语法描述的功能……三、实验步骤:1、测试评价(1)、测试1:能说明一些简单的变量,如关键字、一般标识符、界符等;(2)、测试2:能输出结果:单词符号(内码形式)、各种信息表(如符号表、常量表等);(3)、测试程序:var x,y,z;beginx:=2;y:=3;if (x+5>=y*y) thenbeginz:=y*y-x;z:=z+x*x;endelsez:=x+y;prn z;end.(4)、结果:①、从键盘读入;部分结果如下:(类型:该标识符所属的类型,如关键字,变量等;下标:该标识符所对应表(如变量标识符表,常量标识符表等)中其相应的位置,下同)②、从文件读入,输出到文件;部分结果如下:其他测试及结果如下:③、出错处理;注:若有错误,则只指出错误,不输出各个表;(5)、评价:这个小语言程序基本上能完成词法分析阶段的工作,识别诸如begin,if等保留字;识别非保留字的一般标识符(有下划线、字符、数字,且第一个字符不能是数字)。
识别数字序列(整数和小数);识别:=,<=,>=之类的特殊符号以及;,(,)等界符。
#include<stdio.h>#include<string.h>#include<stdlib.h>void init();void getsym();enum symbol {nul,ident,number,plus,minus,times,slash,oddsym,eql,neq, beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym, constsym,varsym,procsym,programsym,};#define norw 14#define al 10#define nmax 10char word [norw][al];char ch;enum symbol sym;enum symbol wsym[norw];enum symbol ssym[256];FILE *fin,*fout;void main(){printf("please input outfile's name:\n");//词法分析之后的结果要输出到的文件}char outname[30],inname[30]; scanf("%s",outname);if((fout=fopen(outname,"w"))==NULL){printf("cannot open output file!");exit(0);}printf("please input infile's name:\n");//需要词法分析的源程序scanf("%s",inname);if((fin=fopen(inname,"r"))==NULL){printf("cannot open file!\n");exit(0);}ch=fgetc(fin);while(ch!=EOF){}getsym();//读取源文件void getsym(){long m;char id[al+1],a[al+1];int i,k;init();if(ch==' '||ch==10||ch==9){}else {if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'){k=0;ch=fgetc(fin);do {if(k<al){a[k]=ch;k++;}ch=fgetc(fin);}while((ch>='a'&&ch<='z'||ch>='0'&&ch<='9')||(ch>='A'&&ch<='Z'||ch>='0'&&ch<='9') );a[k]=0;strcpy(id,a);for(i=0;i<norw;i++){if(strcmp(id,word[i])==0){sym=wsym[i]; printf("%s %ssym\n",id,id);fprintf(fout,"%s %ssym\n",id,id);break;}else {if(i==(norw-1)){sym=ident;printf("%s ident\n",id);fprintf(fout,"%s ident\n",id);}}}}else {if(ch>='0'&&ch<='9'){k=0;m=0;sym=number;do}{m=10*m+ch-'0';k++;ch=getc(fin);}while(ch>='0'&&ch<='9');if(k>=nmax){printf("error!数值太大!\n");//exit(0);}printf("%d number\n",m);fprintf(fout,"%d number\n",m); else {if(ch==':'){ch=getc(fin);printf(":fprintf(fout,":ch=fgetc(fin);}else {}sym=nul; fprintf(fout,":nul\n");printf(":nul\n");else {if(ch=='<'){ch=fgetc(fin); if(ch=='='){sym=leq;printf("<=lep\n");fprintf(fout,"<=ch=fgetc(fin);}else {sym=lss; printf("<fprintf(fout,"<}}else {if(ch=='>'){ch=fgetc(fin); if(ch=='='){sym=geq;printf(">=fprintf(fout,">=ch=fgetc(fin);}else {sym=gtr;printf(">fprintf(fout,">}}else {sym=ssym[ch];if(ch=='+'){printf("+plus\n");ch=fgetc(fin);}else lep\n");lss\n");lss\n");geq\n");geq\n");gtr\n");gtr\n");plus\n");fprintf(fout,"+if(ch=='-'){printf("-minus\n");fprintf(fout,"-else if(ch=='*'){printf("*times\n");fprintf(fout,"*elseif(ch=='/'){printf("/slash\n");fprintf(fout,"/minus\n");ch=fgetc(fin);} times\n");ch=fgetc(fin);}slash\n");ch=fgetc(fin);}if(ch=='('){printf("(rparen\n");ch=fgetc(fin);}eql\n");ch=fgetc(fin);}neq\n");ch=fgetc(fin);}period\n");ch=fgetc(fin);}semicoln\n");ch=fgetc(fin);}nul\n",ch);ch=fgetc(fin);}}}}}}}}//对关键字等实现初始化void init(){int i;for(i=0;i<=255;i++){elselparen\n");fprintf(fout,"(elseif(ch==')'){printf(")elseif(ch=='='){printf("=elseif(ch==','){printf(",elseif(ch=='#'){printf("#elseif(ch=='.'){printf(".elseif(ch==';'){printf(";else{printf("%c lparen\n");ch=fgetc(fin);}rparen\n");fprintf(fout,")neq\n");fprintf(fout,"#period\n");fprintf(fout,".semicoln\n");fprintf(fout,"; nul\n",ch);fprintf(fout,"%c }ssym[i]=nul;}ssym['+']=plus;ssym['-']=minus;ssym['*']=times;ssym['/']=slash;ssym['(']=lparen;ssym[')']=rparen;ssym['=']=eql;ssym['.']=period;ssym['#']=neq;ssym[';']=semicolon;strcpy(&(word[0][0]),"begin");strcpy(&(word[1][0]),"call");strcpy(&(word[2][0]),"const");strcpy(&(word[3][0]),"do");strcpy(&(word[4][0]),"end");strcpy(&(word[5][0]),"if");strcpy(&(word[6][0]),"odd");strcpy(&(word[7][0]),"procedure");strcpy(&(word[8][0]),"read");strcpy(&(word[9][0]),"program"); strcpy(&(word[10][0]),"var"); strcpy(&(word[11][0]),"whlie"); strcpy(&(word[12][0]),"write"); strcpy(&(word[13][0]),"then"); wsym[0]=beginsym;wsym[1]=callsym;wsym[2]=constsym;wsym[3]=dosym;wsym[4]=endsym;wsym[5]=ifsym;wsym[6]=oddsym;wsym[7]=procsym;wsym[8]=readsym;wsym[9]=programsym;wsym[10]=varsym;wsym[11]=whilesym;wsym[12]=writesym;wsym[13]=thensym;。
C语言词法分析器_源代码_风君版.txt小时候觉得父亲不简单,后来觉得自己不简单,再后来觉得自己孩子不简单。
越是想知道自己是不是忘记的时候,反而记得越清楚。
#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();}}void char_search(char *word){int m;int value1=0;FILE *foutput;for (m=1;m<=34;m++)if (strcmp(word,key0[m])==0){value1=1;break;}if (value1==1){foutput=fopen("output.txt","a");fprintf(foutput,"keyword:%s\n",word);fclose(foutput);}else{foutput=fopen("output.txt","a");fprintf(foutput,"New Identifier:\"%s\"\n",word);fclose(foutput);}}。