一個詞法分析器原始碼的剖析
一,詞法分析器
作用:讀取源程式的輸入字元、將他們組成詞素,生成並輸出一個詞法單元序列
二,設計原理
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;
}
相關文章
- 詞法分析器詞法分析
- Lex詞法分析器詞法分析
- 詞法分析器Java詞法分析Java
- 詞法分析器的實現詞法分析
- 實現指令碼直譯器 - 詞法分析器指令碼詞法分析
- Monkey 01 lexer 詞法分析器詞法分析
- 【編譯原理】手工打造詞法分析器編譯原理詞法分析
- Flutter 原始碼剖析(一)Flutter原始碼
- vue原始碼剖析(一)Vue原始碼
- Kafka 原始碼剖析(一)Kafka原始碼
- 用Python實現 詞法分析器(Lexical Analyzer)Python詞法分析
- Java集合原始碼剖析——ArrayList原始碼剖析Java原始碼
- 【Java集合原始碼剖析】ArrayList原始碼剖析Java原始碼
- 【Java集合原始碼剖析】Vector原始碼剖析Java原始碼
- 【Java集合原始碼剖析】HashMap原始碼剖析Java原始碼HashMap
- 【Java集合原始碼剖析】Hashtable原始碼剖析Java原始碼
- 【Java集合原始碼剖析】TreeMap原始碼剖析Java原始碼
- C++原始碼單詞掃描程式(詞法分析)C++原始碼詞法分析
- Hanlp自然語言處理工具之詞法分析器HanLP自然語言處理詞法分析
- 編譯原理上機作業1——詞法分析器編譯原理詞法分析
- 【Java集合原始碼剖析】LinkedList原始碼剖析Java原始碼
- 【Java集合原始碼剖析】LinkedHashmap原始碼剖析Java原始碼HashMap
- 剖析 React 原始碼:render 流程(一)React原始碼
- 【水汐の編譯原理】 詞法分析器 課題1編譯原理詞法分析
- PHP-7.1 原始碼學習:詞法分析PHP原始碼詞法分析
- Flutter原始碼剖析(一):原始碼獲取與構建Flutter原始碼
- YYCache 原始碼剖析:一覽亮點原始碼
- 編譯器前端之如何實現基於DFA的詞法分析器編譯前端詞法分析
- epoll–原始碼剖析原始碼
- HashMap原始碼剖析HashMap原始碼
- Alamofire 原始碼剖析原始碼
- Handler原始碼剖析原始碼
- Kafka 原始碼剖析Kafka原始碼
- TreeMap原始碼剖析原始碼
- SDWebImage原始碼剖析(-)Web原始碼
- Boost原始碼剖析--原始碼
- 一個分詞指令碼分詞指令碼
- Spring原始碼剖析9:Spring事務原始碼剖析Spring原始碼