1. 程式人生 > >編譯原理實驗:實驗一 簡單詞法分析程序設計(必修)(Python實現)

編譯原理實驗:實驗一 簡單詞法分析程序設計(必修)(Python實現)

it is 括號 ali 鍵盤輸入 優化 沒有 mce constant 是否

一、實驗目的

了解詞法分析程序的基本構造原理,掌握詞法分析程序的手工構造方法。

二、實驗內容

1、了解編譯程序的詞法分析過程。

2根據PASCAL語言的說明語句形式,用手工方法構造一個對說明語句進行詞法分析的程序。該程序能對從鍵盤輸入或從文件讀入形如:

“const count=10,sum=81.5, char1=’f’, string1=”hj”,max=169;”

的常量說明串進行處理,分析常量說明串中各常量名、常量類型及常量值,並統計各種類型常量個數。

三、實驗要求

1、輸入的常量說明串,要求最後以分號作結束標誌;

2、根據輸入串或讀入的文本文件中第一個單詞是否為“const”判斷輸入串或文本文件是否為常量說明內容;

3、識別輸入串或打開的文本文件中的常量名。常量名必須是標識符,定義為字母開頭,後跟若幹個字母,數字或下劃線;

4、根據各常量名緊跟等號“=”後面的內容判斷常量的類型。其中:字符型常量定義為放在單引號內的一個字符;字符串常量定義為放在雙引號內所有內容;整型常量定義為帶或不帶+、- 號,不以0開頭的若幹數字的組合;實型常量定義為帶或不帶+、- 號,不以0開頭的若幹數字加上小數點再後跟若幹數字的組合;

5、統計並輸出串或文件中包含的各種類型的常量個數;

6、以二元組(類型,值)的形式輸出各常量的類型和值;

7、根據常量說明串置於高級語言源程序中時可能出現的錯誤情況,模仿高級語言編譯器對不同錯誤情況做出相應處理;

代碼實現:考慮到Python的正則表達式的強大,我就用了Python來實現,也正好練練自己的Python代碼能力,學習Python這麽久了,自己還沒用Python正式寫過項目,實在不敢說自己學過Python。

考慮到實驗內容,我分別用了幾個函數來提取const關鍵字,提取每一個常量定義的句子,和提取變量標識符,和判斷變臉的類型。

