您的位置:首页 > 编程语言 > C语言/C++

C++写的一个简单的词法分析器(分析C语言)

2012-10-31 12:39 309 查看
实验用:

几点注意:

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: