python 预备实验1文法的读入和输出 编译原理

本文章实现内容:

1、设计一个表示文法的数据结构;
2、从文本文件中读入文法,利用定义的数据结构存放文法,并输出

编辑一个文本文文件g.txt,在文件中输入如下内容:

S->Qc;
S->c;
Q->Rb;
Q->b;
R->Sa;
R->a;

上述文法整理后的输出形式: 

S->Qc|c;
Q->Rb|b;
R->Sa|a;

 同样支持这样的输入:

S->Qc|c|cc|da|Q1
Q->Rb|b|V
R->Sa|a|cV2
Q1->aa|bd
V2->d|Q2
Q2->a
V->V2|e

结果:

S->Qc|c|cc|da|Q1;
Q->Rb|b|V;
R->Sa|a|cV2;
Q1->aa|bd;
V2->d|Q2;
Q2->a;
V->V2|e;

代码如下:

def GetGrammar(grammar):  # 输出文法
    global non_terminator, production
    for i in grammar[non_terminator]:  # 遍历非终结符
        print(i + '->', end='')  # 前部
        for j in range(len(grammar[production][i])):  # 根据非终结符遍历该终结符的产生式
            if j > 0:
                print('|', end='')
            for k in grammar[production][i][j]:
                print(k, end='')
        print(';')


def LongStr(sting, list_data):  # 从列表中寻找匹配最长的项
    maxlen = 0  # 最长的匹配字符串长度
    maxstr = -1  # 匹配的最长字符串位置
    for i in range(len(list_data)):  # 遍历
        if sting.startswith(list_data[i]):  # 判断字符串是否以list[i]开头
            leni = len(list_data[i])
            if leni > maxlen:  # 如果新匹配字符串比原来长,替换
                maxlen = leni
                maxstr = i
    return maxlen, maxstr


def PrimaryTreatment(grammar):  # 初步处理,使得产生式内部分开
    global non_terminator, production
    for i in grammar[non_terminator]:  # 遍历非终结符
        for j in range(len(grammar[production][i])):  # 根据非终结符遍历该终结符的产生式
            k = 0  # 所处位置指针
            str_production = grammar[production][i][j][0]  # 产生式字符串
            new_production = []  # 准备存初步处理后的产生式
            while k < len(str_production):
                maxlen, maxstr = LongStr(str_production, grammar[non_terminator])  # 寻找匹配最长的终结符
                if maxlen == 0:  # 没找到
                    new_production.append(str_production[k])  # 分出一个终结符
                    k += 1
                else:  # 找到了
                    new_production.append(str_production[k:k + maxlen])  # 分出一个非终结符
                    k += maxlen
            grammar[production][i][j] = new_production  # 产生式替换
            pass


def OpenGrammar(file):  # 从文件中打开(读取)文法。并作初级处理(产生式中各个非终结符和终结符分开)
    global non_terminator, production
    file = open(file)  # 读取文件
    non_terminator = '非终结符'
    production = '产生式'
    grammar = {non_terminator: [], production: {}}
    while i := file.readline():  # 一行一行的读取,并赋值给i
        for j in range(len(i)):  # 遍历i中每一个字符
            if i[j] == '-' and i[j + 1] == '>':  # 分割前面的字符就是非终结符
                if not i[0:j] in grammar[non_terminator]:  # 该非终结符还没有记录
                    grammar[non_terminator].append(i[0:j])  # 加入进去
                    grammar[production][i[0:j]] = []
                k = j + 2  # 直达产生式右部第一个字符
                for l in range(len(i)+1):   # +1是为了处理最后一行又不带分号又不带回车的情况
                    # 这里由于用了断路特性即l == len(i)成立后不会运行后面的,从而不会产生数组越界报错
                    if l == len(i) or i[l] == ';' or i[l] == '\n':  # 往后找到最后一个,结束
                        grammar[production][i[0:j]].append([i[k:l]])  # 添加到后面
                        break
                    if i[l] == '|':  # 遇到了中断
                        grammar[production][i[0:j]].append([i[k:l]])  # 添加到后面
                        k = l + 1  # 并且左边标记右移
                break
    file.close()
    PrimaryTreatment(grammar)
    return grammar


