SLR(1)分析法

SLR(1)分析法是一种解决LR(0)文法中冲突的简单确定性分析方法,通过向前查看一个输入符号来确定分析动作。当遇到冲突时,根据FOLLOW集合判断移进或规约。SLR(1)分析表的构造过程与LR(0)类似,但针对规约项目会考虑FOLLOW集合,以避免冲突。
摘要由CSDN通过智能技术生成


LR(0)文法要求文法的每一个LR(0)项目都不含有冲突的项目,这个条件比较苛刻。对于大多数程序设计语言来说,一般都不能满足LR(0)文法的条件。

例如:

在这里插入图片描述

不难看出在状态 I 2 I_2 I2中既存在规约项目,又存在移进项目,因而这个文法不是LR(0)文法。

为了对语言句子进行确定性的分析,需要解决冲突。可以采用对含有冲突的项目集向前查看一个输入符号的办法来解决冲突,这种分析法称为简单的LR分析法,即SLR(1)分析法。

分析构造LR(0)分析表的方法,易看出是分析表出现多重定义的原因在于其中的规则2。即对于每一个项目集 I k I_k Ik中的规约项目 A → α ⋅ A\rightarrow{\alpha·} Aα,不管当前输入符号是什么,都将ACTION表中第k行的各个元素均置为 r j r_j rj

因此当一个LR(0)项目集闺范族中存在一个含有冲突的项目集,例如:

