C++写的一个简单的词法分析器(分析C语言)
2012-10-31 12:39
309 查看
实验用:
几点注意:
1.代码又长又臭,时间关系,没有优化,冗余项多(我都看不下去了。囧)
2.加了一下简单的错误检测。(在mapping.h中定义了错误类型,可以查阅)
3.使用头文件宏定义来表示单词的各种属性,也可以用文件
4.对于标志符的入口地址,无非是为了唯一识别,只要名字相同,都作为一个,使用自增的Int来模拟入口地址,即唯一标识。不考虑变量类型。
5.最后输出有三个表:Token表,错误表,标志符表。
6.一个字符一个字符的读文件,其实可以每次读到一个固定长度的缓冲区,双缓冲区进行分析。也可以读每一行。
代码:
mapping.h:
main.cpp:
测试的C文件:test.c(一个错误很多的C程序)
程序运行结果:
几点注意:
1.代码又长又臭,时间关系,没有优化,冗余项多(我都看不下去了。囧)
2.加了一下简单的错误检测。(在mapping.h中定义了错误类型,可以查阅)
3.使用头文件宏定义来表示单词的各种属性,也可以用文件
4.对于标志符的入口地址,无非是为了唯一识别,只要名字相同,都作为一个,使用自增的Int来模拟入口地址,即唯一标识。不考虑变量类型。
5.最后输出有三个表:Token表,错误表,标志符表。
6.一个字符一个字符的读文件,其实可以每次读到一个固定长度的缓冲区,双缓冲区进行分析。也可以读每一行。
代码:
mapping.h:
/* 头文件:mapping.h */ //关键字 #define AUTO 1 #define BREAK 2 #define CASE 3 #define CHAR 4 #define CONST 5 #define CONTINUE 6 #define DEFAULT 7 #define DO 8 #define DOUBLE 9 #define ELSE 10 #define ENUM 11 #define EXTERN 12 #define FLOAT 13 #define FOR 14 #define GOTO 15 #define IF 16 #define INT 17 #define LONG 18 #define REGISTER 19 #define RETURN 20 #define SHORT 21 #define SIGNED 22 #define SIZEOF 23 #define STATIC 24 #define STRUCT 25 #define SWITCH 26 #define TYPEDEF 27 #define UNION 28 #define UNSIGNED 29 #define VOID 30 #define VOLATILE 31 #define WHILE 32 #define KEY_DESC "关键字" //标志符 #define IDENTIFER 40 #define IDENTIFER_DESC "标志符" //常量 #define INT_VAL 51 //整形常量 #define CHAR_VAL 52 //字符常量 #define FLOAT_VAL 53 //浮点数常量 #define STRING_VAL 54 //双精度浮点数常量 #define MACRO_VAL 55 //宏常量 #define CONSTANT_DESC "常量" //运算符 #define NOT 61 // ! #define BYTE_AND 62 //& #define COMPLEMENT 63 // ~ #define BYTE_XOR 64 // ^ #define MUL 65 // * #define DIV 66// / #define MOD 67 // % #define ADD 68 // + #define SUB 69 // - #define LES_THAN 70 // < #define GRT_THAN 71 // > #define ASG 72 // = #define ARROW 73 // -> #define SELF_ADD 74 // ++ #define SELF_SUB 75 // -- #define LEFT_MOVE 76 // << #define RIGHT_MOVE 77 // >> #define LES_EQUAL 78 // <= #define GRT_EQUAL 79 // >= #define EQUAL 80 // == #define NOT_EQUAL 81 // != #define AND 82 // && #define OR 83 // || #define COMPLETE_ADD 84 // += #define COMPLETE_SUB 85 // -= #define COMPLETE_MUL 86 // *= #define COMPLETE_DIV 87 // /= #define COMPLETE_BYTE_XOR 88 // ^= #define COMPLETE_BYTE_AND 89 // &= #define COMPLETE_COMPLEMENT 90 // ~= #define COMPLETE_MOD 91 //%= #define BYTE_OR 92 // | #define OPE_DESC "运算符" //限界符 #define LEFT_BRA 100 // ( #define RIGHT_BRA 101 // ) #define LEFT_INDEX 102 // [ #define RIGHT_INDEX 103 // ] #define L_BOUNDER 104 // { #define R_BOUNDER 105 // } #define POINTER 106 // . #define JING 107 // # #define UNDER_LINE 108 // _ #define COMMA 109 // , #define SEMI 110 // ; #define SIN_QUE 111 // ' #define DOU_QUE 112 // " #define CLE_OPE_DESC "限界符" #define NOTE1 120 // "/**/"注释 #define NOTE2 121 // "//"注释 #define NOTE_DESC "注释" #define HEADER 130 //头文件 #define HEADER_DESC "头文件" //错误类型 #define FLOAT_ERROR "float表示错误" #define FLOAT_ERROR_NUM 1 #define DOUBLE_ERROR "double表示错误" #define DOUBLE_ERROR_NUM 2 #define NOTE_ERROR "注释没有结束符" #define NOTE_ERROR_NUM 3 #define STRING_ERROR "字符串常量没有结束符" #define STRING_ERROR_NUM 4 #define CHARCONST_ERROR "字符常量没有结束符" #define CHARCONST_ERROR_NUM 5 #define CHAR_ERROR "非法字符" #define CHAR_ERROR_NUM 6 #define LEFT_BRA_ERROR "'('没有对应项" #define LEFT_BRA_ERROR_NUM 7 #define RIGHT_BRA_ERROR "')'没有对应项" #define RIGHT_BRA_ERROR_NUM 8 #define LEFT_INDEX_ERROR "'['没有对应项" #define LEFT_INDEX_ERROR_NUM 9 #define RIGHT_INDEX_ERROR "']'没有对应项" #define RIGHT_INDEX_ERROR_NUM 10 #define L_BOUNDER_ERROR "'{'没有对应项" #define L_BOUNDER_ERROR_NUM 11 #define R_BOUNDER_ERROR "'}'没有对应项" #define R_BOUNDER_ERROR_NUM 12 #define PRE_PROCESS_ERROR "预处理错误" //头文件或者宏定义错误 #define PRE_PROCESS_ERROR_NUM 13 #define _NULL "无"
main.cpp:
//main.cpp #include <iostream> #include <fstream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <iomanip> #include "mapping.h" using namespace std; const char * key[] = {"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", "union","unsigned","void","volatile","while" };//C语言的关键字 int leftSmall = 0;//左小括号 int rightSmall = 0;//右小括号 int leftMiddle = 0;//左中括号 int rightMiddle = 0;//右中括号 int leftBig = 0;//左大括号 int rightBig = 0;//右大括号 int lineBra[6][1000] = {0};//括号和行数的对应关系,第一维代表左右6种括号 int static_iden_number = 0;//模拟标志符的地址,自增 //Token节点 struct NormalNode { char content[30];//内容 char describe[30];//描述 int type;//种别码 int addr;//入口地址 int line;//所在行数 NormalNode * next;//下一个节点 }; NormalNode * normalHead;//首结点 //错误节点 struct ErrorNode { char content[30];//错误内容 char describe[30];//错误描述 int type; int line;//所在行数 ErrorNode * next;//下一个节点 }; ErrorNode * errorHead;//首节点 //标志符节点 struct IdentiferNode { char content[30];//内容 char describe[30];//描述 int type;//种别码 int addr;//入口地址 int line;//所在行数 IdentiferNode * next;//下一个节点 }; IdentiferNode * idenHead;//首节点 void initNode() { normalHead = new NormalNode(); strcpy(normalHead->content,""); strcpy(normalHead->describe,""); normalHead->type = -1; normalHead->addr = -1; normalHead->line = -1; normalHead->next = NULL; errorHead = new ErrorNode(); strcpy(errorHead->content,""); strcpy(errorHead->describe,""); errorHead->line = -1; errorHead->next = NULL; idenHead = new IdentiferNode(); strcpy(idenHead->content,""); strcpy(idenHead->describe,""); idenHead->type = -1; idenHead->addr = -1; idenHead->line = -1; idenHead->next = NULL; } void createNewNode(char * content,char *descirbe,int type,int addr,int line) { NormalNode * p = normalHead; NormalNode * temp = new NormalNode(); while(p->next!=NULL) { p = p->next; } strcpy(temp->content,content); strcpy(temp->describe,descirbe); temp->type = type; temp->addr = addr; temp->line = line; temp->next = NULL; p->next = temp; } void createNewError(char * content,char *descirbe,int type,int line) { ErrorNode * p = errorHead; ErrorNode * temp = new ErrorNode(); strcpy(temp->content,content); strcpy(temp->describe,descirbe); temp->type = type; temp->line = line; temp->next = NULL; while(p->next!=NULL) { p = p->next; } p->next = temp; } //返回值是新的标志符的入口地址 int createNewIden(char * content,char *descirbe,int type,int addr,int line) { IdentiferNode * p = idenHead; IdentiferNode * temp = new IdentiferNode(); int flag = 0; int addr_temp = -2; while(p->next!=NULL) { if(strcmp(content,p->next->content) == 0) { flag = 1; addr_temp = p->next->addr; } p = p->next; } if(flag == 0) { addr_temp = ++static_iden_number;//用自增来模拟入口地址 } strcpy(temp->content,content); strcpy(temp->describe,descirbe); temp->type = type; temp->addr = addr_temp; temp->line = line; temp->next = NULL; p->next = temp; return addr_temp; } void printNodeLink() { NormalNode * p = normalHead; p = p->next; cout<<"************************************分析表******************************"<<endl<<endl; cout<<setw(30)<<"内容"<<setw(10)<<"描述"<<"\t"<<"种别码"<<"\t"<<"地址"<<"\t"<<"行号"<<endl; while(p!=NULL) { if(p->type == IDENTIFER) { cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<p->addr<<"\t"<<p->line<<endl; } else { cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<"\t"<<p->line<<endl; } p = p->next; } cout<<endl<<endl; } /* 错误种类: 1.float表示错误 2.double表示错误 3.注释没有结束符 4.字符串常量没有结束符 5.字符常量没有结束符 6.非法字符 7.'('没有对应项 8.预处理错误 */ void printErrorLink() { ErrorNode * p = errorHead; p = p->next; cout<<"************************************错误表******************************"<<endl<<endl; cout<<setw(10)<<"内容"<<setw(30)<<"描述"<<"\t"<<"类型"<<"\t"<<"行号"<<endl; while(p!=NULL) { cout<<setw(10)<<p->content<<setw(30)<<p->describe<<"\t"<<p->type<<"\t"<<p->line<<endl; p = p->next; } cout<<endl<<endl; } //标志符表,有重复部分,暂不考虑 void printIdentLink() { IdentiferNode * p = idenHead; p = p->next; cout<<"************************************标志符表******************************"<<endl<<endl; cout<<setw(30)<<"内容"<<setw(10)<<"描述"<<"\t"<<"种别码"<<"\t"<<"地址"<<"\t"<<"行号"<<endl; while(p!=NULL) { cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<p->addr<<"\t"<<p->line<<endl; p = p->next; } cout<<endl<<endl; } int mystrlen(char * word) { if(*word == '\0') { return 0; } else { return 1+mystrlen(word+1); } } //预处理,处理头文件和宏定义 void preProcess(char * word,int line) { const char * include_temp = "include"; const char * define_temp = "define"; char * p_include,*p_define; int flag = 0; p_include = strstr(word,include_temp); if(p_include!=NULL) { flag = 1; int i; for(i=7;;) { if(*(p_include+i) == ' ' || *(p_include+i) == '\t') { i++; } else { break; } } createNewNode(p_include+i,HEADER_DESC,HEADER,-1,line); } else { p_define = strstr(word,define_temp); if(p_define!=NULL) { flag = 1; int i; for(i=7;;) { if(*(p_define+i) == ' ' || *(p_define+i) == '\t') { i++; } else { break; } } createNewNode(p_define+i,CONSTANT_DESC,MACRO_VAL,-1,line); } } if(flag == 0) { createNewError(word,PRE_PROCESS_ERROR,PRE_PROCESS_ERROR_NUM,line); } } void close() { delete idenHead; delete errorHead; delete normalHead; } int seekKey(char * word) { for(int i=0; i<32; i++) { if(strcmp(word,key[i]) == 0) { return i+1; } } return IDENTIFER; } void scanner() { char filename[30]; char ch; char array[30];//单词长度上限是30 char * word; int i; int line = 1;//行数 FILE * infile; printf("请输入要进行语法分析的C语言程序:\n"); scanf("%s",filename); infile = fopen(filename,"r"); while(!infile) { printf("打开文件失败!\n"); return; } ch = fgetc(infile); while(ch!=EOF) { i = 0; //以字母或者下划线开头,处理关键字或者标识符 if((ch>='A' && ch<='Z') || (ch>='a' && ch<='z') || ch == '_') { while((ch>='A' && ch<='Z')||(ch>='a' && ch<='z')||(ch>='0' && ch<='9') || ch == '_') { array[i++] = ch; ch = fgetc(infile); } word = new char[i+1]; memcpy(word,array,i); word[i] = '\0'; int seekTemp = seekKey(word); if(seekTemp!=IDENTIFER) { createNewNode(word,KEY_DESC,seekTemp,-1,line); } else { int addr_tmp = createNewIden(word,IDENTIFER_DESC,seekTemp,-1,line); createNewNode(word,IDENTIFER_DESC,seekTemp,addr_tmp,line); } fseek(infile,-1L,SEEK_CUR);//向后回退一位 } //以数字开头,处理数字 else if(ch >='0' && ch<='9') { int flag = 0; int flag2 = 0; //处理整数 while(ch >='0' && ch<='9') { array[i++] = ch; ch = fgetc(infile); } //处理float if(ch == '.') { flag2 = 1; array[i++] = ch; ch = fgetc(infile); if(ch>='0' && ch<='9') { while(ch>='0' && ch<='9') { array[i++] = ch; ch = fgetc(infile); } } else { flag = 1; } //处理Double if(ch == 'E' || ch == 'e') { array[i++] = ch; ch = fgetc(infile); if(ch == '+' || ch == '-') { array[i++] = ch; ch = fgetc(infile); } if(ch >='0' && ch<='9') { array[i++] = ch; ch = fgetc(infile); } else { flag = 2; } } } word = new char[i+1]; memcpy(word,array,i); word[i] = '\0'; if(flag == 1) { createNewError(word,FLOAT_ERROR,FLOAT_ERROR_NUM,line); } else if(flag == 2) { createNewError(word,DOUBLE_ERROR,DOUBLE_ERROR_NUM,line); } else { if(flag2 == 0) { createNewNode(word,CONSTANT_DESC,INT_VAL,-1,line); } else { createNewNode(word,CONSTANT_DESC,FLOAT_VAL,-1,line); } } fseek(infile,-1L,SEEK_CUR);//向后回退一位 } //以"/"开头 else if(ch == '/') { ch = fgetc(infile); //处理运算符"/=" if(ch == '=') { createNewNode("/=",OPE_DESC,COMPLETE_DIV,-1,line); } //处理"/**/"型注释 else if(ch == '*') { ch = fgetc(infile); while(1) { while(ch != '*') { if(ch == '\n') { line++; } ch = fgetc(infile); if(ch == EOF) { createNewError(_NULL,NOTE_ERROR,NOTE_ERROR_NUM,line); return; } } ch = fgetc(infile); if(ch == '/') { break; } if(ch == EOF) { createNewError(_NULL,NOTE_ERROR,NOTE_ERROR_NUM,line); return; } } createNewNode(_NULL,NOTE_DESC,NOTE1,-1,line); } //处理"//"型注释 else if(ch == '/') { while(ch!='\n') { ch = fgetc(infile); if(ch == EOF) { createNewNode(_NULL,NOTE_DESC,NOTE2,-1,line); return; } } line++; createNewNode(_NULL,NOTE_DESC,NOTE2,-1,line); if(ch == EOF) { return; } } //处理除号 else { createNewNode("/",OPE_DESC,DIV,-1,line); } } //处理常量字符串 else if(ch == '"') { createNewNode("\"",CLE_OPE_DESC,DOU_QUE,-1,line); ch = fgetc(infile); i = 0; while(ch!='"') { array[i++] = ch; if(ch == '\n') { line++; } ch = fgetc(infile); if(ch == EOF) { createNewError(_NULL,STRING_ERROR,STRING_ERROR_NUM,line); return; } } word = new char[i+1]; memcpy(word,array,i); word[i] = '\0'; createNewNode(word,CONSTANT_DESC,STRING_VAL,-1,line); createNewNode("\"",CLE_OPE_DESC,DOU_QUE,-1,line); } //处理常量字符 else if(ch == '\'') { createNewNode("\'",CLE_OPE_DESC,SIN_QUE,-1,line); ch = fgetc(infile); i = 0; while(ch!='\'') { array[i++] = ch; if(ch == '\n') { line++; } ch = fgetc(infile); if(ch == EOF) { createNewError(_NULL,CHARCONST_ERROR,CHARCONST_ERROR_NUM,line); return; } } word = new char[i+1]; memcpy(word,array,i); word[i] = '\0'; createNewNode(word,CONSTANT_DESC,CHAR_VAL,-1,line); createNewNode("\'",CLE_OPE_DESC,SIN_QUE,-1,line); } else if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { if(ch == '\n') { line++; } } else { if(ch == EOF) { return; } //处理头文件和宏常量(预处理) else if(ch == '#') { while(ch!='\n' && ch!=EOF) { array[i++] = ch; ch = fgetc(infile); } word = new char[i+1]; memcpy(word,array,i); word[i] = '\0'; preProcess(word,line); fseek(infile,-1L,SEEK_CUR);//向后回退一位 } //处理-开头的运算符 else if(ch == '-') { array[i++] = ch; ch = fgetc(infile); if(ch >='0' && ch<='9') { int flag = 0; int flag2 = 0; //处理整数 while(ch>='0' && ch<='9') { array[i++] = ch; ch = fgetc(infile); } //处理float if(ch == '.') { flag2 = 1; array[i++] = ch; ch = fgetc(infile); if(ch>='0' && ch<='9') { while(ch>='0' && ch<='9') { array[i++] = ch; ch = fgetc(infile); } } else { flag = 1; } //处理Double if(ch == 'E' || ch == 'e') { array[i++] = ch; ch = fgetc(infile); if(ch == '+' || ch == '-') { array[i++] = ch; ch = fgetc(infile); } if(ch >='0' && ch<='9') { array[i++] = ch; ch = fgetc(infile); } else { flag = 2; } } } word = new char[i+1]; memcpy(word,array,i); word[i] = '\0'; if(flag == 1) { createNewError(word,FLOAT_ERROR,FLOAT_ERROR_NUM,line); } else if(flag == 2) { createNewError(word,DOUBLE_ERROR,DOUBLE_ERROR_NUM,line); } else { if(flag2 == 0) { createNewNode(word,CONSTANT_DESC,INT_VAL,-1,line); } else { createNewNode(word,CONSTANT_DESC,FLOAT_VAL,-1,line); } } fseek(infile,-1L,SEEK_CUR);//向后回退一位 } else if(ch == '>') { createNewNode("->",OPE_DESC,ARROW,-1,line); } else if(ch == '-') { createNewNode("--",OPE_DESC,SELF_SUB,-1,line); } else if(ch == '=') { createNewNode("--",OPE_DESC,SELF_SUB,-1,line); } else { createNewNode("-",OPE_DESC,SUB,-1,line); fseek(infile,-1L,SEEK_CUR); } } //处理+开头的运算符 else if(ch == '+') { ch = fgetc(infile); if(ch == '+') { createNewNode("++",OPE_DESC,SELF_ADD,-1,line); } else if(ch == '=') { createNewNode("+=",OPE_DESC,COMPLETE_ADD,-1,line); } else { createNewNode("+",OPE_DESC,ADD,-1,line); fseek(infile,-1L,SEEK_CUR); } } //处理*开头的运算符 else if(ch == '*') { ch = fgetc(infile); if(ch == '=') { createNewNode("*=",OPE_DESC,COMPLETE_MUL,-1,line); } else { createNewNode("*",OPE_DESC,MUL,-1,line); fseek(infile,-1L,SEEK_CUR); } } //处理按^开头的运算符 else if(ch == '^') { ch = fgetc(infile); if(ch == '=') { createNewNode("^=",OPE_DESC,COMPLETE_BYTE_XOR,-1,line); } else { createNewNode("^",OPE_DESC,BYTE_XOR,-1,line); fseek(infile,-1L,SEEK_CUR); } } //处理%开头的运算符 else if(ch == '%') { ch = fgetc(infile); if(ch == '=') { createNewNode("%=",OPE_DESC,COMPLETE_MOD,-1,line); } else { createNewNode("%",OPE_DESC,MOD,-1,line); fseek(infile,-1L,SEEK_CUR); } } //处理&开头的运算符 else if(ch == '&') { ch = fgetc(infile); if(ch == '=') { createNewNode("&=",OPE_DESC,COMPLETE_BYTE_AND,-1,line); } else if(ch == '&') { createNewNode("&&",OPE_DESC,AND,-1,line); } else { createNewNode("&",OPE_DESC,BYTE_AND,-1,line); fseek(infile,-1L,SEEK_CUR); } } //处理~开头的运算符 else if(ch == '~') { ch = fgetc(infile); if(ch == '=') { createNewNode("~=",OPE_DESC,COMPLETE_COMPLEMENT,-1,line); } else { createNewNode("~",OPE_DESC,COMPLEMENT,-1,line); fseek(infile,-1L,SEEK_CUR); } } //处理!开头的运算符 else if(ch == '!') { ch = fgetc(infile); if(ch == '=') { createNewNode("!=",OPE_DESC,NOT_EQUAL,-1,line); } else { createNewNode("!",OPE_DESC,NOT,-1,line); fseek(infile,-1L,SEEK_CUR); } } //处理<开头的运算符 else if(ch == '<') { ch = fgetc(infile); if(ch == '<') { createNewNode("<<",OPE_DESC,LEFT_MOVE,-1,line); } else if(ch == '=') { createNewNode("<=",OPE_DESC,LES_EQUAL,-1,line); } else { createNewNode("<",OPE_DESC,LES_THAN,-1,line); fseek(infile,-1L,SEEK_CUR); } } //处理>开头的运算符 else if(ch == '>') { ch = fgetc(infile); if(ch == '>') { createNewNode(">>",OPE_DESC,RIGHT_MOVE,-1,line); } else if(ch == '=') { createNewNode(">=",OPE_DESC,GRT_EQUAL,-1,line); } else { createNewNode(">",OPE_DESC,GRT_THAN,-1,line); fseek(infile,-1L,SEEK_CUR); } } //处理|开头的运算符 else if(ch == '|') { ch = fgetc(infile); if(ch == '|') { createNewNode("||",OPE_DESC,OR,-1,line); } else { createNewNode("|",OPE_DESC,BYTE_OR,-1,line); fseek(infile,-1L,SEEK_CUR); } } else if(ch == '=') { ch = fgetc(infile); if(ch == '=') { createNewNode("==",OPE_DESC,EQUAL,-1,line); } else { createNewNode("=",OPE_DESC,ASG,-1,line); fseek(infile,-1L,SEEK_CUR); } } else if(ch == '(') { leftSmall++; lineBra[0][leftSmall] = line; createNewNode("(",CLE_OPE_DESC,LEFT_BRA,-1,line); } else if(ch == ')') { rightSmall++; lineBra[1][rightSmall] = line; createNewNode(")",CLE_OPE_DESC,RIGHT_BRA,-1,line); } else if(ch == '[') { leftMiddle++; lineBra[2][leftMiddle] = line; createNewNode("[",CLE_OPE_DESC,LEFT_INDEX,-1,line); } else if(ch == ']') { rightMiddle++; lineBra[3][rightMiddle] = line; createNewNode("]",CLE_OPE_DESC,RIGHT_INDEX,-1,line); } else if(ch == '{') { leftBig++; lineBra[4][leftBig] = line; createNewNode("{",CLE_OPE_DESC,L_BOUNDER,-1,line); } else if(ch == '}') { rightBig++; lineBra[5][rightBig] = line; createNewNode("}",CLE_OPE_DESC,R_BOUNDER,-1,line); } else if(ch == '.') { createNewNode(".",CLE_OPE_DESC,POINTER,-1,line); } else if(ch == ',') { createNewNode(",",CLE_OPE_DESC,COMMA,-1,line); } else if(ch == ';') { createNewNode(";",CLE_OPE_DESC,SEMI,-1,line); } else { char temp[2]; temp[0] = ch; temp[1] = '\0'; createNewError(temp,CHAR_ERROR,CHAR_ERROR_NUM,line); } } ch = fgetc(infile); } } void BraMappingError() { if(leftSmall != rightSmall) { int i = (leftSmall>rightSmall) ? (leftSmall-rightSmall) : (rightSmall - leftSmall); bool flag = (leftSmall>rightSmall) ? true : false; if(flag) { while(i--) { createNewError(_NULL,LEFT_BRA_ERROR,LEFT_BRA_ERROR_NUM,lineBra[0][i+1]); } } else { while(i--) { createNewError(_NULL,RIGHT_BRA_ERROR,RIGHT_BRA_ERROR_NUM,lineBra[1][i+1]); } } } if(leftMiddle != rightMiddle) { int i = (leftMiddle>rightMiddle) ? (leftMiddle-rightMiddle) : (rightMiddle - leftMiddle); bool flag = (leftMiddle>rightMiddle) ? true : false; if(flag) { while(i--) { createNewError(_NULL,LEFT_INDEX_ERROR,LEFT_INDEX_ERROR_NUM,lineBra[2][i+1]); } } else { while(i--) { createNewError(_NULL,RIGHT_INDEX_ERROR,RIGHT_INDEX_ERROR_NUM,lineBra[3][i+1]); } } } if(leftBig != rightBig) { int i = (leftBig>rightBig) ? (leftBig-rightBig) : (rightBig - leftSmall); bool flag = (leftBig>rightBig) ? true : false; if(flag) { while(i--) { createNewError(_NULL,L_BOUNDER_ERROR,L_BOUNDER_ERROR_NUM,lineBra[4][i+1]); } } else { while(i--) { createNewError(_NULL,R_BOUNDER_ERROR,R_BOUNDER_ERROR_NUM,lineBra[5][i+1]); } } } } int main() { initNode(); scanner(); BraMappingError(); printNodeLink(); printErrorLink(); printIdentLink(); close(); return 0; }
测试的C文件:test.c(一个错误很多的C程序)
#include <stdio.h> #include "my.h" #define max 90 #de some int char main() { 8888char yn; do { int 9801; float 9.; double 9.ef; float -9.876; double hello.8.9; float 7.9e-5; int e-5; a /= 6; init(); /*初始化*/ scanner();//扫描源程序// printf("Are You continue(y/n)\n"); yn=getch(); if(a == 7) { } else { } @ } while(yn=='y'||yn=='Y'); return 0; [hello // // // printf("hello"); /*我是头猪
程序运行结果:
请输入要进行语法分析的C语言程序: test.c ************************************分析表****************************** 内容 描述 种别码 地址 行号 <stdio.h> 头文件 130 1 "my.h" 头文件 130 2 max 90 常量 55 3 int 关键字 17 6 char 关键字 4 6 main 标志符 40 1 6 ( 限界符 100 6 ) 限界符 101 6 { 限界符 104 7 8888 常量 51 8 char 关键字 4 8 yn 标志符 40 2 8 ; 限界符 110 8 do 关键字 8 9 { 限界符 104 10 int 关键字 17 11 9801 常量 51 11 ; 限界符 110 11 float 关键字 13 12 ; 限界符 110 12 double 关键字 9 13 f 标志符 40 3 13 ; 限界符 110 13 float 关键字 13 14 -9.876 常量 53 14 ; 限界符 110 14 double 关键字 9 15 hello 标志符 40 4 15 . 限界符 106 15 8.9 常量 53 15 ; 限界符 110 15 float 关键字 13 16 7.9e-5 常量 53 16 ; 限界符 110 16 int 关键字 17 17 e 标志符 40 5 17 -5 常量 51 17 ; 限界符 110 17 a 标志符 40 6 18 /= 运算符 87 18 6 常量 51 18 ; 限界符 110 18 init 标志符 40 7 19 ( 限界符 100 19 ) 限界符 101 19 ; 限界符 110 19 无 注释 120 19 scanner 标志符 40 8 20 ( 限界符 100 20 ) 限界符 101 20 ; 限界符 110 20 无 注释 121 21 printf 标志符 40 9 21 ( 限界符 100 21 " 限界符 112 21 Are You continue(y/n)\n 常量 54 21 " 限界符 112 21 ) 限界符 101 21 ; 限界符 110 21 yn 标志符 40 2 22 = 运算符 72 22 getch 标志符 40 10 22 ( 限界符 100 22 ) 限界符 101 22 ; 限界符 110 22 if 关键字 16 23 ( 限界符 100 23 a 标志符 40 6 23 == 运算符 80 23 7 常量 51 23 ) 限界符 101 23 { 限界符 104 24 } 限界符 105 26 else 关键字 10 27 { 限界符 104 28 } 限界符 105 30 } 限界符 105 33 while 关键字 32 34 ( 限界符 100 34 yn 标志符 40 2 34 == 运算符 80 34 ' 限界符 111 34 y 常量 52 34 ' 限界符 111 34 || 运算符 83 34 yn 标志符 40 2 34 == 运算符 80 34 ' 限界符 111 34 Y 常量 52 34 ' 限界符 111 34 ) 限界符 101 34 ; 限界符 110 34 return 关键字 20 36 0 常量 51 36 ; 限界符 110 36 [ 限界符 102 37 hello 标志符 40 4 37 无 注释 121 43 无 注释 121 45 无 注释 121 46 printf 标志符 40 9 47 ( 限界符 100 47 " 限界符 112 47 hello 常量 54 47 " 限界符 112 47 ) 限界符 101 47 ; 限界符 110 47 ************************************错误表****************************** 内容 描述 类型 行号 #de some 预处理错误 13 4 9. float表示错误 1 12 9.e double表示错误 2 13 @ 非法字符 6 31 无 注释没有结束符 3 49 无 '['没有对应项 9 37 无 '{'没有对应项 11 7 ************************************标志符表****************************** 内容 描述 种别码 地址 行号 main 标志符 40 1 6 yn 标志符 40 2 8 f 标志符 40 3 13 hello 标志符 40 4 15 e 标志符 40 5 17 a 标志符 40 6 18 init 标志符 40 7 19 scanner 标志符 40 8 20 printf 标志符 40 9 21 yn 标志符 40 2 22 getch 标志符 40 10 22 a 标志符 40 6 23 yn 标志符 40 2 34 yn 标志符 40 2 34 hello 标志符 40 4 37 printf 标志符 40 9 47 Process returned 0 (0x0) execution time : 5.629 s Press any key to continue.
相关文章推荐
- C++写的一个简单的词法分析器(分析C语言)
- C++写的一个简单的语法分析器(分析C语言)
- 深入浅出编译原理-4-一个简单词法分析器的C语言实现
- 一个C语言写的简单的单词识别程序附带VS性能分析结果
- C语言实现一个简单的词法分析器
- 模拟器与程序分析-4-一个简单的周期精确模拟器(CAS)的C语言实现
- C/C++拾遗录--关于一个C语言小程序的分析
- 分析C语言一个简单程序
- C++写一个简单的解析器(分析C语言)
- 一个简单词法分析器的C语言实现
- 《Linux内核分析》week1作业-分析一个简单c语言的汇编代码
- 从零开始学习OpenCL开发(二)一个最简单的示例与简单性能分析
- 一个简单实现apk推广并静默安装的样本分析
- 一个简单线程池的实现 --C语言
- C语言实现一个简单的线程池
- 一个最简单的OSG例子源代码(C++)
- 一个简单的C++的RTTI实现
- 简单分析一个采集交流电压平均值的电路
- 一个程序员面试题目的简单分析
- 做一个简单的解释器----小话c语言