?? 詞法分析器.txt
字號(hào):
詞法分析器
/*****************************C_minus詞法分析器 1.0版 *********************************
* 作者:溫銘
* Email: moonbingbing@gmail.com
* 版權(quán)所有(C) 2005.11
***************************************************************************************/
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
//****************************************
char * change(char *ps,char *pt); //處理路徑中的反斜杠問題。因?yàn)樵谧址幸肻\表示\
int searchkey(char *word,struct key tab[],int n);//二分法查找關(guān)鍵字
int searchsymbol(char c,struct symbol tab[],int n);
void getword(int c,FILE * p);
//****************************************
//用到的結(jié)構(gòu)數(shù)組:
struct key{ //關(guān)鍵字表
char* word;
int value;
}keytab[] = {
"else", 0,
"if", 1,
"int", 2,
"return",3,
"void", 4,
"while", 5,
};
//****
struct symbol{ //符號(hào)表
char c;
int value;
}symboltab[] = {
'(', 0,
')', 1,
'*', 2,
'+', 3,
',', 4,
'-', 5,
'/', 6,
';', 7,
'<', 8,
'=', 9,
'>', 10,
'[', 11,
']', 12,
'{', 13,
'}', 14,
};
//*****************************************
//用到的常量
enum{MAX = 50,
NKEYS = sizeof keytab / sizeof keytab[0],
NSYMBOL = sizeof symboltab / sizeof symboltab[0]
};
//*****************************************
//用到的全局變量
int flagnum = 0; //用來防止出現(xiàn)10t這種情況被當(dāng)作數(shù)字處理。這種情況程序報(bào)錯(cuò)
int countnum = 0;
int countid = 0;
int countfault = 0;
int type[] = {0,1,2,3,4}; //詞法分析中的類型 依次為 關(guān)鍵字,數(shù)字,id,符號(hào)
char array[MAX]; //存放getword中的字符串
//*****************************************
main()
{
int c;
int flag; //判斷搜索函數(shù)是否成功返回
char s[MAX]; //數(shù)組s,t用來存放讀取文件的路徑
char t[2 * MAX];
char *ps = s;
char *pt = t;
FILE * p = NULL;
printf("input the path of the file\n");
scanf("%s",s);
p = fopen( change(ps,pt),"r" ); //打開文件
if( p == NULL ){ //如果輸入的文件路徑不對(duì)或文件不存在
printf("open fail!\n");
exit(0);
}
printf("data \t (type,value)\n");
while( ( c = fgetc(p) ) != EOF ){
if ( isspace(c) ) // 如果是空白字符
continue;
else if ( isalpha(c) ){
getword(c,p);
flag = searchkey(array,keytab,NKEYS);
if ( flag >= 0 ) //如果是關(guān)鍵字
printf("%s\t(%d,%d)\n",array,type[0],flag);
else{ //如果以字母開頭,但不是關(guān)鍵字
printf("%s\t(%d,%d)\n",array,type[2],countid);
countid ++;
}
}else if ( isdigit(c) ){ //如果是數(shù)字
flagnum = 0; /*解決getword中的一個(gè)bug。如果一個(gè)數(shù)字之前有超過1個(gè)的字符串,如in 2。則后面所有的數(shù)字都不能被正確分析*/
getword(c,p);
if ( flagnum == 0 )
printf("%s\t(%d,%d)\n",array,type[1],countnum);
else
printf("%s\t(%d,%d)\t illegal input \n",array,type[4],countfault);
}else if ( ispunct(c) ){ //如果是符號(hào)
flag = searchsymbol(c,symboltab,NSYMBOL);
if ( flag >= 0 )
printf("%c\t(%d,%d)\n",c,type[3],flag);
else{
printf("%c\t(%d,%d)\n",c,type[4],countfault); //出錯(cuò)處理
countfault ++;
}
}else{
printf("%c\t(%d,%d)\n",c,type[4],countfault); //出錯(cuò)處理
countfault ++;
}
}
return 0;
}
//*******************************************
char * change(char *ps,char *pt) /*處理反斜杠的問題*/
{
char *p = pt;
char c;
while( (c = *pt++ = *ps++) != '\0' )
if( c == '\\' )
*pt = '\\';
return p;
}
//******************************************
int searchkey(char *word,struct key tab[],int n)
{
int cond;
int low,high,mid;
low = 0;
high = n -1;
while ( low <= high ){
mid = (low +high) / 2;
if ( ( cond = strcmp(word,tab[mid].word) ) < 0 )
high = mid - 1;
else if ( cond > 0 )
low = mid + 1;
else
return mid;
}
return -1;
}
//**********************************************
int searchsymbol(char c,struct symbol tab[],int n)
{
int low,high,mid;
low = 0;
high = n -1;
while ( low <= high ){
mid = (low +high) / 2;
if ( c < tab[mid].c)
high = mid - 1;
else if(c > tab[mid].c)
low = mid + 1;
else
return mid;
}
return -1;
}
//*******************************************
void getword(int c,FILE * p)
{
int i = 0;
array[i] = c;
while( (c = fgetc(p)) != ' ' && c != '\n'){
if ( isalpha(c) | ispunct(c) ) //如果數(shù)字中有字母或字符,則報(bào)錯(cuò)
flagnum = 1; /*一個(gè)可能引起錯(cuò)誤的地方。已經(jīng)解決(在讀入數(shù)字后,把flagnum置0,再進(jìn)入getword)*/
array[++i] = c;
}
array[++i] = '\0';
}
http://www.qqserver.com/program-33_0.htm
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -