【编译原理】第四章总结

思维导图

在这里插入图片描述

总结

语法分析的功能和任务

  • 功能:根据文法规则,从源程序单词符号串中识别出语法成分,并进行语法检查
  • 基本任务:识别符号串S是否为某语法成分

自顶向下分析算法的基本思想

  • 基本思想:
    在这里插入图片描述
  • 例题:
    在这里插入图片描述
  • 一般过程:
    给定符号串S,若预测是某一语法成分,则可根据该语法成分的文法,设法为S构造一棵语法树,若成功,则S最终被识别为某一语法成分,即
    在这里插入图片描述
    其中G[Z]为某语法成分的文法。若不成功, 则
    在这里插入图片描述
  • 特点:
    1、分析过程是带预测的,对输入符号串要预测属于什么语法成分,然后根据该语法成分的文法建立语法树。
    2、分析过程是一种试探过程,是尽一切办法(选用不同规则) 来建立语法树的过程, 由于是试探过程, 难免有失败, 所以分析过程需进行回溯, 因此也称这种方法是带回溯的自顶向下分析方法。
    3、最左推导可以编写程序来实现, 但带回溯的自顶向下分析方法在实际上价值不大, 效率低。
  • 主要方法:
    1、递归子程序法
    2、LL分析法
  • 主要问题:
    1、左递归问题
    2、回溯问题

自顶向下语法分析中,消除左递归和回溯

消除左递归文法

在这里插入图片描述

消除直接左递归
  • 扩充BNF表示法来改写文法:
    规则一(提因子)
    若:U∷=xy|xw|….|xz
    则可改写为:U∷=x(y|w|….|z)
    若:y=y1y2, w=y1w2
    则U∷=x(y1(y2|w2)|….|z)
    在这里插入图片描述
    规则二
    若有文法规则:U∷=x|y|……|z|Uv
    在这里插入图片描述在这里插入图片描述
  • 将左递归规则改为右递归规则
    规则三
    在这里插入图片描述
  • 总结
    在这里插入图片描述
消除 一般左递归
  • 把G的非终结符整理成某种顺序A1, A2, ……An, 使得:
    A1 ::= δ1|δ2|……|δk
    A2 ::= A1 r……
    A3 ::= A2u | A1v……
    …….
  • For i:=1 to n do
    begin
    for j:=1 to i-1 do
    把每个形如Ai∷=Ajr的规则替换成
    Ai ∷=(δ1|δ2|……|δk) r ,
    其中Aj ∷=δ1|δ2|……|δk是当前全部Aj 的规则;
    消除Ai规则中的直接左递归
    end
  • 化简由2得到的文法
  • 例题
    在这里插入图片描述

回溯问题

在这里插入图片描述

  • 消除回溯的途径:
    1、改写文法
    对具有多个右部的规则反复提取左因子
    2、超前扫描
    当文法不满足避免回溯的条件时,即各选择的首符号相交时,可以采用超前扫描的方法,即向前侦察各输入符号串的第二个、第三个符号来确定要选择的目标
  • 充分必要条件:
    在这里插入图片描述在这里插入图片描述

自底向上分析算法的基本思想

  • 基本思想:
    在这里插入图片描述
  • 主要方法:
    1、算符优先分析法
    2、LR分析法
  • 主要问题:
    句柄的识别问题

