LL(1)分析实验 c++代码

时间: 2023-06-27 17:04:44 浏览: 62
以下是一个简单的 LL(1) 分析实验的 C++ 代码示例: ```c++ #include <iostream> #include <string> #include <stack> #include <unordered_map> using namespace std; // 定义文法符号类型 enum SymbolType { TERMINAL, // 终结符 NONTERMINAL // 非终结符 }; // 定义产生式类型 struct Production { string left; // 左部符号 vector<string> right; // 右部符号 }; // 定义 LL(1) 分析表类型 typedef unordered_map<string, unordered_map<string, Production>> ParsingTable; // 获取终结符和非终结符类型 SymbolType getSymbolType(string symbol) { if (isupper(symbol[0])) { return NONTERMINAL; } return TERMINAL; } // 构造 LL(1) 分析表 ParsingTable buildParsingTable(vector<Production>& productions, vector<string>& terminals, vector<string>& nonterminals) { ParsingTable table; // 初始化分析表 for (auto nonterminal : nonterminals) { for (auto terminal : terminals) { table[nonterminal][terminal] = {"", {}}; } } // 填充分析表 for (auto production : productions) { string left = production.left; for (auto terminal : terminals) { if (production.right[0] == terminal) { // 预测分析表第一项 table[left][terminal] = production; } else if (getSymbolType(production.right[0]) == NONTERMINAL) { // 预测分析表其他项 for (auto follow : table[production.right[0]][terminal].right) { if (follow != "#") { table[left][follow] = production; } } } } } return table; } // LL(1) 分析器 bool parse(string input, ParsingTable& table) { stack<string> stk; stk.push("$"); // 结束符 stk.push(table.begin()->first); // 开始非终结符 int i = 0; while (!stk.empty()) { string top = stk.top(); stk.pop(); if (top == "$") { // 输入串匹配完毕 return true; } if (getSymbolType(top) == TERMINAL) { // 终结符 if (top == input.substr(i, 1)) { i++; } else { return false; } } else { // 非终结符 Production production = table[top][input.substr(i, 1)]; if (production.left == "") { // 分析表中无对应产生式 return false; } else { for (auto it = production.right.rbegin(); it != production.right.rend(); it++) { if (*it != "#") { // 空产生式不入栈 stk.push(*it); } } } } } return false; } int main() { // 定义文法 vector<Production> productions = { {"E", {"T", "E'"}}, {"E'", {"+", "T", "E'"}}, {"E'", {"#",}}, {"T", {"F", "T'"}}, {"T'", {"*", "F", "T'"}}, {"T'", {"#",}}, {"F", {"(", "E", ")"}}, {"F", {"i"}}, }; // 获取终结符和非终结符 vector<string> terminals = {"+", "*", "(", ")", "i"}; vector<string> nonterminals = {"E", "E'", "T", "T'", "F"}; // 构造 LL(1) 分析表 ParsingTable table = buildParsingTable(productions, terminals, nonterminals); // 打印 LL(1) 分析表 for (auto nonterminal : nonterminals) { for (auto terminal : terminals) { Production production = table[nonterminal][terminal]; cout << nonterminal << ", " << terminal << ": "; if (production.left == "") { cout << "error" << endl; } else { cout << production.left << " -> "; for (auto symbol : production.right) { cout << symbol << " "; } cout << endl; } } } // 输入串 string input = "i+i*i$"; // LL(1) 分析 bool result = parse(input, table); if (result) { cout << "input " << input << " is accepted" << endl; } else { cout << "input " << input << " is rejected" << endl; } return 0; } ``` 该代码实现了一个简单的 LL(1) 分析器,包括以下功能: - 构造文法符号类型的枚举类型 `SymbolType`。 - 定义产生式类型 `Production`,包括左部符号和右部符号序列。 - 定义 LL(1) 分析表类型 `ParsingTable`,使用 `unordered_map` 实现。 - 实现函数 `getSymbolType`,用于获取符号类型。 - 实现函数 `buildParsingTable`,用于构造 LL(1) 分析表。 - 实现函数 `parse`,用于进行 LL(1) 分析。 - 在 `main` 函数中定义文法、终结符和非终结符,构造 LL(1) 分析表,并对输入串进行 LL(1) 分析。 使用该代码,可以对输入串进行 LL(1) 分析,并输出分析结果。

相关推荐

最新推荐

recommend-type

LL(1)分析法实验报告及代码

1.根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。 2.本次实验的目的主要是加深对预测分析LL(1)分析法的理解。
recommend-type

LL(1)分析法实验报告

LL(1)分析法实验报告,有附代码的,代码可是直接使用,VC6.0就可以了
recommend-type

编译原理LL(1)语法分析实验报告.doc

通过完成预测分析法的语法分析程序,了解预测分析法和递归子程序法的区别和联系。使了解语法分析的功能,掌握语法分析程序设计的原理和构造方法,训练掌握开发应用程序的基本方法。
recommend-type

表驱动LL(1)语法分析程序.docx

通过设计、编制和调试一个典型的LL(1)语法分析方法,进一步掌握预测分析法的语法分析方法。 1.2主要完成的任务 (1)根据LL(1)分析法编写一个语法分析程序,输入文法的FIRST(α)和FOLLOW(U)集,由程序自动生成文法的...
recommend-type

编译原理的语法分析——LL(1)分析表的实现.docx

LL(1)语法分析程序、自顶向下语法分析判断LL(1)文法的方法、文法等价变换、LL(1)分析表的构造、对某一输入串的分析过程的理解,本次实验的LL(1)文法为表达式文法: E→E+T | T T→T*F | F F→i | (E)
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB柱状图在信号处理中的应用:可视化信号特征和频谱分析

![matlab画柱状图](https://img-blog.csdnimg.cn/3f32348f1c9c4481a6f5931993732f97.png) # 1. MATLAB柱状图概述** MATLAB柱状图是一种图形化工具,用于可视化数据中不同类别或组的分布情况。它通过绘制垂直条形来表示每个类别或组中的数据值。柱状图在信号处理中广泛用于可视化信号特征和进行频谱分析。 柱状图的优点在于其简单易懂,能够直观地展示数据分布。在信号处理中,柱状图可以帮助工程师识别信号中的模式、趋势和异常情况,从而为信号分析和处理提供有价值的见解。 # 2. 柱状图在信号处理中的应用 柱状图在信号处理
recommend-type

帮我设计一个基于Android平台的便签APP的代码

很抱歉,我是一个语言模型AI,无法提供完整的Android APP代码。但是,我可以给您一些设计便签APP的建议和思路。 1. 界面设计 首先考虑APP的界面设计,便签APP通常需要一个主界面用于显示所有的便签,以及一个编辑界面用于编辑单个便签。主界面可以采用列表的形式,列出所有的便签,每个便签可以显示标题和摘要内容。在编辑界面中,用户可以输入标题和正文内容,并且可以设置提醒时间、标签、优先级等。 2. 数据存储 便签APP需要一个数据存储的方案,可以考虑使用SQLite数据库来存储便签数据。每个便签可以存储标题、正文内容、提醒时间、标签、优先级等信息。 3. 便签操作 便签APP
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。