問題描述:

用C或C++語言編寫一個簡單的詞法分析程序,掃描C語言小子集的源程序,根據(jù)給定的詞法規(guī)則,識別單詞,填寫相應的表。如果產(chǎn)生詞法錯誤,則顯示錯誤信息、位置,并試圖從錯誤中恢復。簡單的恢復方法是忽略該字符(或單詞)重新開始掃描。
相關(guān)詞法規(guī)則
<標識符>::=<字母>
<標識符>::=<標識符><字母>
<標識符>::=<標識符><數(shù)字>
<常量>::=<無符號整數(shù)>
<無符號整數(shù)>::=<數(shù)字序列>
<數(shù)字序列>::=<數(shù)字序列><數(shù)字>
<數(shù)字序列>::=<數(shù)字>
<字母>::=a|b|c|……|x|y|z
<數(shù)字>::=0|1|2|3|4|5|6|7|8|9
<加法運算符>::=+|-
<乘法運算符>::=*|/
<關(guān)系運算符>::=<|>|!=|>=|<=|==
<分界符>::=,|;|(|)|{|}
<保留字>::=main|int|if|else|while|do
編寫詞法分析程序的步驟:
(1)確定所要翻譯的語言(或其子集)。
C語言
(2)設計屬性字,及各類表格,如標識符表、常量表、符號及其機內(nèi)表示對照表等。
與詞法分析有關(guān)的表格:
1. 字符表
保留字:main,int,if,else,while,do
字母(全小寫):a|b|c|……|x|y|z
數(shù)字:0,1,2,3,4,5,6,7,8,9
運算符和界符:<,>,!=,>=,<=,==,,,;,(,),{,}
2. 特定單詞機內(nèi)表示表

3.畫出總控流程圖及各個子程序的流程圖。