I k = { X → δ ⋅ b B , A → α ⋅ , B → r ⋅ } I_k = \{X \rightarrow{\delta·bB,A\rightarrow{\alpha·},B\rightarrow{r·}}\}

  • 23
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
SLR(1)分析法是一种自底向上的语法分析方法,可以通过一个确定性有限自动机(DFA)来实现。以下是一个简单的SLR(1)分析器的C++代码示例: ```cpp #include <iostream> #include <stack> #include <vector> #include <unordered_map> using namespace std; // 语法规则 struct Production { char lhs; // 左部 string rhs; // 右部 Production(char lhs, string rhs) : lhs(lhs), rhs(rhs) {} }; // LR(0) 项 struct Item { Production prod; // 产生式 int dot; // 点的位置 Item(Production prod, int dot = 0) : prod(prod), dot(dot) {} // 判断两个项是否相等 bool operator==(const Item& other) const { return prod.lhs == other.prod.lhs && prod.rhs == other.prod.rhs && dot == other.dot; } }; // 计算闭包 void closure(Item item, const vector<Production>& prods, unordered_map<char, vector<Item>>& items) { // 初始状态 items[item.prod.lhs].push_back(item); // 计算闭包 stack<Item> stk; stk.push(item); while (!stk.empty()) { Item cur = stk.top(); stk.pop(); if (cur.dot < cur.prod.rhs.size()) { // 当前项还有符号未处理 char next_sym = cur.prod.rhs[cur.dot]; if (isupper(next_sym)) { // 下一个符号是非终结符 for (Production prod : prods) { if (prod.lhs == next_sym) { // 找到所有以该符号为左部的产生式 Item next_item(prod, 0); if (find(items[next_item.prod.lhs].begin(), items[next_item.prod.lhs].end(), next_item) == items[next_item.prod.lhs].end()) { items[next_item.prod.lhs].push_back(next_item); stk.push(next_item); } } } } } } } // 计算GOTO函数 unordered_map<char, unordered_map<char, vector<Item>>> goto_func(const vector<Production>& prods, const unordered_map<char, vector<Item>>& items) { // 初始化GOTO unordered_map<char, unordered_map<char, vector<Item>>> goto_map; for (auto& item_list : items) { char lhs = item_list.first; for (Item item : item_list.second) { if (item.dot < item.prod.rhs.size()) { char next_sym = item.prod.rhs[item.dot]; if (goto_map[lhs].count(next_sym) == 0) { goto_map[lhs][next_sym] = vector<Item>(); } } } } // 计算GOTO for (auto& item_list : items) { char lhs = item_list.first; for (Item item : item_list.second) { if (item.dot < item.prod.rhs.size()) { char next_sym = item.prod.rhs[item.dot]; if (isupper(next_sym)) { // 下一个符号是非终结符 for (Item next_item : items.at(next_sym)) { if (next_item.prod.lhs == next_sym) { goto_map[lhs][next_sym].push_back(next_item); } } } } } } return goto_map; } // 构造LR(1)自动机 unordered_map<int, unordered_map<char, int>> construct_lr1(const vector<Production>& prods) { // 计算所有LR(0)项 Item start_item(Production('S', "E"), 0); unordered_map<char, vector<Item>> items{{start_item.prod.lhs, vector<Item>{start_item}}}; closure(start_item, prods, items); // 计算GOTO函数 unordered_map<char, unordered_map<char, vector<Item>>> goto_map = goto_func(prods, items); // 初始化DFA unordered_map<int, unordered_map<char, int>> dfa{{0, unordered_map<char, int>()}}; stack<int> stk; stk.push(0); // 构造DFA int cnt = 0; while (!stk.empty()) { int cur_state = stk.top(); stk.pop(); for (auto& sym_items : goto_map) { char sym = sym_items.first; unordered_map<char, vector<Item>>& items = sym_items.second; if (items.empty()) continue; unordered_map<char, vector<Item>> new_items; for (Item item : items[sym]) { new_items[item.prod.lhs].push_back(Item(item.prod, item.dot + 1)); } closure(Item(Production('\0', ""), 0), prods, new_items); int next_state; if (dfa.count(cur_state) && dfa[cur_state].count(sym)) { next_state = dfa[cur_state][sym]; } else { next_state = ++cnt; dfa[cur_state][sym] = next_state; dfa[next_state] = unordered_map<char, int>(); stk.push(next_state); } for (auto& item_list : new_items) { char lhs = item_list.first; int next_state2 = next_state; if (item_list.second[0].dot == item_list.second[0].prod.rhs.size()) { next_state2 = -lhs; // 接受状态 } dfa[next_state][lhs] = next_state2; } } } return dfa; } // 计算SLR(1)分析表 unordered_map<int, unordered_map<char, string>> construct_table(const vector<Production>& prods) { unordered_map<int, unordered_map<char, int>> dfa = construct_lr1(prods); // 计算ACTION和GOTO表 unordered_map<int, unordered_map<char, string>> table; for (auto& state_trans : dfa) { int cur_state = state_trans.first; unordered_map<char, int>& trans = state_trans.second; for (auto& sym_state : trans) { char sym = sym_state.first; int next_state = sym_state.second; if (isupper(sym)) { // 非终结符,填入GOTO表 table[cur_state][sym] = to_string(next_state); } else { // 终结符,填入ACTION表 if (next_state > 0) { // 移进 table[cur_state][sym] = "s" + to_string(next_state); } else if (next_state < 0) { // 接受 table[cur_state][sym] = "acc"; } else { // 错误 table[cur_state][sym] = "err"; } } } } return table; } int main() { // 例子:文法 S->E, E->E+T | T, T->T*F | F, F->(E) | id vector<Production> prods{{'S', "E"}, {'E', "E+T"}, {'E', "T"}, {'T', "T*F"}, {'T', "F"}, {'F', "(E)"}, {'F', "id"}}; // 构造SLR(1)分析表 unordered_map<int, unordered_map<char, string>> table = construct_table(prods); // 输出分析表 cout << "ACTION" << endl; for (auto& row : table) { int state = row.first; cout << state << ": "; for (auto& entry : row.second) { char sym = entry.first; string action = entry.second; cout << sym << "=" << action << " "; } cout << endl; } return 0; } ``` 这段代码实现了一个简单的SLR(1)分析器,并输出了分析表。具体分析过程可参考CSDN博客:[SLR(1)语法分析算法的C++实现](https://blog.csdn.net/clover_hxy/article/details/120316783)。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值