編譯原理實驗 識別標識符


實驗環境:Python3.6

實驗目的

  • 根據 PL/0 語言的文法規范,編寫 PL/0 語言的標識符識別程序。
  • 通過設計調試標識符識別程序,實現從源程序中分出各個標識符的方法;加深對課堂教學的理解; 為后序詞法分析程序的實現打下基礎 。
  • 掌握從源程序文件中讀取有效字符的方法和產生源程序的內部表示文件的法。
  • 掌握識別標識符的實現方法。
  • 上機調試完成的識別標識符程序的實現。

實驗時間

2學時

實驗內容

上機調試完成的識別標識符程序的實現。

實驗要求

  • 識別程序讀入 PL/0 語言源程序(文本文件),識別結果也以文本文件保存 。
  • 按標識符出現的順序輸出結果, 每個標識符一行, 采用二元式序列,即: (標識符值, 標識符出現次數)
  • 源程序中字符不區分大小寫,即:“a1” 和“A1” 是同一個標識符。
  • 准備至少 5 組測試用例,每組測試用例包括:輸入源程序文件和輸出結果。
  • 測試用例應該考慮各種合法標識符的組合情況。

輸入輸出樣例

輸入文件

Const num=100;
Var a1,b2;
Begin
	Read(A1);
	b2:=a1+num;
	write(A1,B2);
End.

輸出:(文本文件)

(num: 2)

(a1: 4)

(b2: 3)

實驗內容

實驗思路

PL/0程序中有兩種標識符定義關鍵字varconst,procedure,利用這三種關鍵字識別標識符,將標識符存儲在一個數組中,之后再根據數組中的標識符進行正則匹配,查找程序中出現了多少次此標識符。本實驗的程序使用python編寫。

實驗代碼解析

# 導入庫,正則匹配需要
import re

# 定義符數組
dingyi = ['var', 'const', 'procedure']
# 計數字典
count = {}
# 程序分割后的語句
yuju = []
# 標識符存儲數組
bianliang = []
# 存儲語句的數組
a = []

# 讀文件操作
with open("input.txt") as f:
    # 將字符全部轉為小寫
    content = f.read().lower().split('\n')
    for c in content:
        c = c.strip()
        # 去除注釋
        if len(c) != 0:
            if c[0] == '{':
                continue
            # 判斷字符串定義
            if c[0:3] == 'var' or c[0:5] == 'const' or c[0:9] == 'procedure':
                if 'var' in c:
                    c = c.replace('var ', '')
                if 'const' in c:
                    c = c.replace('const ', '')
                elif 'procedure' in c:
                    c = c.replace('procedure', '')
                c.replace(' ', '')
                con = c.split(',')
                for cd in con:
                    x = cd.split('=')
                    count[x[0].rstrip(";").replace(' ', '')] = 0
                    # 存儲字符串
                    bianliang.append(x[0].rstrip(";").replace(' ', ''))
    for c in content:
        # 去除字符左右兩邊的空格
        c = c.strip()
        if len(c) != 0:
            # 去除注釋
            if c[0] == '{':
                continue
            for b in bianliang:
                # 正則匹配  [^a-z]為非字母
                matchObj = re.match(r'.*[^a-z]' + b + '[^a-z^0-9]', c, re.M | re.I)
                a = -1
                while matchObj:
                    count[b] = count[b] + 1
                    a = matchObj.end() - 2
                    matchObj = re.match(r'.*[^a-z]' + b + '[^a-z^0-9]', c[:matchObj.end() - 2], re.M | re.I)
                matchObj = re.match(r'' + b + '[^a-z^0-9]', c[:a], re.M | re.I)
                while matchObj:
                    count[b] = count[b] + 1
                    matchObj = re.match(r'' + b + '[^a-z^0-9]', c[:matchObj.end() - 2], re.M | re.I)
# 寫入文件操作
with open("output.txt", 'w') as f:
    for i in bianliang:
        f.write("(" + i + ":\t" + str(count[i]) + ")\n")

測試用例

測試用例一

var a, b, c, r;
{ 將a, b, c排序 }
begin
	read(a);
	read(b);
	read(c);
	if a > b then
		begin
			r := a;
			a := b;
			b := r;
		end;
	if b > c then
		begin
			r := b;
			b := c;
			c := r;
		end;
	if a > b then
		begin
			r := a;
			a := b;
			b := r;
		end;
	write(a);
	write(b);
	write(c);
end.

測試用例二

var a, b, c, flag, x, y, z, flag2, flag3;
const yiban=0, dengyao = 1, dengyaozhijiao = 2, zhijiao=3, dengbian=4, fei=5;
procedure dyzhijiao;
	begin
		if 2 * x * x = y * y then
            begin
                write(dengyaozhijiao);
                flag2 := 1;
                flag := 1;
            end;
		if flag2 # 1 then
            begin
                write(dengyao);
                flag := 1;
            end;
	end;
beigin
	call dyzhijiao;
end.

測試用例三

var a, b, c, flag, x, y, z, flag2, flag3;
const yiban=0, dengyao = 1, dengyaozhijiao = 2, zhijiao=3, dengbian=4, fei=5;
	begin
		if x*x + y*y = z*z then
            begin
                write(zhijiao);
                flag := 1;
            end;
	end;

測試用例四

var a, b, c, flag, x, y, z, flag2, flag3;
const yiban=0, dengyao = 1, dengyaozhijiao = 2, zhijiao=3, dengbian=4, fei=5;
begin
    if a+b>c then
    	begin
    		if a+c>b then
    			begin
    				if b+c>a then
    					begin
                            flag3 := 1;
                            if  a = b then
                                begin
                                    if b = c then
                                        begin
                                            write(dengbian);
                                            flag := 1;
                                        end;
                                end;
                            if flag # 1 then
                                begin
                                    if a = b then
                                        begin
                                            x := a;y := c;
                                            call dyzhijiao;
                                        end;
                                    if c = b then
                                        begin
                                            x := b;y := a;
                                            call dyzhijiao;
                                        end;
                                    if a = c then
                                        begin
                                            x := a;y := b;
                                            call dyzhijiao;
                                        end;
                                    if flag # 1 then
                                        begin
                                            x:=a;y:=b;z:=c;
                                            call zhijiao;
                                            x:=a;y:=c;z:=b;
                                            call zhijiao;
                                            x:=c;y:=b;z:=a;
                                            call zhijiao;
                                        end;
                                        if flag # 1 then
                                            begin
                                                wirte(yiban)
                                            end;
                                end;
                        end;
    			end;
    	end;

測試用例五

var flag3;
const yiban=0, dengyao = 1, dengyaozhijiao = 2, zhijiao=3, dengbian=4, fei=5;
if flag3 # 1 then
    	begin
    		write(fei)
    	end;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM