一个词法分析器源码的剖析
生活随笔
收集整理的這篇文章主要介紹了
一个词法分析器源码的剖析
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一,詞法分析器
作用:讀取源程序的輸入字符、將他們組成詞素,生成并輸出一個(gè)詞法單元序列
二,設(shè)計(jì)原理
1)C程序語(yǔ)言的符號(hào)分類:關(guān)鍵字、標(biāo)識(shí)符、常數(shù)、運(yùn)算符、界符
2)詞法分析器的二元輸出:<單詞種別,單詞符號(hào)屬性值>
3)正規(guī)式和狀態(tài)轉(zhuǎn)換圖
4)程序說明:
1>main 中打開源碼文件,從第一個(gè)字符流讀取
2>如果第一個(gè)是字符,則交給letterprocess(str); 處理
3>如果第一個(gè)是數(shù)字,則交給numberprocess(str); 處理
4>如果第一個(gè)是數(shù)字,則交給otherprocess(str);處理
5>注意上述過程中,File *fp每讀取一個(gè)詞素,fp都會(huì)移動(dòng)到下一個(gè)詞素。對(duì)于空格的處理:isspace(ch)檢查參數(shù)c是否為空格字符,也就是判斷是否為空格('')、定位字符
('\t')、CR('\r')、換行('\n')、垂直定位字符('\v')或翻頁(yè)('\f')的情況
這個(gè)程序輸出結(jié)果情況匯總:關(guān)鍵字、算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、分割符號(hào)、特殊符號(hào)、注釋符號(hào)、邏輯運(yùn)算符、非法符號(hào)
三,程序源碼
Html代碼 ?
#include <stdio.h> ?
#include <stdlib.h> ?
#include <string.h> ?
#include <ctype.h> ?
#include <malloc.h> ?
#include <conio.h> ?
#define NULL 0 ?
FILE *fp; ?
char ch; ?
char *keyword[34]={"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", "printf", ?
"union","unsigned","void","volatile","while","main"}; ?
char *operatornum[6]={"+","-","*","/","++","--"}; ?
char *comparison[8]={"<","<=","=",">",">=","<>","==","!="}; ?
char *interpunction[8]={",",";",":=",".","(",")","{","}"}; ?
char *biaoshifu[6]={"%","$","^","&","_","#"};//特殊標(biāo)識(shí)符 ?
char *zhushifu[3]={"//","/*","*/"};//注釋符 ?
char *luoji[3]={"&&","||","!"};//邏輯運(yùn)算符 ?
??
??
bool search(char searchstr[],int wordtype)//符號(hào)匹配 ??
{ ?
? ? int i; ?
? ? switch (wordtype) ?
? ? { ?
? ? ? ? case 1: ?
? ? ? ? ? ? for(i=0;i<=33;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if(strcmp(keyword[i],searchstr)==0) ?
? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? break; ?
? ? ? ? case 2: ?
? ? ? ? ? ? for(i=0;i<=5;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if(strcmp(operatornum[i],searchstr)==0) ?
? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? ?break; ?
? ? ? ? ? ? ??
? ? ? ? case 3: ??
? ? ? ? ? ? for(i=0;i<=7;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ?if(strcmp(comparison[i],searchstr)==0) ?
? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? break; ?
? ? ?
? ? ? ? case 4: ??
? ? ? ? ? ? for(i=0;i<=7;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if(strcmp(interpunction[i],searchstr)==0) ?
? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ??
? ? ? ? ? ? break; ?
? ? ? ? case 5: ??
? ? ? ? ? ? for(i=0;i<=5;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if(strcmp(biaoshifu[i],searchstr)==0) ?
? ? ? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? break; ?
? ? ? ? case 6: ?
? ? ? ? ? ? ?for(i=0;i<=2;i++) ?
? ? ? ? ? ? ?{ ?
? ? ? ? ? ? ? ? if(strcmp(zhushifu[i],searchstr)==0) ?
? ? ? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? break; ?
? ? ? ? case 7: ??
? ? ? ? ? ? for(i=0;i<=2;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if(strcmp(luoji[i],searchstr)==0) ?
? ? ? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? break; ?
? ? } ?
??
? ? return false; ?
} ?
??
char letterprocess (char ch)//字母處理函數(shù) ?
{ ?
? ? int i=-1; ?
? ? char letter[20]; ?
? ? while (isalnum(ch)!=0) ?
? ? { ?
? ? ? ? letter[++i]=ch; ?
? ? ? ? ch=fgetc(fp); ?
? ? } ?
? ? letter[i+1]='\0'; ?
? ? if (search(letter,1)) ?
? ? { ?
? ? ? ? printf("<%s,關(guān)鍵字>\n",letter); ?
? ? ? ? //strcat(letter,"\n"); ?
? ? ? ? //fputs('<' letter '>\n',outp); ?
? ? } ?
? ? else ?
? ? { ?
? ? ? ? printf("<%s,自定義變量>\n",letter); ?
? ? ? ? //strcat(letter,"\n"); ?
? ? ? ? //fputs(letter,outp); ?
? ? } ?
??
? ? return(ch); ?
} ?
??
char numberprocess(char ch)//數(shù)字處理程序 ?
{ ?
? ? int i=-1; ?
? ? char num[20]; ?
? ? while (isdigit(ch)!=0) ?
? ? { ?
? ? ? ? num[++i]=ch; ?
? ? ? ? ch=fgetc(fp); ?
? ? } ?
? ? if(isalpha(ch)!=0)//數(shù)字后面是字符 ??
? ? { ?
? ? ? ? while(isspace(ch)==0) ?
? ? ? ? { ?
? ? ? ? ? ? num[++i]=ch; ?
? ? ? ? ? ? ch=fgetc(fp); ?
? ? ? ? } ?
? ? ? ? num[i+1]='\0'; ?
? ? ? ? printf("錯(cuò)誤!非法標(biāo)識(shí)符:%s\n",num); ?
? ? goto u; ?
? ? } ?
? ? num[i+1]='\0'; ?
? ? printf("<%s,數(shù)字>\n",num); ?
??
? ? u: return(ch); ?
} ?
??
char otherprocess(char ch)//其他處理程序 ??
{ ?
? ? int i=-1; ?
? ? char other[20]; ?
? ? if (isspace(ch)!=0) ?
? ? { ?
? ? ? ? ch=fgetc(fp); ?
? ? ? ? goto u; ?
? ? } ?
? ? while ((isspace(ch)==0)&&(isalnum(ch)==0)) ?
? ? { ?
? ? ? ? other[++i]=ch; ?
? ? ? ? ch=fgetc(fp); ?
? ? } ?
? ? other[i+1]='\0'; ?
? ? if (search(other,2)) ?
? ? ? ? printf("<%s,算數(shù)運(yùn)算符>\n",other); ?
? ? else if (search(other,3)) ?
? ? ? ? printf("<%s,關(guān)系運(yùn)算符號(hào)>\n",other); ?
? ? else if (search(other,4)) ?
? ? ? ? printf("<%s,分隔符號(hào)>\n",other); ?
? ? else if (search(other,5)) ?
? ? ? ? printf("<%s,特殊標(biāo)識(shí)符號(hào)>\n",other); ?
? ? else if (search(other,6)) ?
? ? ? ? printf("<%s,注釋符號(hào)>\n",other); ?
? ? else if (search(other,7)) ?
? ? ? ? printf("<%s,邏輯運(yùn)算符號(hào)>\n",other); ?
? ? else ??
? ? ? ? printf("錯(cuò)誤!非法字符:%s\n",other); ?
? ? u: return (ch); ?
} ?
??
int main () ?
{ ?
? ? char str; ?
? ? printf("**********************************詞法分析器************************************\n"); ?
? ? if ((fp=fopen("源程序.txt","r"))==NULL) ?
? ? ? ? printf("源程序無法打開!\n"); ?
? ? else ?
? ? { ?
? ? ? ? str =fgetc(fp);//從流中讀取字符 ??
? ? ? ? while (str!=EOF) ?
? ? ? ? { ?
? ? ? ? ? ? if (isalpha(str)!=0)//如果是字符 ? ?isalpha包含在#include <cctype> ?
? ? ? ? ? ? ? ? str=letterprocess(str); ?
? ? ? ? ? ? else ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if (isdigit(str)!=0) ?
? ? ? ? ? ? ? ? ? ? str=numberprocess(str); ?
? ? ? ? ? ? ? ? else ?
? ? ? ? ? ? ? ? ? ? str=otherprocess(str); ?
? ? ? ? ? ? } ?
? ? ??
? ? ? ? }; ?
? ? ?printf("詞法分析結(jié)束,謝謝使用!\n"); ?
? ? ?//printf("點(diǎn)任意鍵退出!\n"); ?
? ?} ?
? ?//c=getch(); ?
? ? ?
? ?return 0; ?
}
作用:讀取源程序的輸入字符、將他們組成詞素,生成并輸出一個(gè)詞法單元序列
二,設(shè)計(jì)原理
1)C程序語(yǔ)言的符號(hào)分類:關(guān)鍵字、標(biāo)識(shí)符、常數(shù)、運(yùn)算符、界符
2)詞法分析器的二元輸出:<單詞種別,單詞符號(hào)屬性值>
3)正規(guī)式和狀態(tài)轉(zhuǎn)換圖
4)程序說明:
1>main 中打開源碼文件,從第一個(gè)字符流讀取
2>如果第一個(gè)是字符,則交給letterprocess(str); 處理
3>如果第一個(gè)是數(shù)字,則交給numberprocess(str); 處理
4>如果第一個(gè)是數(shù)字,則交給otherprocess(str);處理
5>注意上述過程中,File *fp每讀取一個(gè)詞素,fp都會(huì)移動(dòng)到下一個(gè)詞素。對(duì)于空格的處理:isspace(ch)檢查參數(shù)c是否為空格字符,也就是判斷是否為空格('')、定位字符
('\t')、CR('\r')、換行('\n')、垂直定位字符('\v')或翻頁(yè)('\f')的情況
這個(gè)程序輸出結(jié)果情況匯總:關(guān)鍵字、算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、分割符號(hào)、特殊符號(hào)、注釋符號(hào)、邏輯運(yùn)算符、非法符號(hào)
三,程序源碼
Html代碼 ?
#include <stdio.h> ?
#include <stdlib.h> ?
#include <string.h> ?
#include <ctype.h> ?
#include <malloc.h> ?
#include <conio.h> ?
#define NULL 0 ?
FILE *fp; ?
char ch; ?
char *keyword[34]={"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", "printf", ?
"union","unsigned","void","volatile","while","main"}; ?
char *operatornum[6]={"+","-","*","/","++","--"}; ?
char *comparison[8]={"<","<=","=",">",">=","<>","==","!="}; ?
char *interpunction[8]={",",";",":=",".","(",")","{","}"}; ?
char *biaoshifu[6]={"%","$","^","&","_","#"};//特殊標(biāo)識(shí)符 ?
char *zhushifu[3]={"//","/*","*/"};//注釋符 ?
char *luoji[3]={"&&","||","!"};//邏輯運(yùn)算符 ?
??
??
bool search(char searchstr[],int wordtype)//符號(hào)匹配 ??
{ ?
? ? int i; ?
? ? switch (wordtype) ?
? ? { ?
? ? ? ? case 1: ?
? ? ? ? ? ? for(i=0;i<=33;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if(strcmp(keyword[i],searchstr)==0) ?
? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? break; ?
? ? ? ? case 2: ?
? ? ? ? ? ? for(i=0;i<=5;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if(strcmp(operatornum[i],searchstr)==0) ?
? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? ?break; ?
? ? ? ? ? ? ??
? ? ? ? case 3: ??
? ? ? ? ? ? for(i=0;i<=7;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ?if(strcmp(comparison[i],searchstr)==0) ?
? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? break; ?
? ? ?
? ? ? ? case 4: ??
? ? ? ? ? ? for(i=0;i<=7;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if(strcmp(interpunction[i],searchstr)==0) ?
? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ??
? ? ? ? ? ? break; ?
? ? ? ? case 5: ??
? ? ? ? ? ? for(i=0;i<=5;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if(strcmp(biaoshifu[i],searchstr)==0) ?
? ? ? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? break; ?
? ? ? ? case 6: ?
? ? ? ? ? ? ?for(i=0;i<=2;i++) ?
? ? ? ? ? ? ?{ ?
? ? ? ? ? ? ? ? if(strcmp(zhushifu[i],searchstr)==0) ?
? ? ? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? ? ? break; ?
? ? ? ? case 7: ??
? ? ? ? ? ? for(i=0;i<=2;i++) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if(strcmp(luoji[i],searchstr)==0) ?
? ? ? ? ? ? ? ? ? ? return(true); ?
? ? ? ? ? ? } ?
? ? ? ? break; ?
? ? } ?
??
? ? return false; ?
} ?
??
char letterprocess (char ch)//字母處理函數(shù) ?
{ ?
? ? int i=-1; ?
? ? char letter[20]; ?
? ? while (isalnum(ch)!=0) ?
? ? { ?
? ? ? ? letter[++i]=ch; ?
? ? ? ? ch=fgetc(fp); ?
? ? } ?
? ? letter[i+1]='\0'; ?
? ? if (search(letter,1)) ?
? ? { ?
? ? ? ? printf("<%s,關(guān)鍵字>\n",letter); ?
? ? ? ? //strcat(letter,"\n"); ?
? ? ? ? //fputs('<' letter '>\n',outp); ?
? ? } ?
? ? else ?
? ? { ?
? ? ? ? printf("<%s,自定義變量>\n",letter); ?
? ? ? ? //strcat(letter,"\n"); ?
? ? ? ? //fputs(letter,outp); ?
? ? } ?
??
? ? return(ch); ?
} ?
??
char numberprocess(char ch)//數(shù)字處理程序 ?
{ ?
? ? int i=-1; ?
? ? char num[20]; ?
? ? while (isdigit(ch)!=0) ?
? ? { ?
? ? ? ? num[++i]=ch; ?
? ? ? ? ch=fgetc(fp); ?
? ? } ?
? ? if(isalpha(ch)!=0)//數(shù)字后面是字符 ??
? ? { ?
? ? ? ? while(isspace(ch)==0) ?
? ? ? ? { ?
? ? ? ? ? ? num[++i]=ch; ?
? ? ? ? ? ? ch=fgetc(fp); ?
? ? ? ? } ?
? ? ? ? num[i+1]='\0'; ?
? ? ? ? printf("錯(cuò)誤!非法標(biāo)識(shí)符:%s\n",num); ?
? ? goto u; ?
? ? } ?
? ? num[i+1]='\0'; ?
? ? printf("<%s,數(shù)字>\n",num); ?
??
? ? u: return(ch); ?
} ?
??
char otherprocess(char ch)//其他處理程序 ??
{ ?
? ? int i=-1; ?
? ? char other[20]; ?
? ? if (isspace(ch)!=0) ?
? ? { ?
? ? ? ? ch=fgetc(fp); ?
? ? ? ? goto u; ?
? ? } ?
? ? while ((isspace(ch)==0)&&(isalnum(ch)==0)) ?
? ? { ?
? ? ? ? other[++i]=ch; ?
? ? ? ? ch=fgetc(fp); ?
? ? } ?
? ? other[i+1]='\0'; ?
? ? if (search(other,2)) ?
? ? ? ? printf("<%s,算數(shù)運(yùn)算符>\n",other); ?
? ? else if (search(other,3)) ?
? ? ? ? printf("<%s,關(guān)系運(yùn)算符號(hào)>\n",other); ?
? ? else if (search(other,4)) ?
? ? ? ? printf("<%s,分隔符號(hào)>\n",other); ?
? ? else if (search(other,5)) ?
? ? ? ? printf("<%s,特殊標(biāo)識(shí)符號(hào)>\n",other); ?
? ? else if (search(other,6)) ?
? ? ? ? printf("<%s,注釋符號(hào)>\n",other); ?
? ? else if (search(other,7)) ?
? ? ? ? printf("<%s,邏輯運(yùn)算符號(hào)>\n",other); ?
? ? else ??
? ? ? ? printf("錯(cuò)誤!非法字符:%s\n",other); ?
? ? u: return (ch); ?
} ?
??
int main () ?
{ ?
? ? char str; ?
? ? printf("**********************************詞法分析器************************************\n"); ?
? ? if ((fp=fopen("源程序.txt","r"))==NULL) ?
? ? ? ? printf("源程序無法打開!\n"); ?
? ? else ?
? ? { ?
? ? ? ? str =fgetc(fp);//從流中讀取字符 ??
? ? ? ? while (str!=EOF) ?
? ? ? ? { ?
? ? ? ? ? ? if (isalpha(str)!=0)//如果是字符 ? ?isalpha包含在#include <cctype> ?
? ? ? ? ? ? ? ? str=letterprocess(str); ?
? ? ? ? ? ? else ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? if (isdigit(str)!=0) ?
? ? ? ? ? ? ? ? ? ? str=numberprocess(str); ?
? ? ? ? ? ? ? ? else ?
? ? ? ? ? ? ? ? ? ? str=otherprocess(str); ?
? ? ? ? ? ? } ?
? ? ??
? ? ? ? }; ?
? ? ?printf("詞法分析結(jié)束,謝謝使用!\n"); ?
? ? ?//printf("點(diǎn)任意鍵退出!\n"); ?
? ?} ?
? ?//c=getch(); ?
? ? ?
? ?return 0; ?
}
總結(jié)
以上是生活随笔為你收集整理的一个词法分析器源码的剖析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 当然我这里讲的都是与数据库有关的字符串拼
- 下一篇: Delphi中的Type