编译原理13:SLR(1)分析表、LR(1)分析表

更强的LR分析

可以根据当前单词,来选择是移进还是归约。只要所有移进项目中的点后面的那些终结符,与归约项目生成的非终结符的Follow集合的元素没有重叠。若当前单词属于上述Follow集合里则规约


SLR(1)冲突解决办法


SLR(1)分析表的构造


SLR(1)分析表的构造示例

拿上面那个例子:

 

 我们来看看状态1的情况,状态1里面有两个项目:一个是规约项目,一个是移进项目,因此有冲突,检查一下要规约生成的S‘的Follow集合,里面有#,所以说这个规约项目告诉我们,在1状态面临#的时候,应该选择规约,这个规约又是接受项目,填入整个分析结束的接受标志acc;二第二个项目告诉我们这是个移进项目,从I1出发,识别+后,DFA告诉我们应该转入状态6,所以在对应位置填上s6。

总之,状态1里有一个规约项目,有一个移进项目,但是通过检查Follow集合,我们把这两个动作区分开来,没有造成冲突。状态2和状态9都类似。

分析状态1:

 分析状态2:

 


一个非SLR(1)文法

 

状态2中有移进规约冲突,查看Follow(R),里面有=,而=又刚好是移进项目中·后面的符号,以这个文法不是SLR(1)。

但状态2处于分析栈的栈顶,而面临符号是=时,并不能对栈顶L进行规约。因为没有以“R=”为前缀的规范句型,只有以“*R=”为前缀的规范句型(I7和I2)


LR(1)有效项目


LR(1)分析表构造


【LR(1)分析表的构造示例】

注意如何添加展望信息


分析器产生工具


小结

 

编译原理中,完成SLR(1)分析的任务涉及几个关键步骤:读取文法、构造分析表、读取句子并识别。这是一个简单的Python示例,假设你已经有了一个用于解析的文法和一个基本的分析工具包: ```python import re from collections import defaultdict # 假设你已经定义了以下文法规则: # S -> A B C # A -> a # B -> b # C -> c class Item: def __init__(self, symbol, state, lookahead): self.symbol = symbol self.state = state self.lookahead = lookahead class Grammar: def __init__(self, start, rules): self.start = start self.rules = rules def get_items(self, state, terminal): items = [] for rule in self.rules: if rule[0] == state and terminal == rule[1:]: items.append(Item(state, '', terminal)) return items def build_goto_table(grammar): goto = defaultdict(list) for rule in grammar.rules: for i in range(1, len(rule)): item = Item('', '', rule[:i]) goto[item].append(item.copy() + Item(rule[i], '', '')) # Shift操作 return goto def build_reduce_table(grammar): reduce = defaultdict(list) for rule in grammar.rules: reduce[rule[0]].append(rule[1:]) # Reduce操作 return reduce def is_valid(grammar, sentence): start_item = Item(grammar.start, '', '') states = {start_item} tokens = re.findall(r'\w+', sentence) for token in tokens: next_items = set() for item in states: if item.symbol in grammar.rules: for new_item in grammar.get_items(item.symbol, token): next_items.add(new_item) elif item.lookahead and item.lookahead[0] == token: new_item = item.copy() + Item('', '', '') next_items.add(new_item) states.clear() states.update(next_items) return len(states) == 1 and start_item in states if __name__ == "__main__": with open("grammar.txt", "r") as f: grammar_str = f.read().splitlines() start, rules = grammar_str[0].split(" -> ") rules = [(symbol, rest.split()) for symbol, rest in map(str.strip, rules[1:].split("\n"))] grammar = Grammar(start, rules) goto_table = build_goto_table(grammar) reduce_table = build_reduce_table(grammar) sentence = "a b c" print(f"Is '{sentence}' valid according to the grammar? {is_valid(grammar, sentence)}") # 上述代码只是一个简化版本,实际中可能还需要处理更复杂的文法结构和错误处理。 ``` 这个示例展示了如何读入文法、构建分析表,以及判断一个给定的句子是否符合文法。请注意,这个例子假定了文法已经是SLR(1)兼容的,并且只适用于这种简单的情况。实际项目中可能需要更复杂的解析算法来处理复杂文法和错误处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值