コンパイル原理実験一:簡単な文法分析


一、実験目的
文法分析プログラムの基本構造原理を理解し、文法分析プログラムの手作業構造方法を把握する.
二、実験内容
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、一定量の説明に従って、高級言語ソースプログラムに直列に置かれた場合に発生する可能性のあるエラー状況を説明し、高級言語コンパイラを真似て異なるエラー状況に対して相応の処理を行う.
import sys
import re

keywords = ['const']


def to_split(str):
    str = str.strip()
    f = 0
    while True:
        if str[-1] == ';':
            str = str[:-1]
            f = 1
        else:
            if f == 1:
                break
            else:
                print("    ;
") sys.exit() # str_list = str.split(',') all = re.finditer(',[^\"\'=]{1,100}=', str) list_dou = [] for i in all: list_dou.append(i.span()[0]) str2 = list(str) a = "" for i in range(len(str)): if i in list_dou: a = a + '!@#123$%^&*' else: a = a + str[i] str = a.split('!@#123$%^&*') return str def get_type(str): str = str.strip() global int_num global char_num global string_num global float_num name_word = "" type_word = "" value_word = "" # p = , index_dengyu = str.find("=") if index_dengyu == -1: print(" =
") sys.exit() # = str_left = str[:index_dengyu].strip() str_right = str[index_dengyu + 1:].strip() # = # = , '', str_left_list = str_left.split(' ') temp = [] for i in str_left_list: if i != '': temp.append(i) str_left_list = temp if len(str_left_list) == 1: name_word = str_left_list[0] # if name_word[0].isalpha() is False: print("%s( ! !)
" % str_left_list[0]) return 0 elif len(str_left_list) == 2: if str_left_list[0] in keywords: name_word = str_left_list[1] if name_word[0].isalpha() is False: print("%s( ! !)
" % str_left_list[1]) return 0 else: print("%s !
" % str_left_list[0]) sys.exit(); # if str_right[0] == '.': type_word = "float" float_num = float_num + 1 value_word = str_right elif str_right[0] == '\'' and str_right[-1] == '\'': if len(str_right) != 3: print("%s( ! !)
" % name_word) return 0 type_word = "char" char_num = char_num + 1 value_word = str_right else: try: try: type_word = "integer" value_word = int(str_right) int_num = int_num + 1 except: type_word = "float" value_word = float(str_right) float_num = float_num + 1 except: if str_right[0] != '\"' and str_right[-1] != '\"': print("%s( ! !)
" % name_word) return 0 type_word = "string" string_num = string_num + 1 value_word = str_right print("%s(%s,%s)
" % (name_word, type_word, value_word)) str = """ const count1 = 2180,sum1 = 6881.655,char1='f', count2=65,max1=169,char2='@',sum2=.0815,str1="\"cds f 89h\"", max2=1.6229,str2="good jbhn"; """ str_list = to_split(str) int_num = 0 char_num = 0 string_num = 0 float_num = 0 # str_list = ["const count1 = 2180"] for i in str_list: get_type(i) print(("int_num = %s,char_num = %s,string_num = %s,float_num = %s
" \ % (int_num, char_num, string_num, float_num)))