global non_terminator, production
file = 'g.txt'  # 文件位置
grammar = OpenGrammar(file)
GetGrammar(grammar)

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 合肥工业大学编译原理实验1是一个词法分析程序实验,使用Python语言进行编写。 词法分析是编译原理中的一个重要内容,主要负责将源代码文件中的字符序列分割成有意义的词法单元,如标识符、关键字、运算符、分隔符等,为后续的语法分析和语义分析做好准备。 Python语言由于其简洁易学和强大的功能,成为许多编译原理实验的首选语言之一。在这个实验中,我们将使用Python编写一个词法分析程序,实现对源代码的分析。 首先,我们需要读取源代码文件,将其转换为字符流,传递给词法分析程序。程序会逐个读取字符,并根据事先定义好的正则表达式进行匹配,识别出相应的词法单元。 实验中可能会用到的一些正则表达式包括:匹配标识符的正则表达式、匹配关键字的正则表达式、匹配运算符的正则表达式、匹配数值常量的正则表达式等。 在识别出词法单元后,程序会生成一个词法单元表,记录下每个词法单元的型和对应的值。该词法单元表将作为语法分析的输入。 在编写这个词法分析程序时,需要注意处理多种可能的错误情况,如不合法的字符、不符合规范的标识符等。可以通过添加捕获异常的机制来处理这些错误情况,并及时进行提示。 综上所述,通过本次实验,我们可以学习到编译原理中词法分析的基本概念和原理,并通过实践来深入理解。通过使用Python语言编写词法分析程序,我们能够更好地掌握Python语言的特性和应用。 ### 回答2: 编译原理实验一是词法分析程序实验,要求使用Python语言编写程序。本实验的主要目的是通过实现词法分析器,能够将输入的源代码分解成一个个的词法单元。在合肥工业大学编译原理实验一的词法分析程序实验中,我们需要实现以下功能: 1. 识别并分各种型的词法单元,比如标识符、数字、关键字、运算符、界符等。 2. 跳过空格、换行符和注释等不影响程序执行的字符。 3. 输出每个词法单元的型和值,方便后续程序分析和处理。 为了完成这个实验,我们可以使用Python语言提供的字符串处理函数和正则表达式库来帮助我们实现上述功能。下面是一个简单的实现示例: ```python import re def lexer(code): # 定义正则表达式,用于识别各种型的词法单元 keywords = ['if', 'else', 'while', 'for', 'int', 'float', 'char'] # 关键字 operators = ['+', '-', '*', '/', '=', '==', '!=', '<', '>', '<=', '>='] # 运算符 delimiters = [';', '(', ')', '{', '}'] # 界符 pattern_keywords = '|'.join(keywords) pattern_operators = '|'.join(re.escape(op) for op in operators) pattern_delimiters = '|'.join(re.escape(dl) for dl in delimiters) pattern = f'({pattern_keywords})|({pattern_operators})|({pattern_delimiters})|\w+|\d+' # 开始词法分析 tokens = re.findall(pattern, code) for token in tokens: if token[0]: print(f'关键字:{token[0]}') elif token[1]: print(f'运算符:{token[1]}') elif token[2]: print(f'界符:{token[2]}') elif token[3]: print(f'标识符:{token[3]}') elif token[4]: print(f'数字:{token[4]}') # 测试代码 code = ''' int main() { int a = 10; if (a > 0) { a = a - 1; } return 0; } ''' lexer(code) ``` 以上是一个简单的词法分析程序实验的实现示例,通过使用正则表达式来识别各种词法单元,并打印出每个词法单元的型和值。实验中可以根据具体需求扩展代码,添加更多的词法单元型和识别规则。 ### 回答3: 合肥工业大学编译原理实验1是关于词法分析程序的实验。词法分析是编译过程中的第一个步骤,主要任务是将源代码分解为一个个的词法单元。在这个实验中,使用Python编写词法分析程序。 在开始编写程序之前,首先需要明确程序的功能和输入输出要求。根据实验要求,我们需要编写一个可以识别并输出源代码中的各个词法单元的程序。 编写词法分析程序的基本思路如下: 1. 读取源代码文件,将其按照字符进行分解; 2. 针对每一个字符,判断其所属的词法单元型; 3. 将每个词法单元及其输出。 在Python中,可以利用正则表达式来匹配词法单元的模式。通过定义适当的正则表达式,可以方便地判断当前字符所属的词法单元型。可以考虑使用re模块来处理正则表达式。 实验的输入是一个源代码文件,首先需要使用Python的文件操作来读取源文件的内容。之后,可以利用re模块的正则表达式相关函数,对每个字符进行匹配和识别。最后,将每个词法单元及其输出一个文件中。 编写完程序后,可以使用一些示例的源代码文件进行测试,验证程序的正确性。如果发现有问题,可以通过调试和修改代码来改进程序的逻辑和功能。 总之,合肥工业大学编译原理实验1词法分析程序实验使用Python编写,通过正则表达式对源代码进行分析和识别,并将每个词法单元及其输出一个文件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值