超簡單易懂的編譯原理詞法分析 python

2021-09-23 20:45:54 字數 4967 閱讀 3159

詞法分析是電腦科學中將字串行轉換為單詞序列的過程,進行詞法分析的程式或者函式叫作詞法分析器,也叫掃瞄器。在本程式中,我通過python實現了乙個簡單的詞法分析器,該程式並不包含完整的詞法分析,因為給的例子並不是很難,所以就沒有新增很多,但是道理就是這樣的道理。

/*example*/

b=1\

00101:a=2*(1+3)

if(b>10) then

a=1else if(b>=5) then

a=2else

goto 101

#coding=utf-8

import sys

import string

operator = ['=','+','>=','*','>'] #定義運算子

delimiters = [':','(',')'] #定義界符

#預處理函式,對例程進行預處理,去掉多餘的空格、注釋

def preprocess(file_name):

try: #try except 使程式不會因為異常而中斷

fp_read = open(file_name,'r') #開啟需要分析的檔案

fp_write = open('preprocess.txt','w')

sign = 0 #每當上乙個字元為空格時,將sign變為1,通過這樣來保證每個需要空格的地方不會有多餘的空格

while true:

read = fp_read.readline() #迴圈讀取每一行字元

if not read:

break #如果沒有讀取到任何東西直接結束迴圈

length = len(read) #獲得當前字串的長度

i = -1

while i < length - 1: #迴圈讀取每個字元

i+=1

if read[i] == ' ':

if sign == 1: #讀取到空格,如果sign為1說明上乙個字元也是空格,那個可以忽略當前空格

continue

else: #如果sign不為1,說明上乙個字元不是空格,那麼就輸出當前空格

sign = 1

fp_write.write(' ')

elif read[i] == '\t': #同上讀取到空格的操作,對於水平製表符(tab)同樣輸出為乙個空格,如果已經輸出過乙個空格了那就選擇跳過

if sign == 1:

continue

else:

sign = 1

fp_write.write('')

elif read[i] == '\n': #同上讀取到水平製表符(tab)的操作

if sign == 1:

continue

else:

sign = 1

fp_write.write(' ')

elif read[i] == '/' and read[i+1] == '*': #如果讀取到/* 即注釋

i = i + 2 #從星號之後的第乙個字元開始遍歷直到讀取到下一對注釋

while true:

if read[i] == '*' and read[i+1] == '/':

break

i = i + 1

i = i + 1 #遍歷完之後i停留在左斜槓,所以需要+1達到下乙個字元

elif read[i] == '\\': #如果讀取到續行符,之所以是雙斜槓因為右斜槓是轉義字元,雙右斜槓等於單右斜槓,即續行符

break

else: #除了以上這些就直接輸出字元就好

fp_write.write(read[i])

sign = 0

fp_write.write('#')#在最後輸出乙個井號

except exception:

print('errors')

以上為預處理函式,該函式先開啟需要分析的檔案(**段),然後對多餘的空格進行刪除,去掉續行符,去掉注釋,得到一段精簡的**。

#k:關鍵字 i:識別符號 c:常數 o:運算子 p:界符 l:標號

def process(file_name):

try:

fp_read=open(file_name,'r') #開啟預處理之後得到的檔案

fp_write=open('result.txt','w') #開啟乙個新的檔案,為了將得到的二元式表輸入進去

lines = fp_read.readlines() #依舊是按行讀取

i = -1

for line in lines: #逐行遍歷

length = len(line) #獲得當前行字元長度為了遍歷每個字元

while i < length - 1:

i+=1

if line[i] == ' ': #當前字元為空格,直接跳過

continue

if line[i] in delimiters: #當前字元在最開始定義的界符集中,那麼就直接輸出(p,當前字元)

print('(p,',line[i],')',file=fp_write)

continue

if line[i] in operator: #當前字元在運算子集中

if line[i-1] in operator: #判斷運算子,祥見程式之後注釋(1)

continue

print('(o,',end='',file=fp_write) #end=''實現print不換行,file=fp_write實現將print的內容輸出到檔案中

if line[i+1] in operator:

print(line[i],line[i+1],')',sep='',file=fp_write) #sep=''實現print連續輸出不加空格,為了輸出》=而不是》 =

else:

print(line[i],')',file=fp_write)

continue

if line[i-1].isdigit(): #判斷數字,祥見程式之後注釋(2)

continue

if line[i].isdigit():

t = i

while line[i].isdigit():

i+=1

if line[i] == ':' or line[i] == '#':

print('(l,',end='',file=fp_write)

else:

print('(c,',end='',file=fp_write)

i = t

while line[i].isdigit():

print(line[i],end='',file=fp_write)

i+=1

print(')',file=fp_write)

i-=1

continue

j = 0

while true:

if line[i] == ' ' or line[i] in operator or line[i] in delimiters:

break

else:

j+=1

i+=1

if i > length-1:

break

temp = line[i-j:i]

if temp in key_word:

print('(k,',temp,')',file=fp_write)

else:

if temp == '#':

break

print('(i,',temp,')',file=fp_write)

i-=1

except exception:

print('error')

該函式分析預處理之後的**,並將得到的二元式表輸出到檔案中。

def main():

preprocess('source.txt')

process('preprocess.txt')

if __name__=='__main__':

main()

(i, b )

(o,= )

(c,100)

(l,101)

(p, : )

(i, a )

(o,= )

(c,2)

(o,* )

(p, ( )

(c,1)

(o,+ )

(c,3)

(p, ) )

(k, if )

(p, ( )

(i, b )

(o,> )

(c,10)

(p, ) )

(k, then )

(i, a )

(o,= )

(c,1)

(k, else )

(k, if )

(p, ( )

(i, b )

(o,>=)

(c,5)

(p, ) )

(k, then )

(i, a )

(o,= )

(c,2)

(k, else )

(k, goto )

(l,101)

編譯原理詞法分析

編譯原理實驗一 詞法分析練習 include include include define tokenmax 100 define progmax 1000 define k esc 27 void analytics 詞法分析 void scanner 輸入掃瞄 bool isletter cha...

詞法分析(編譯原理)

詞法分析 英語 lexical analysis 是電腦科學中將字串行轉換為單詞 token 序列的過程。進行詞法分析的程式或者函式叫作詞法分析器 lexical analyzer,簡稱lexer 也叫掃瞄器 scanner 詞法分析器一般以函式的形式存在,供語法分析器呼叫。完成詞法分析任務的程式稱...

編譯原理詞法分析

1 注意識別符號和無符號整數的重複問題,本人採用map解決。2 cin ch自動忽略空白字元。include include include include using namespace std struct pairs int isboundaries char ch return 3 case...