代碼如下:

  

  1 import re
  2 """5個做統計的全局變量"""
  3 int_num = 0
  4 char_num = 0
  5 string_num = 0
  6 float_num = 0
  7 bool_num = 0
  8 """
用來去掉正則時產生的 中括號 以及 分號 ‘ """ 9 def myReplace(s): 10 s = s.replace([\‘,‘‘) 11 s = s.replace(\‘],‘‘) 12 s = s.replace([,‘‘) 13 s = s.replace(],‘‘) 14 return s 15 """判斷是否是bool型常量""" 16 def IsBool(s,currn): 17 s = s + 18 global bool_num 19 bool_error = re.findall(r= *([a-z]+ +[^ ]+) ,s,0)#優先匹配錯誤情況,比如 x = true hdfkjg(中間空格分開的字符) 20 if(bool_error): 21 return False 22 bool_T = re.findall(r= *(true) ,s,0)#匹配true情況 23 if(bool_T): 24 print(currn+(bool,+bool_T[0]+)) 25 bool_num = bool_num + 1 26 return True 27 bool_F = re.findall(r= *(false) ,s,0)#匹配false情況 28 if(bool_F): 29 print(currn + (bool, + bool_F[0] + )) 30 bool_num = bool_num + 1 31 return True 32 33 """判斷是否是字符串常量""" 34 def IsStrings(s,currn): 35 global string_num 36 String = (re.findall(=[\ ]*([\“|\"][^\“\"]*[\”|\"])[\ |,|;]*,s,0)) 37 for strings in String: 38 strings = str(strings) 39 if(strings): 40 print(currn+(string,+strings+)) 41 string_num = string_num + 1 42 return True 43 else: 44 return False 45 """判斷是否是字符常量""" 46 def IsChar(s,currn): 47 Char = re.findall(=\ *([\‘|\‘][^\‘\‘\’]+[\’|\‘]),s,0) 48 global char_num 49 for C in Char: 50 C = str(C) 51 if(C): 52 if(len(C)==3): 53 print(currn+(char, +C+)) 54 char_num = char_num + 1 55 else: 56 print(currn+(Wrong! There are more than one char in ‘’.)) 57 return True 58 else: 59 return False 60 61 """判斷是否是浮點數常量""" 62 def IsFloat(s,currn): 63 s = s + 64 global float_num 65 Float_first = re.findall(r= *([+|-]?0?.[0-9]+) ,s,0)#匹配整數部分為0或者沒有的情況的情況 66 if(Float_first): 67 print(currn+(float,+Float_first[0]+)) 68 float_num = float_num + 1 69 return True 70 Float_0 = re.findall(r= *([+|-]?0[0-9]+.[0-9]+) ,s,0)#匹配整數部分以0開始的錯誤情況 71 if(Float_0): 72 print(currn + (Wrong! The float can’t be started with ‘0’.)) 73 return False 74 Float_E = re.findall(r= *([+|-]?[1-9].[0-9]+[E|e]-[1-9][0-9]*) ,s,0)#匹配正確的實型科學計數法,未考慮錯誤情況 75 if(Float_E): 76 print(currn + (float, + Float_E[0]+ )) 77 float_num = float_num + 1 78 return True 79 Float = str(re.findall(r\=[\ ]*([+|-]?[0-9]*\.[0-9]+) ,s,0)) 80 Float = myReplace(Float) 81 if(Float): 82 print(currn+(float,+Float+)) 83 float_num = float_num + 1 84 return True 85 else: 86 return False 87 88 """判斷是否是整形常量""" 89 def IsInt(s,currn): 90 s = s + 91 global int_num 92 Int_E = re.findall(r= *([+|-]?[1-9].[0-9]+[E|e][+][1-9][0-9]*) ,s,0)#匹配整型為科學計數法的情況,未考慮錯誤情況 93 if(Int_E): 94 print(currn + (integer, + Int_E[0] + )) 95 int_num = int_num + 1 96 return True 97 Int_first = re.findall(r= *([0]) ,s,0)#匹配數值為0的情況 98 if(Int_first): 99 int_num = int_num + 1 100 print(currn + (integer, + 0 + )) 101 return True 102 Int_0 = re.findall(r= *([+|-]?0[0-9]*) ,s,0)#匹配數值以0開頭的情況(已去掉單個0情況) 103 if(Int_0): 104 print(currn + (Wrong! The integer can’t be started with ‘0’.)) 105 return False 106 Int = (str)(re.findall(r= *([+|-]?[1-9][0-9]*) ,s,0)) 107 Int = myReplace(Int) 108 if(Int): 109 print(currn+(integer,+Int+)) 110 int_num = int_num + 1 111 return True 112 else: 113 return False 114 """判斷變量名是否合法""" 115 def pd(s): 116 bian = str(re.findall(r *([A-Za-z0-9_]*) *=,s,0)) 117 bian = myReplace(bian) 118 if(bian and (not(bian[0]>=0and bian[0]<=9))): 119 return bian 120 else: 121 print(bian+(Wrong! It is not aidentifier!)) 122 return 0error 123 """獲得const關鍵字""" 124 def getcon(s): 125 fir = re.findall([\ ]*(const)\ , s, 0) 126 if(len(fir) == 1): 127 return fir 128 else: 129 return None 130 """獲得變量的類型""" 131 def getType(s): 132 fir = (re.findall(r[ |,|,|]+?(.*?[^,;]+)[,|;]*?,s,0))#將輸入正確的串按照 ,(逗號) 或者 ;(分號)分開,/ 133 #操作後的fir就是一個個變量定義的集合 例如 [x = 1, y=2.2] 134 for men in fir: 135 currn = pd(str(men))#判斷變量名是否合法,並取出合法的變量名,如果變量名不合法,currn=‘0error‘ 136 if(currn==0error): 137 continue 138 else: 139 if(IsBool(men,currn)): 140 continue 141 if(IsStrings(men,currn)): 142 continue 143 if(IsChar(men,currn)): 144 continue 145 if(IsFloat(men,currn)): 146 continue 147 if(IsInt(men,currn)): 148 continue 149 150 """Main 函數入口""" 151 if __name__ == __main__: 152 while(True): 153 bool_num = int_num = float_num = char_num = string_num = 0 154 st = input() 155 fir = getcon(st)#獲得const標識符 156 if(fir!=None): 157 getType(st) 158 print("int_num=%d; char_num=%d; string_num=%d; float_num=%d; bool_num=%d."%(int_num,char_num,string_num,float_num,bool_num)) 159 else: 160 print(It is not a constant declaration statement!) 161 print(Please input a string again!) 162 163 164 """ const count=10,sum=81.5,char1=‘f’,max=169,str1=“h*54 2..4S!AAsj”, char2=‘@’,str2=“aa!+h”;

