用C語言編寫一個簡單的詞法分析程序

問題描述:ios

用C或C++語言編寫一個簡單的詞法分析程序,掃描C語言小子集的源程序,根據給定的詞法規則,識別單詞,填寫相應的表。若是產生詞法錯誤,則顯示錯誤信息、位置,並試圖從錯誤中恢復。簡單的恢復方法是忽略該字符(或單詞)從新開始掃描。數組

相關詞法規則 ide

<標識符>::=<字母>
<標識符>::=<標識符><字母>
<標識符>::=<標識符><數字>
<常量>::=<無符號整數>
<無符號整數>::=<數字序列>
<數字序列>::=<數字序列><數字>
<數字序列>::=<數字>
<字母>::=a|b|c|……|x|y|z
<數字>::=0|1|2|3|4|5|6|7|8|9
<加法運算符>::=+|-
<乘法運算符>::=*|/
<關係運算符>::=<|>|!=|>=|<=|==
<分界符>::=,|;|(|)|{|}
<保留字>::=main|int|if|else|while|do函數

編寫詞法分析程序的步驟:
spa

(1)肯定所要翻譯的語言(或其子集)。翻譯

C語言設計

(2)設計屬性字,及各種表格,如標識符表、常量表、符號及其機內表示對照表等。code

與詞法分析有關的表格:blog

1. 字符表ci

保留字:main,int,if,else,while,do
字母(全小寫):a|b|c|……|x|y|z
數字:0,1,2,3,4,5,6,7,8,9
運算符和界符:<,>,!=,>=,<=,==,,,;,(,),{,}

2. 特定單詞機內表示表

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

4. 程序

輸入:一個存放C語言程序的s.txt文件
輸出:存放以(單詞,種別碼)形式輸出的result.txt文件

須要6個數組:

1. 存儲關鍵字 key[6]
2. 存儲對應下標關鍵字的種別碼 keyNum[6]
3. 存儲運算符和界符 symbol[17]
4. 存儲運算符對應下標的種別碼 symbolNum[17]
5. 存儲從文件中取出的每一個字符(不包括括號)letter[1000]

主要函數:

TakeWord();

功能:將文件letter[]中每一個字符進行提取,找出關鍵字,輸出種別碼

Num做爲全局變量保存提取到字符的哪一個下標

1. 先提取一個字符,若是是字母,進入case1,調用identifier(),不斷的提取字母或數字進行鏈接,沒鏈接一個字符用int isKeyWord()程序(返回關鍵字種別碼)判斷是否爲關鍵字,是就退出函數返回string,不是就繼續執行函數,直到鏈接的字符再也不是字母或數字,即此時字符串爲標識符

2. 若是是數字,進入case 2,調用Number()函數,不斷進行字符串鏈接,知道下一個鏈接字符再也不是數字

3. 若是是符號,進入case 3,調用symbolStr()函數,若是是=,>,<,!,則要繼續進行下個字符判斷,其他符號能夠直接返回

其餘輔助函數:

int isSymbol()判斷運算符和界符,並返回種別碼
bool isNum() 判斷是否爲數字
bool isLetter()判斷是否爲字母
int isKeyWord()判斷是否爲關鍵字,是返回種別碼
int typeword()返回單個字符的類型
string identifier()標識符的鏈接
string symbolStr()符號和界符的鏈接
string Number()數字的鏈接
void print()輸出

#include <iostream> #include<stdio.h> #include<string.h> #include<stdlib.h>
using namespace std; //關鍵字 
string key[6]={"main","int","if","else","while","do"}; //關鍵字的種別碼
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]; //將字符轉換爲單詞
string words[1000]; int length; //保存程序中字符的數目 
int num; int isSymbol(string s){ //判斷運算符和界符 
 int i; for(i=0;i<17;i++){ if(s==symbol[i]) return symbolNum[i]; } return 0; } //判斷是否爲數字 
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; } //判斷是否爲關鍵字,是返回種別碼 
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") //數字 
  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);//關閉文件 
 fclose(stdout);//關閉文件 
 return 0; }

相關文章
相關標籤/搜索