4. 程序
輸入:一個存放C語言程序的s.txt文件
輸出:存放以(單詞,種別碼)形式輸出的result.txt文件
需要6個數(shù)組:
1. 存儲關(guān)鍵字 key[6]
2. 存儲對應下標關(guān)鍵字的種別碼 keyNum[6]
3. 存儲運算符和界符 symbol[17]
4. 存儲運算符對應下標的種別碼 symbolNum[17]
5. 存儲從文件中取出的每個字符(不包括括號)letter[1000]
主要函數(shù):
TakeWord();
功能:將文件letter[]中每個字符進行提取,找出關(guān)鍵字,輸出種別碼
Num作為全局變量保存提取到字符的哪個下標
1. 先提取一個字符,如果是字母,進入case1,調(diào)用identifier(),不斷的提取字母或數(shù)字進行連接,沒連接一個字符用int isKeyWord()程序(返回關(guān)鍵字種別碼)判斷是否為關(guān)鍵字,是就退出函數(shù)返回string,不是就繼續(xù)執(zhí)行函數(shù),直到連接的字符不再是字母或數(shù)字,即此時字符串為標識符
2. 如果是數(shù)字,進入case 2,調(diào)用Number()函數(shù),不斷進行字符串連接,知道下一個連接字符不再是數(shù)字
3. 如果是符號,進入case 3,調(diào)用symbolStr()函數(shù),如果是=,>,<,!,則要繼續(xù)進行下個字符判斷,其余符號可以直接返回
其他輔助函數(shù):
int isSymbol()判斷運算符和界符,并返回種別碼
bool isNum() 判斷是否為數(shù)字
bool isLetter()判斷是否為字母
int isKeyWord()判斷是否為關(guān)鍵字,是返回種別碼
int typeword()返回單個字符的類型
string identifier()標識符的連接
string symbolStr()符號和界符的連接
string Number()數(shù)字的連接
void print()輸出
程序:
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
//關(guān)鍵字
string key[6]={"main","int","if","else","while","do"};
//關(guān)鍵字的種別碼
int keyNum[6]={1,2,3,4,5,6};
//運算符和界符
string symbol[17]={"<",">","!=",">=","<=","==",",",";","(",")","{","}","+","-","*","/","="};
//char symbol[12]={'<','>','!=','>=','<=','==',',',';','(',')','{','}'};
//運算符和界符的種別碼
int symbolNum[17]={7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};
//存放文件取出的字符
string letter[1000];
//將字符轉(zhuǎn)換為單詞
string words[1000];
int length; //保存程序中字符的數(shù)目
int num;
int isSymbol(string s){ //判斷運算符和界符
int i;
for(i=0;i<17;i++){
if(s==symbol[i])
return symbolNum[i];
}
return 0;
}
//判斷是否為數(shù)字
bool isNum(string s){
if(s>="0" && s<="9")
return true;
return false;
}
//判斷是否為字母
bool isLetter(string s)
{
if(s>="a" && s<="z")
return true;
return false;
}
//判斷是否為關(guān)鍵字,是返回種別碼
int isKeyWord(string s){
int i;
for(i=0;i<6;i++){
if(s==key[i])
return keyNum[i];
}
return 0;
}
//返回單個字符的類型
int typeword(string str){
if(str>="a" && str<="z") // 字母
return 1;
if(str>="0" && str<="9") //數(shù)字
return 2;
if(str==">"||str=="="||str=="<"||str=="!"||str==","||str==";"||str=="("||str==")"||str=="{"||str=="}"
||str=="+"||str=="-"||str=="*"||str=="/") //判斷運算符和界符
return 3;
}
string identifier(string s,int n){
int j=n+1;
int flag=1;
while(flag){
if(isNum(letter[j]) || isLetter(letter[j])){
s=(s+letter[j]).c_str();
if(isKeyWord(s)){
j++;
num=j;
return s;
}
j++;
}
else{
flag=0;
}
}
num=j;
return s;
}
string symbolStr(string s,int n){
int j=n+1;
string str=letter[j];
if(str==">"||str=="="||str=="<"||str=="!") {
s=(s+letter[j]).c_str();
j++;
}
num=j;
return s;
}
string Number(string s,int n){
int j=n+1;
int flag=1;
while(flag){
if(isNum(letter[j])){
s=(s+letter[j]).c_str();
j++;
}
else{
flag=0;
}
}
num=j;
return s;
}
void print(string s,int n){
cout<<"("<<s<<","<<n<<")"<<endl;
}
void TakeWord(){ //取單詞
int k;
for(num=0;num<length;){
string str1,str;
str=letter[num];
k=typeword(str);
switch(k){
case 1:
{
str1=identifier(str,num);
if(isKeyWord(str1))
print(str1,isKeyWord(str1));
else
print(str1,0);
break;
}
case 2:
{
str1=Number(str,num);
print(str1,24);
break;
}
case 3:
{
str1=symbolStr(str,num);
print(str1,isSymbol(str1));
break;
}
}
}
}
int main(){
char w;
int i,j;
freopen("s.txt","r",stdin);
freopen("result.txt","w",stdout); //從控制臺輸出,而不是文本輸出
length=0;
while(cin>>w){
if(w!=' '){
letter[length]=w;
length++;
} //去掉程序中的空格
}
TakeWord();
// for(j=0;j<length;j++){
// cout<<letter[j]<<endl;
// }
fclose(stdin);//關(guān)閉文件
fclose(stdout);//關(guān)閉文件
return 0;
}另外有需要云服務器可以了解下創(chuàng)新互聯(lián)建站www.chinadenli.net,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
標題名稱:C語言實現(xiàn)詞法分析器-創(chuàng)新互聯(lián)
網(wǎng)站地址:http://www.chinadenli.net/article36/diopsg.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設計、網(wǎng)站營銷、自適應網(wǎng)站、企業(yè)建站、企業(yè)網(wǎng)站制作、虛擬主機
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容