LR(0)分析算法

LL(1)分析算法

从左( L) 向右读入程序,最左(L) 推导,采用一个(1) 前看符号
++ 优点:
– 算法运行高效
– 有现成的工具可用
++缺点:
– 能分析的文法类型受限
– 往往需要文法的改写


自底向上分析算法

研究其中最重要也是最广泛应用的一类
++ LR分析算法(移进-归约算法)
– 算法运行高效
– 有现成的工具可用
++ 这也是目前应该广泛的一类语法分析器的自动生成器中采用的算法
– YACC, bison, CUP, C#yacc, 等


自底向上分析的基本思想

最右推导的逆过程!
这里写图片描述


点记号

为了方便标记语法分析器已经读入了多少输入,我们可以引入一个点记号 •
这里写图片描述


自底向上分析

这里写图片描述

另外的写法

这里写图片描述


生成一个逆序的最右推导

需要两个步骤:
– 移进 一个记号到栈顶上,或者
– 归约 栈顶上的n个符号(某产生式的右部)到左部的非终结符
这里写图片描述
核心的问题:如何确定移进和归约的时机?


算法思想

LR——利用了有记忆能力的自动机

这里写图片描述


LR(0)分析表

这里写图片描述


LR(0)分析算法

这里写图片描述

这里写图片描述


LR(0)分析表构造算法

这里写图片描述


Q=enQueue(C0)
//enQueue——入队
//Q就是作为一个工作表,看哪些状态没有计算过


D=goto(C,x)
//给一个项集(项目集合)C,在读入了一个文法符合(终结符T或非终结符N),它能够到达哪些状态。


goto和closure

这里写图片描述

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
LR(0)语法分析器的构造过程如下: 1. 对文法进行扩展,添加一个新的起始符号和一个新的产生式,使其成为SLR(1)语法。 2. 构造LR(0)自动机,包括所有可能的状态和转换。 3. 对于每个状态,计算LR(0)项目集并构造相应的分析表。对于每个项目,如果其后面有一个非终结符,则添加一个新的项目到项目集中。 4. 使用构造的分析表对输入的符号串进行分析,最终得到语法分析结果。 以下是一个示例文法和其LR(0)分析器的Python实现: 文法: S -> E E -> E + T | T T -> T * F | F F -> ( E ) | id LR(0)分析器实现: ```python # 定义文法 grammar = { 'S': ['E'], 'E': ['E + T', 'T'], 'T': ['T * F', 'F'], 'F': ['( E )', 'id'] } # 构造LR(0)自动机 def closure(items, grammar): """ 计算LR(0)项目集闭包 """ while True: new_items = items.copy() for item in items: pos = item.index('.') if pos == len(item) - 1: continue symbol = item[pos+1] if symbol in grammar: for production in grammar[symbol]: new_item = symbol + '->.' + production if new_item not in new_items: new_items.append(new_item) if new_items == items: break items = new_items return items def goto(items, symbol, grammar): """ 计算LR(0)项目集的GOTO集合 """ new_items = [] for item in items: pos = item.index('.') if pos == len(item) - 1: continue if item[pos+1] == symbol: new_item = item[:pos] + symbol + '.' + item[pos+2:] new_items.append(new_item) return closure(new_items, grammar) def construct_lr0_automaton(grammar): """ 构造LR(0)自动机 """ automaton = {} start_item = 'S->.E' start_state = closure([start_item], grammar) automaton[0] = start_state state_count = 1 state_dict = {str(start_state): 0} state_queue = [start_state] while state_queue: state = state_queue.pop(0) for symbol in grammar.keys(): next_state = goto(state, symbol, grammar) if not next_state: continue if str(next_state) not in state_dict: state_dict[str(next_state)] = state_count automaton[state_count] = next_state state_queue.append(next_state) state_count += 1 automaton[state_dict[str(state)]][symbol] = state_dict[str(next_state)] return automaton # 构造LR(0)分析表 def construct_lr0_table(automaton, grammar): """ 构造LR(0)分析表 """ table = {} for state, items in automaton.items(): for item in items: pos = item.index('.') if pos == len(item) - 1: for i, symbol in enumerate(grammar.keys()): if symbol == item[0]: table[(state, symbol)] = ('acc', None) break continue symbol = item[pos+1] if symbol in grammar: goto_state = automaton[state][symbol] table[(state, symbol)] = ('shift', goto_state) else: for production in grammar[item[0]]: if production == 'epsilon': follow_set = grammar[item[0]] else: follow_set = set(production) for follow_symbol in follow_set: table[(state, follow_symbol)] = ('reduce', item[0]+'->'+production) return table # LR(0)分析器 def lr0_parser(input_string, automaton, table): """ LR(0)分析器 """ input_list = input_string.split() stack = [0] output = [] input_pos = 0 while True: state = stack[-1] symbol = input_list[input_pos] if input_pos < len(input_list) else '$' action, value = table.get((state, symbol), (None, None)) if action == 'shift': stack.append(value) input_pos += 1 elif action == 'reduce': production = value lhs, rhs = production.split('->') rhs_len = len(rhs) for i in range(rhs_len): stack.pop() state = stack[-1] stack.append(automaton[state][lhs]) output.append(production) elif action == 'acc': return output else: raise ValueError('Invalid input string') ``` 使用示例: ```python automaton = construct_lr0_automaton(grammar) table = construct_lr0_table(automaton, grammar) input_string = 'id + id * id' output = lr0_parser(input_string, automaton, table) print(output) # ['S->E', 'E->T', 'T->F', 'F->id', 'T->T*F', 'F->id', 'E->E+T', 'T->T*F', 'F->id'] ``` 以上就是LR(0)分析器的构造过程和Python实现,希望对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值