标签:char 终结符 back LASTVT 编译 productions FIRSTVT
FIRSTVT与LASTVT的求解。
根据相关算法对FIRSTVT或LASTVT进行求解。
根据实验内容编写程序,上机调试、得出正确的运行程序,掌握FIRSTVT和LASTVT的求解方法,了解其求解过程。
- FIRSTVT
找FIRSTVT的三条规则:如果要找A的FIRSTVT,A的候选式中出现:
①A->a…,即以终结符开头,该终结符入FIRSTVT;
②A->B…,即以非终结符开头,该非终结符的FIRSTVT入A的FIRSTVT;
③A->Ba…,即以非终结符接终结符开头,则该终结符入FIRSTVT。
- LASTVT
找LASTVT的三条规则:如果要找A的LASTVT,A的候选式中出现:
①A->…a,即以终结符结尾,该终结符入LASTVT;
②A->…B,即以非终结符结尾,该非终结符的LASTVT入A的LASTVT;
③A->…aB,即以终结符接非终结符结尾,则终结符入LASTVT。
求解FIRSTVT C++代码 |
- #include <iostream>
- #include <vector>
- #include <map>
- #include <set>
- #include <cstring>
- using namespace std;
- // 全局变量,用于存储每个非终结符的FIRSTVT集合
- map<char, set<char>> firstvt;
- // 判断字符是否为非终结符
- bool isNonTerminal(char ch) {
- return ch >= 'A' && ch <= 'Z';
- }
- // 计算文法的FIRSTVT集合
- void findFirstVT(const vector<pair<char, string>>& productions) {
- // 遍历每个产生式
- for (const auto& production : productions) {
- // 获取产生式左部非终结符和右部符号串
- char nonTerminal = production.first;
- string rhs = production.second;
- // 获取右部第一个符号
- char firstSymbol = rhs[0];
- char secondSymbol = rhs[1];
- // 若右部第一个符号是终结符,则将其加入左部非终结符的FIRSTVT集合中
- if (!isNonTerminal(firstSymbol)) {
- firstvt[nonTerminal].insert(firstSymbol);
- } else {
- // 若右部第一个符号是非终结符,则遍历其FIRSTVT集合
- for (char vt : firstvt[firstSymbol]) {
- firstvt[nonTerminal].insert(vt);
- }
- if(!isNonTerminal(secondSymbol)){
- firstvt[nonTerminal].insert(secondSymbol);
- }
- }
- }
- }
- int main() {
- // 输入产生式
- vector<pair<char, string>> productions;
- productions.push_back(make_pair('S', "a"));
- productions.push_back(make_pair('S', "^"));
- productions.push_back(make_pair('S', "(T)"));
- productions.push_back(make_pair('T', "T,S"));
- productions.push_back(make_pair('T', "S"));
- productions.push_back(make_pair('T', "a"));
- // 计算FIRSTVT集合
- findFirstVT(productions);
- // 打印FIRSTVT集合
- cout << "FIRSTVT集合:\n";
- for (const auto& entry : firstvt) {
- cout << "FIRSTVT(" << entry.first << "): { ";
- for (char symbol : entry.second) {
- cout << symbol << " ";
- }
- cout << "}\n";
- }
- return 0;
- }
|
求解LASTVT C++代码 |
- #include <iostream>
- #include <vector>
- #include <map>
- #include <set>
- #include <cstring>
- using namespace std;
- // 全局变量,用于存储每个非终结符的LASTVT集合
- map<char, set<char>> lastvt;
- // 判断字符是否为非终结符
- bool isNonTerminal(char ch) {
- return ch >= 'A' && ch <= 'Z';
- }
- // 计算文法的LASTVT集合
- void findLastVT(const vector<pair<char, string>>& productions) {
- // 遍历每个产生式
- for (const auto& production : productions) {
- // 获取产生式左部非终结符和右部符号串
- char nonTerminal = production.first;
- string rhs = production.second;
- // 获取右部最后一个符号
- char lastSymbol = rhs[rhs.length() - 1];
- char lastSymbol_1 = rhs[rhs.length() - 2];
- // 若右部最后一个符号是终结符,则将其加入左部非终结符的LASTVT集合中
- if (!isNonTerminal(lastSymbol)) {
- lastvt[nonTerminal].insert(lastSymbol);
- } else {
- // 若右部最后一个符号是非终结符,则从右往左遍历其LASTVT集合
- for (char vt : lastvt[lastSymbol]) {
- lastvt[nonTerminal].insert(vt);
- }
- if(!isNonTerminal(lastSymbol_1)){
- lastvt[nonTerminal].insert(lastSymbol_1);
- }
- }
- }
- }
- int main() {
- // 输入产生式
- vector<pair<char, string>> productions;
- productions.push_back(make_pair('S', "a"));
- productions.push_back(make_pair('S', "^"));
- productions.push_back(make_pair('S', "(T)"));
- productions.push_back(make_pair('T', "T,S"));
- productions.push_back(make_pair('T', "S"));
- productions.push_back(make_pair('T', "a"));
- // 计算LASTVT集合
- findLastVT(productions);
- // 打印LASTVT集合
- cout << "LASTVT集合:\n";
- for (const auto& entry : lastvt) {
- cout << "LASTVT(" << entry.first << "): { ";
- for (char symbol : entry.second) {
- cout << symbol << " ";
- }
- cout << "}\n";
- }
- return 0;
- }
|
- 运行结果
- 1: 求解FIRSTVT结果
本次实验通过实现FIRSTVT和LASTVT集合的求解算法,加深了对编译原理中相关概念的理解。通过实验,进一步掌握了文法的FIRSTVT和LASTVT集合的求解方法,为后续的语法分析器设计和实现提供了基础和指导。同时,通过编写和测试算法,提高了问题分析和算法设计的能力,加深了对编译原理理论的实践应用。
标签:char,
终结符,
back,
LASTVT,
编译,
productions,
FIRSTVT
From: https://blog.csdn.net/ha_ha_ha_wys/article/details/145030708