一个词法分析器源码的剖析
生活随笔
收集整理的這篇文章主要介紹了
一个词法分析器源码的剖析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一,詞法分析器
作用:讀取源程序的輸入字符、將他們組成詞素,生成并輸出一個詞法單元序列
二,設計原理
1)C程序語言的符號分類:關鍵字、標識符、常數、運算符、界符
2)詞法分析器的二元輸出:<單詞種別,單詞符號屬性值>
3)正規式和狀態轉換圖
4)程序說明:
1>main 中打開源碼文件,從第一個字符流讀取
2>如果第一個是字符,則交給letterprocess(str); 處理
3>如果第一個是數字,則交給numberprocess(str); 處理
4>如果第一個是數字,則交給otherprocess(str);處理
5>注意上述過程中,File *fp每讀取一個詞素,fp都會移動到下一個詞素。對于空格的處理:isspace(ch)檢查參數c是否為空格字符,也就是判斷是否為空格('')、定位字符
('\t')、CR('\r')、換行('\n')、垂直定位字符('\v')或翻頁('\f')的情況
這個程序輸出結果情況匯總:關鍵字、算術運算符、關系運算符、分割符號、特殊符號、注釋符號、邏輯運算符、非法符號
三,程序源碼
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]={"%","$","^","&","_","#"};//特殊標識符 ?
char *zhushifu[3]={"//","/*","*/"};//注釋符 ?
char *luoji[3]={"&&","||","!"};//邏輯運算符 ?
??
??
bool search(char searchstr[],int wordtype)//符號匹配 ??
{ ?
? ? 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)//字母處理函數 ?
{ ?
? ? 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,關鍵字>\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)//數字處理程序 ?
{ ?
? ? int i=-1; ?
? ? char num[20]; ?
? ? while (isdigit(ch)!=0) ?
? ? { ?
? ? ? ? num[++i]=ch; ?
? ? ? ? ch=fgetc(fp); ?
? ? } ?
? ? if(isalpha(ch)!=0)//數字后面是字符 ??
? ? { ?
? ? ? ? while(isspace(ch)==0) ?
? ? ? ? { ?
? ? ? ? ? ? num[++i]=ch; ?
? ? ? ? ? ? ch=fgetc(fp); ?
? ? ? ? } ?
? ? ? ? num[i+1]='\0'; ?
? ? ? ? printf("錯誤!非法標識符:%s\n",num); ?
? ? goto u; ?
? ? } ?
? ? num[i+1]='\0'; ?
? ? printf("<%s,數字>\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,算數運算符>\n",other); ?
? ? else if (search(other,3)) ?
? ? ? ? printf("<%s,關系運算符號>\n",other); ?
? ? else if (search(other,4)) ?
? ? ? ? printf("<%s,分隔符號>\n",other); ?
? ? else if (search(other,5)) ?
? ? ? ? printf("<%s,特殊標識符號>\n",other); ?
? ? else if (search(other,6)) ?
? ? ? ? printf("<%s,注釋符號>\n",other); ?
? ? else if (search(other,7)) ?
? ? ? ? printf("<%s,邏輯運算符號>\n",other); ?
? ? else ??
? ? ? ? printf("錯誤!非法字符:%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("詞法分析結束,謝謝使用!\n"); ?
? ? ?//printf("點任意鍵退出!\n"); ?
? ?} ?
? ?//c=getch(); ?
? ? ?
? ?return 0; ?
}
作用:讀取源程序的輸入字符、將他們組成詞素,生成并輸出一個詞法單元序列
二,設計原理
1)C程序語言的符號分類:關鍵字、標識符、常數、運算符、界符
2)詞法分析器的二元輸出:<單詞種別,單詞符號屬性值>
3)正規式和狀態轉換圖
4)程序說明:
1>main 中打開源碼文件,從第一個字符流讀取
2>如果第一個是字符,則交給letterprocess(str); 處理
3>如果第一個是數字,則交給numberprocess(str); 處理
4>如果第一個是數字,則交給otherprocess(str);處理
5>注意上述過程中,File *fp每讀取一個詞素,fp都會移動到下一個詞素。對于空格的處理:isspace(ch)檢查參數c是否為空格字符,也就是判斷是否為空格('')、定位字符
('\t')、CR('\r')、換行('\n')、垂直定位字符('\v')或翻頁('\f')的情況
這個程序輸出結果情況匯總:關鍵字、算術運算符、關系運算符、分割符號、特殊符號、注釋符號、邏輯運算符、非法符號
三,程序源碼
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]={"%","$","^","&","_","#"};//特殊標識符 ?
char *zhushifu[3]={"//","/*","*/"};//注釋符 ?
char *luoji[3]={"&&","||","!"};//邏輯運算符 ?
??
??
bool search(char searchstr[],int wordtype)//符號匹配 ??
{ ?
? ? 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)//字母處理函數 ?
{ ?
? ? 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,關鍵字>\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)//數字處理程序 ?
{ ?
? ? int i=-1; ?
? ? char num[20]; ?
? ? while (isdigit(ch)!=0) ?
? ? { ?
? ? ? ? num[++i]=ch; ?
? ? ? ? ch=fgetc(fp); ?
? ? } ?
? ? if(isalpha(ch)!=0)//數字后面是字符 ??
? ? { ?
? ? ? ? while(isspace(ch)==0) ?
? ? ? ? { ?
? ? ? ? ? ? num[++i]=ch; ?
? ? ? ? ? ? ch=fgetc(fp); ?
? ? ? ? } ?
? ? ? ? num[i+1]='\0'; ?
? ? ? ? printf("錯誤!非法標識符:%s\n",num); ?
? ? goto u; ?
? ? } ?
? ? num[i+1]='\0'; ?
? ? printf("<%s,數字>\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,算數運算符>\n",other); ?
? ? else if (search(other,3)) ?
? ? ? ? printf("<%s,關系運算符號>\n",other); ?
? ? else if (search(other,4)) ?
? ? ? ? printf("<%s,分隔符號>\n",other); ?
? ? else if (search(other,5)) ?
? ? ? ? printf("<%s,特殊標識符號>\n",other); ?
? ? else if (search(other,6)) ?
? ? ? ? printf("<%s,注釋符號>\n",other); ?
? ? else if (search(other,7)) ?
? ? ? ? printf("<%s,邏輯運算符號>\n",other); ?
? ? else ??
? ? ? ? printf("錯誤!非法字符:%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("詞法分析結束,謝謝使用!\n"); ?
? ? ?//printf("點任意鍵退出!\n"); ?
? ?} ?
? ?//c=getch(); ?
? ? ?
? ?return 0; ?
}
總結
以上是生活随笔為你收集整理的一个词法分析器源码的剖析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 当然我这里讲的都是与数据库有关的字符串拼
- 下一篇: Delphi中的Type