LL(1)语法分析器 c++实现
来源:互联网 发布:松下多功能机软件 编辑:程序博客网 时间:2024/06/01 10:42
- 结构
- 记号和规定
- 代码
- Baseh
- Basecpp
- TableStackh
- TableStackcpp
- maincpp
结构
- main.cpp包含了主函数的调用
- Base.h和Base.cpp定义了类Base, 类Base用于存储产生式、符号表、FIRST集合FOLLOW集
- TableStack.h和TableStack.cpp定义了类TableStack, 类TableStack继承了Base, 用于生成预测表和分析.
记号和规定
$表示空ε, #表示终止
大写字母为非终结符.
默认第一个产生式的左边那个非终结符就是开始符号
输入的产生式分开写(比如A->a|b, 要输入A->a和A->b才能处理)
代码
Base.h
#ifndef _BASE_H_#define _BASE_H_#include <iostream>#include <iomanip>#include <string>#include <vector>#include <set>using namespace std;struct node { // 产生式数据结构 char left; string right;};class Base {protected: int T; node production[100]; // 产生式集 set<char> first_set[100]; // first集 set<char> follow_set[100]; // follow集 vector<char> terminalNoEmpty; // 去$(空)的终结符 vector<char> terminal; // 终结符 vector<char> nonterminal; // 非终结符public: Base() :T(0){} bool isNonterminal(char c); int get_index(char target); // 获得target在终结符集合中的下标 int get_nindex(char target); // 获得target在非终结符集合中的下标 void get_first(char target); // 得到first集合 void get_follow(char target); // 得到follow集合 void inputAndSolve(); // 处理得到first和follow集 void displayFirstAndFollow(); // 显示First和Follow集};#endif
Base.cpp
#include "Base.h"bool Base::isNonterminal(char c) { if (c >= 'A' && c <= 'Z') return true; return false;}int Base::get_nindex(char target) { for (int i = 0; i<nonterminal.size(); i++) { if (target == nonterminal[i]) return i; } return -1;}int Base::get_index(char target) { for (int i = 0; i<terminalNoEmpty.size(); i++) { if (target == terminalNoEmpty[i]) return i; } return -1;}void Base::get_first(char target) { int countEmpty = 0; int isEmpty = 0; int targetIndex = get_nindex(target); for (int i = 0; i < T; i++) { if (production[i].left == target) { //匹配产生式左部 if (!isNonterminal(production[i].right[0])) { //对于终结符,直接加入first first_set[targetIndex].insert(production[i].right[0]); } else { for (int j = 0; j < production[i].right.length(); j++) { // X->Y1..Yj..Yk是一个产生式 if (!isNonterminal(production[i].right[j])) { //Yj是终结符(不能产生空),FIRST(Yj)=Yj加入FIRST(X),不能继续迭代,结束 first_set[targetIndex].insert(production[i].right[j]); break; } get_first(production[i].right[j]);//递归 先求出FIRST(Yj) // cout<<"curr :"<<production[i].right[j]; set<char>::iterator it; int YjIndex = get_nindex(production[i].right[j]); for (it = first_set[YjIndex].begin(); it != first_set[YjIndex].end(); it++) { if (*it == '$') // 遍历查看FIRST(Yj)中是否含有'$'(能产生空) isEmpty = 1; else first_set[targetIndex].insert(*it);//将FIRST(Yj)中的非$就加入FIRST(X) } if (isEmpty == 0) // Yj不能产生空, 迭代结束 break; else { countEmpty += isEmpty; isEmpty = 0; } } if (countEmpty == production[i].right.length())//所有右部first(Y)都有$(空),将$加入FIRST(X)中 first_set[get_nindex(target)].insert('$'); } } }}void Base::get_follow(char target) { int targetIndex = get_nindex(target); for (int i = 0; i<T; i++) { int index = -1; int len = production[i].right.length(); for (int j = 0; j < len; j++) { // 寻找target在产生式中的位置index if (production[i].right[j] == target) { index = j; break; } } if (index != -1 && index < len - 1) { // 找到target在产生式中的位置index // 存在A->αBβ, 将FIRST(β)中除了终结符$之外的所有放入FOLLOW(B)中 // 这里B对应target, β对应nxt char nxt = production[i].right[index + 1]; if (!isNonterminal(nxt)) { // β是终结符 follow_set[targetIndex].insert(nxt); } else { // β是非终结符 int isExt = 0; set<char>::iterator it; int nxtIndex = get_nindex(nxt); for (it = first_set[nxtIndex].begin(); it != first_set[nxtIndex].end(); it++) { if (*it == '$') isExt = 1; else follow_set[targetIndex].insert(*it); } if (isExt && production[i].left != target) { // 存在A->αBβ且FIRST(β)->$ // FOLLOW(A)放在FOLLOW(B)中 get_follow(production[i].left); set<char>::iterator it; char tmp = production[i].left; int tmpIndex = get_nindex(tmp); for (it = follow_set[tmpIndex].begin(); it != follow_set[tmpIndex].end(); it++) follow_set[targetIndex].insert(*it); } } } else if (index != -1 && index == len - 1 && target != production[i].left) { // 存在A->αB ,FOLLOW(A)放在FOLLOW(B)中 get_follow(production[i].left); set<char>::iterator it; char tmp = production[i].left; int tmpIndex = get_nindex(tmp); for (it = follow_set[tmpIndex].begin(); it != follow_set[tmpIndex].end(); it++) follow_set[targetIndex].insert(*it); } }}void Base::inputAndSolve() { string s; cout << "输入的产生式的个数:" << endl; cin >> T; for (int index = 0; index < T; index++) { // 处理每一个产生式 cin >> s; string temp = ""; // 存储去掉空格的产生式 for (int i = 0; i < s.length(); i++) { // 去掉产生式中的' ' if (s[i] != ' ') temp += s[i]; } production[index].left = temp[0]; // 产生式的左部 for (int i = 3; i<temp.length(); i++) // 产生式的右部 production[index].right += temp[i]; for (int i = 0; i < temp.length(); i++) { // 存储所有终结符和非终结符 if (i == 1 || i == 2) continue; // 跳过产生符号-> if (isNonterminal(temp[i])) { //插入一个非终结符 int flag = 0; for (int j = 0; j < nonterminal.size(); j++) { if (nonterminal[j] == temp[i]) { flag = 1; break; } } if (!flag) nonterminal.push_back(temp[i]); } else { //插入一个终结符 int flag = 0; for (int j = 0; j < terminal.size(); j++) { if (terminal[j] == temp[i]) { flag = 1; break; } } if (!flag) terminal.push_back(temp[i]); } } } terminal.push_back('#'); for (int i = 0; i < terminal.size(); i++) { // 存储没有$符号的终结符 if (terminal[i] != '$') terminalNoEmpty.push_back(terminal[i]); } // 获得first集 for (int i = 0; i < nonterminal.size(); i++) { get_first(nonterminal[i]); } // 获得follow集 for (int i = 0; i < nonterminal.size(); i++) { if (i == 0) // 开始符号, 先加入结束符号 follow_set[0].insert('#'); get_follow(nonterminal[i]); }}void Base::displayFirstAndFollow() { cout << "FIRST集合" << endl; for (int i = 0; i<nonterminal.size(); i++) { cout << nonterminal[i] << ": "; set<char>::iterator it; for (it = first_set[i].begin(); it != first_set[i].end(); it++) cout << *it << " "; cout << endl; } cout << endl; cout << "FOLLOW集合" << endl; for (int i = 0; i<nonterminal.size(); i++) { cout << nonterminal[i] << ": "; set<char>::iterator it; for (it = follow_set[i].begin(); it != follow_set[i].end(); it++) cout << *it << " "; cout << endl; } cout << endl;}
TableStack.h
#ifndef _TABLESTACK_H_#define _TABLESTACK_H_#include"Base.h"class TableStack : public Base {protected: vector<char> to_any; // 分析栈 vector<char> left_any; // 剩余输入串 int tableMap[100][100]; // 预测表public: TableStack(){ memset(tableMap, -1, sizeof(tableMap)); } void get_table(); // 生成预测表 void analyExp(string s); // 分析输入语句s void print_predictTable(); // 打印预测表 void getAns(); // 综合处理};#endif
TableStack.cpp
#include"TableStack.h"void TableStack::get_table() { for (int i = 0; i < T; i++) { // 对于每个产生式(编号i):A->α char tmp = production[i].right[0]; int row = get_nindex(production[i].left); if (!isNonterminal(tmp)) { // tmp是终结符 // 1) 对FIRST(α)中的每个终结符号a,将i加入(A, a)中 if (tmp != '$') tableMap[row][get_index(tmp)] = i; if (tmp == '$') { // 2) 如果空$在FIRST(α)中,对FOLLOW(A)中的每个终结符或结束符b,将i加入(A,b)中 set<char>::iterator it; for (it = follow_set[row].begin(); it != follow_set[row].end(); it++) { tableMap[row][get_index(*it)] = i; } } } else { // tmp是非终结符 set<char>::iterator ti; int tmpIndex = get_nindex(tmp); // 1) 对FIRST(α)中的每个终结符号a,将i加入(A, a)中 for (ti = first_set[tmpIndex].begin(); ti != first_set[tmpIndex].end(); ti++) { tableMap[row][get_index(*ti)] = i; } if (first_set[tmpIndex].count('$') != 0) { // 2) 如果空$在FIRST(α)中,对FOLLOW(A)中的每个终结符或结束符b,将i加入(A,b)中 set<char>::iterator it; for (it = follow_set[row].begin(); it != follow_set[row].end(); it++) { tableMap[row][get_index(*it)] = i; } } } }}void TableStack::analyExp(string s) { for (int i = 0; i < s.size(); i++) left_any.push_back(s[i]); left_any.push_back('#'); to_any.push_back('#'); to_any.push_back(nonterminal[0]); // 加入开始符号 while (to_any.size() > 0) { //cout<<"分析栈:"; string outs = ""; for (int i = 0; i < to_any.size(); i++) outs += to_any[i]; cout << setw(15) << outs; //cout<<"剩余输入串:"; outs = ""; for (int i = 0; i < left_any.size(); i++) outs += left_any[i]; cout << setw(15) << outs; // 匹配 char char1 = to_any.back(); char char2 = left_any.front(); if (char1 == char2 && char1 == '#') { cout << setw(15) << "Accepted!" << endl; return; } if (char1 == char2) { to_any.pop_back(); left_any.erase(left_any.begin()); cout << setw(15) << "匹配:" << char1 << endl; } else if (tableMap[get_nindex(char1)][get_index(char2)] != -1) { int tg = tableMap[get_nindex(char1)][get_index(char2)]; to_any.pop_back(); if (production[tg].right != "$") { for (int i = production[tg].right.length() - 1; i >= 0; i--) to_any.push_back(production[tg].right[i]); } //cout<<"推导:"<<production[tg].right<<endl; cout << setw(15) << "推导:" << production[tg].right << endl; } else { cout << setw(15) << "error!" << endl; return; } }}void TableStack::print_predictTable() { //table for (int i = 0; i<terminalNoEmpty.size(); i++) { cout << setw(10) << terminalNoEmpty[i]; } cout << endl; for (int i = 0; i < nonterminal.size(); i++) { cout << nonterminal[i] << ": "; for (int j = 0; j<terminalNoEmpty.size(); j++) { if (tableMap[i][j] == -1) cout << setw(10) << " "; else cout << setw(10) << production[tableMap[i][j]].right; } cout << endl; } cout << endl;}void TableStack::getAns(){ inputAndSolve(); displayFirstAndFollow(); get_table(); print_predictTable(); //栈匹配 string ss; cout << "请输入符号串:" << endl; cin >> ss; cout << setw(15) << "分析栈" << setw(15) << "剩余输入串" << setw(15) << "推导式" << endl; analyExp(ss);}
main.cpp
#include "TableStack.h"int main() { // $表示空, #表示终止 TableStack res; res.getAns(); return 0;}
阅读全文
0 0
- LL(1)语法分析器 //c++实现
- LL(1)语法分析器 c++实现
- LL(1)语法分析器
- LL(1)分析器的Java实现
- LL(1)文法分析器简单实现
- 计算机编译原理习作——LL(1)语法分析器
- 编译原理 实验2 语法分析器的构造 LL(1)
- 语法分析器C语言实现
- LL(1) 文法分析器
- LL语法分析器和LR语法分析器的比较
- 编译原理:LL(1)文法 语法分析器(预测分析表法)
- 编译原理:LL(1)文法 语法分析器(预测分析表法)
- 【C++】C++实现LL(1)语法分析
- Java实现C的语法分析器(预测分析法)
- C语言的语法分析器——java实现
- Java实现C的语法分析器(预测分析法)
- c语言实现一个简单的语法分析器
- 基于c语言的语法分析器的实现
- [BZOJ3653]谈笑风生(dfs序+主席树)
- 每天一个linux命令(53):route命令
- HDU1711-Number Sequence
- 2017-12-18php学习基础巩固第一天
- 国学名句(3)
- LL(1)语法分析器 c++实现
- FPGA基本语法及重点
- 每天一个linux命令(54):ping命令
- cafir10集合的训练经验
- 网易云通信实现最简单的单人聊天
- 关于免费实现外网访问内网的经验
- jquery解析xml文件
- 每天一个linux命令(55):traceroute命令
- Python convert a list to String