实验用:
几点注意:
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.