實驗用:
幾點注意:
1.代碼又長又臭,時間關系,沒有優化,冗余項多(我都看不下去了。囧)
2.加了一下簡單的錯誤檢測。(在mapping.h中定義了錯誤類型,可以查閱)
3.使用頭文件宏定義來模擬符號表,也可以用文件
4.對於標志符的入口地址,無非是為了唯一識別,只要名字相同,都作為一個,使用自增的Int來模擬入口地址,即唯一標識。不考慮變量類型。
5.最後輸出有三個表:Token表,錯誤表,標志符表。
6.一個字符一個字符的讀文件,其實可以每次讀到一個固定長度的緩沖區,雙緩沖區進行分析。也可以讀每一行。
代碼:
mapping.h:
[cpp]
/*
頭文件: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:
[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程序)
[cpp] view plaincopy
#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");
/*我是頭豬
程序運行結果:
[plain] view plaincopy
請輸入要進行語法分析的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.