count(float,10)
sum(float,81.5)
char1(char, ‘f’)
max(float,169)
str1(string,“h*54 2..4S!AAsj”)
char2(char, ‘@’)
str2(string,“aa!+h”)
int_num=0; char_num=2; string_num=2; float_num=3; bool_num=0.

Aconstt count=10,sum=81.5,char1=‘f’;

It is not a constant declaration statement!
Please input a string again!

const count=10,12sum=81.5,char1=‘ff’,max=0016;

count(float,10)
12sum(Wrong! It is not aidentifier!)
char1(Wrong! There are more than one char in ‘’.)
max(float,0016)
int_num=0; char_num=0; string_num=0; float_num=2; bool_num=0.

const dx = 1.27e+7,de = 1.27e-21,dd=89.7,fdg=678.6.7.6,4554, rtrtryt=.9898,gfgffggf=8.45,rt = +11.23,rr = -0.01,ry=-00.11;

dx(integer,1.27e+7)
de(float,1.27e-21)
dd(float,89.7)
(Wrong! It is not aidentifier!)
rtrtryt(float,.9898)
gfgffggf(float,8.45)
rt(float,+11.23)
rr(float,-0.01)
ry(Wrong! The float can’t be started with ‘0’.)
int_num=1; char_num=0; string_num=0; float_num=6; bool_num=0.

const x = 1,y=2.2,z=‘u‘,u="hdfjksah",dd=true,dt=false,ry=true ,ri=   false   , zx = true ui,mr = false dslk;

x(float, 1)
y(float,2.2)
z(char, ‘u‘)
u(string,"hdfjksah")
dd(bool,true)
dt(bool,false)
ry(bool,true)
ri(bool,false)
int_num=0; char_num=1; string_num=1; float_num=2; bool_num=4.

const x = 1,y=2.2,z=‘u’,u="hdfjksah";

It is not a constant declaration statement!
Please input a string again!
x(float, 1)
y(float,2.2)
z(char, ‘u’)
u(string,"hdfjksah")
int_num=0; char_num=1; string_num=1; float_num=2; bool_num=0.

"""

六、分析與討論

1、若考慮用E或e的科學計數法來表示整數和實數,應該如何實現?

2、若考慮布爾型常量,且規定其值只能為true或false,應該如何實現?

3、如何對手工構造的詞法分析程序做進一步的優化,以提高代碼質量和運行效率?

優化咋辦還沒有考慮,希望大神幫忙指點。

編譯原理實驗:實驗一 簡單詞法分析程序設計(必修)(Python實現)