递归下降分析法

  • 具体做法:
    对语法的每一个非终结符都编一个分析程序,当根据文法和当时的输入符号预测到要用某个非终结符去匹配输入串时,就调用该非终结符的分析程序
  • 具体过程:
    在这里插入图片描述1、
    在这里插入图片描述2、
    在这里插入图片描述
    3、算法框图/编写非终结符的分析函数
    非终结符号的分析子程序的功能是:用规则右部符号串去匹配输入串
    Z∷=‘(’U‘)’|aUb子程序:
    在这里插入图片描述
    U∷=(dZ|e){d}子程序:
    在这里插入图片描述
  • 例子:
    在这里插入图片描述
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Python Tkinter GUI实现任意文法消除左递归和回溯算法的示例代码: ```python from tkinter import * # Function to eliminate left recursion from grammar def eliminate_left_recursion(grammar): non_terminals = list(grammar.keys()) for i in range(len(non_terminals)): for j in range(i): A = non_terminals[i] B = non_terminals[j] productions = grammar[A] new_productions = [] old_productions = [] for production in productions: if production.startswith(B): new_productions.append(production[1:] + A + "'") else: old_productions.append(production + A + "'") if new_productions: grammar[A] = old_productions grammar[A + "'"] = new_productions return grammar # Function to eliminate left recursion and left factoring from grammar def eliminate_left_recursion_and_left_factoring(grammar): # Eliminate left recursion first non_terminals = list(grammar.keys()) for i in range(len(non_terminals)): for j in range(i): A = non_terminals[i] B = non_terminals[j] productions = grammar[A] new_productions = [] old_productions = [] for production in productions: if production.startswith(B): new_productions.append(production[1:] + A + "'") else: old_productions.append(production + A + "'") if new_productions: grammar[A] = old_productions grammar[A + "'"] = new_productions # Eliminate left factoring next non_terminals = list(grammar.keys()) for A in non_terminals: productions = grammar[A] new_productions = [] old_productions = [] while len(productions) > 1: alpha = set() for production in productions: alpha.add(production[0]) common_prefix = '' for i in range(len(productions[0])): if all(production[i] == productions[0][i] for production in productions): common_prefix += productions[0][i] else: break if common_prefix: new_non_terminal = A + "'" new_production = common_prefix + new_non_terminal new_productions.append(new_production) old_productions = [production[len(common_prefix):] for production in productions] old_productions.append('') grammar[A] = old_productions grammar[new_non_terminal] = new_productions productions = old_productions else: new_productions.append(productions.pop(0)) if productions: new_productions.append(productions[0]) grammar[A] = new_productions return grammar # Function to display the grammar in the GUI def display_grammar(grammar, text_widget): text_widget.delete(1.0, END) for non_terminal, productions in grammar.items(): text_widget.insert(END, non_terminal + " -> ") for production in productions: text_widget.insert(END, production + " | ") text_widget.delete("end-2c", "end") text_widget.insert(END, "\n") # Function to handle button click event def handle_click(grammar_textbox, result_textbox, eliminate_left_recursion_var, eliminate_left_factoring_var): # Parse the grammar input input_text = grammar_textbox.get(1.0, END).strip() grammar = {} for line in input_text.split('\n'): non_terminal, productions = line.split(' -> ') grammar[non_terminal] = [p.strip() for p in productions.split('|')] # Eliminate left recursion and/or left factoring as requested if eliminate_left_recursion_var.get(): grammar = eliminate_left_recursion(grammar) if eliminate_left_factoring_var.get(): grammar = eliminate_left_recursion_and_left_factoring(grammar) # Display the result display_grammar(grammar, result_textbox) # Create the GUI root = Tk() root.title("Eliminate Left Recursion and Left Factoring") # Create the input box for the grammar grammar_label = Label(root, text="Enter the grammar:") grammar_label.pack() grammar_textbox = Text(root, height=10) grammar_textbox.pack() # Create the checkboxes for left recursion and left factoring eliminate_left_recursion_var = BooleanVar() eliminate_left_recursion_checkbox = Checkbutton(root, text="Eliminate Left Recursion", variable=eliminate_left_recursion_var) eliminate_left_recursion_checkbox.pack() eliminate_left_factoring_var = BooleanVar() eliminate_left_factoring_checkbox = Checkbutton(root, text="Eliminate Left Factoring", variable=eliminate_left_factoring_var) eliminate_left_factoring_checkbox.pack() # Create the button to perform the elimination eliminate_button = Button(root, text="Eliminate", command=lambda: handle_click(grammar_textbox, result_textbox, eliminate_left_recursion_var, eliminate_left_factoring_var)) eliminate_button.pack() # Create the output box for the result result_label = Label(root, text="Result:") result_label.pack() result_textbox = Text(root, height=10) result_textbox.pack() # Start the GUI root.mainloop() ``` 该程序使用Tkinter库创建了一个简单的GUI窗口,其中包含一个文本框用于输入文法,两个复选框用于选择要执行的算法,一个按钮用于执行算法,并且另一个文本框用于显示结果。 算法本身实现为两个函数,一个用于仅消除左递归,另一个用于同时消除左递归和左公共因子。这些函数接受一个文法字典作为输入,并返回一个修改后的文法字典作为输出。 处理点击事件的函数从输入文本框中解析文法,根据复选框的状态选择要执行的算法,并将结果显示在输出文本框中。 最后,使用mainloop()函数启动GUI。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值