首页 > 编程语言 >根据相关算法对FIRSTVT或LASTVT进行求解(编译原理与技术)

根据相关算法对FIRSTVT或LASTVT进行求解(编译原理与技术)

时间:2025-01-09 12:33:31浏览次数:3  
标签:char 终结符 back LASTVT 编译 productions FIRSTVT

  • 实验名称

FIRSTVT与LASTVT的求解。

  • 实验内容

根据相关算法对FIRSTVT或LASTVT进行求解。

  • 实验目的

根据实验内容编写程序,上机调试、得出正确的运行程序,掌握FIRSTVT和LASTVT的求解方法,了解其求解过程。

  • 上机环境

  • 设计思想(流程)
  1. FIRSTVT

找FIRSTVT的三条规则:如果要找A的FIRSTVT,A的候选式中出现:

①A->a…,即以终结符开头,该终结符入FIRSTVT;

②A->B…,即以非终结符开头,该非终结符的FIRSTVT入A的FIRSTVT;

③A->Ba…,即以非终结符接终结符开头,则该终结符入FIRSTVT。

  1. LASTVT

找LASTVT的三条规则:如果要找A的LASTVT,A的候选式中出现:

①A->…a,即以终结符结尾,该终结符入LASTVT;

②A->…B,即以非终结符结尾,该非终结符的LASTVT入A的LASTVT;

③A->…aB,即以终结符接非终结符结尾,则终结符入LASTVT。

  • 实验代码

求解FIRSTVT C++代码

  1. #include <iostream>
  2. #include <vector>
  3. #include <map>
  4. #include <set>
  5. #include <cstring>
  6. using namespace std;
  7. // 全局变量,用于存储每个非终结符的FIRSTVT集合
  8. map<char, set<char>> firstvt;
  9. // 判断字符是否为非终结符
  10. bool isNonTerminal(char ch) {
  11.     return ch >= 'A' && ch <= 'Z';
  12. }
  13. // 计算文法的FIRSTVT集合
  14. void findFirstVT(const vector<pair<char, string>>& productions) {
  15.     // 遍历每个产生式
  16.     for (const auto& production : productions) {
  17.         // 获取产生式左部非终结符和右部符号串
  18.         char nonTerminal = production.first;
  19.         string rhs = production.second;
  20.         // 获取右部第一个符号
  21.         char firstSymbol = rhs[0];
  22.         char secondSymbol = rhs[1];
  23.         // 若右部第一个符号是终结符,则将其加入左部非终结符的FIRSTVT集合中
  24.         if (!isNonTerminal(firstSymbol)) {
  25.             firstvt[nonTerminal].insert(firstSymbol);
  26.         } else {
  27.             // 若右部第一个符号是非终结符,则遍历其FIRSTVT集合
  28.             for (char vt : firstvt[firstSymbol]) {
  29.                 firstvt[nonTerminal].insert(vt);
  30.             }
  31.             if(!isNonTerminal(secondSymbol)){
  32.              firstvt[nonTerminal].insert(secondSymbol);
  33.    }
  34.         }
  35.     }
  36. }
  37. int main() {
  38.     // 输入产生式
  39.     vector<pair<char, string>> productions;
  40.     productions.push_back(make_pair('S', "a"));
  41.     productions.push_back(make_pair('S', "^"));
  42.     productions.push_back(make_pair('S', "(T)"));
  43.     productions.push_back(make_pair('T', "T,S"));
  44.     productions.push_back(make_pair('T', "S"));
  45.     productions.push_back(make_pair('T', "a"));
  46.     // 计算FIRSTVT集合
  47.     findFirstVT(productions);
  48.     // 打印FIRSTVT集合
  49.     cout << "FIRSTVT集合:\n";
  50.     for (const auto& entry : firstvt) {
  51.         cout << "FIRSTVT(" << entry.first << "): { ";
  52.         for (char symbol : entry.second) {
  53.             cout << symbol << " ";
  54.         }
  55.         cout << "}\n";
  56.     }
  57.     return 0;
  58. }

求解LASTVT C++代码

  1. #include <iostream>
  2. #include <vector>
  3. #include <map>
  4. #include <set>
  5. #include <cstring>
  6. using namespace std;
  7. // 全局变量,用于存储每个非终结符的LASTVT集合
  8. map<char, set<char>> lastvt;
  9. // 判断字符是否为非终结符
  10. bool isNonTerminal(char ch) {
  11.     return ch >= 'A' && ch <= 'Z';
  12. }
  13. // 计算文法的LASTVT集合
  14. void findLastVT(const vector<pair<char, string>>& productions) {
  15.     // 遍历每个产生式
  16.     for (const auto& production : productions) {
  17.         // 获取产生式左部非终结符和右部符号串
  18.         char nonTerminal = production.first;
  19.         string rhs = production.second;
  20.         // 获取右部最后一个符号
  21.         char lastSymbol = rhs[rhs.length() - 1];
  22.         char lastSymbol_1 = rhs[rhs.length() - 2];
  23.         // 若右部最后一个符号是终结符,则将其加入左部非终结符的LASTVT集合中
  24.         if (!isNonTerminal(lastSymbol)) {
  25.             lastvt[nonTerminal].insert(lastSymbol);
  26.         } else {
  27.             // 若右部最后一个符号是非终结符,则从右往左遍历其LASTVT集合
  28.             for (char vt : lastvt[lastSymbol]) {
  29.              lastvt[nonTerminal].insert(vt);
  30.             }
  31.           if(!isNonTerminal(lastSymbol_1)){
  32.              lastvt[nonTerminal].insert(lastSymbol_1);
  33.    }
  34.         }
  35.     }
  36. }
  37. int main() {
  38.     // 输入产生式
  39.     vector<pair<char, string>> productions;
  40.     productions.push_back(make_pair('S', "a"));
  41.     productions.push_back(make_pair('S', "^"));
  42.     productions.push_back(make_pair('S', "(T)"));
  43.     productions.push_back(make_pair('T', "T,S"));
  44.     productions.push_back(make_pair('T', "S"));
  45.     productions.push_back(make_pair('T', "a"));
  46.     // 计算LASTVT集合
  47.     findLastVT(productions);
  48.     // 打印LASTVT集合
  49.     cout << "LASTVT集合:\n";
  50.     for (const auto& entry : lastvt) {
  51.         cout << "LASTVT(" << entry.first << "): { ";
  52.         for (char symbol : entry.second) {
  53.             cout << symbol << " ";
  54.         }
  55.         cout << "}\n";
  56.     }
  57.     return 0;
  58. }

  • 运行结果
  • 1: 求解FIRSTVT结果

        

  • 2: 求解LASTVT结果
  • 实验小结

本次实验通过实现FIRSTVT和LASTVT集合的求解算法,加深了对编译原理中相关概念的理解。通过实验,进一步掌握了文法的FIRSTVT和LASTVT集合的求解方法,为后续的语法分析器设计和实现提供了基础和指导。同时,通过编写和测试算法,提高了问题分析和算法设计的能力,加深了对编译原理理论的实践应用。

标签:char,终结符,back,LASTVT,编译,productions,FIRSTVT
From: https://blog.csdn.net/ha_ha_ha_wys/article/details/145030708

相关文章

  • C++程序编译的过程及命名空间
    C++程序编译的过程:预处理-> 编译(优化、汇编)->链接 目录 1.预处理一、包含头文件二、宏定义指令三、条件编译2、编译和链接一、源代码的组织二、编译预处理三、编译四、链接五、更多细节3、命名空间一、语法二、使用命名空间三、注意事项四、代码示例 1......
  • 【OpenCV编译教程】VS2017+OpenCV环境配置
    下载安装visualstudio、下载安装OpenCV(安装教程)后,需要在项目中配置OpenCV。步骤1:打开VisualStudio2017,创建一个新的C++项目或打开现有项目。步骤2:点击“视图”菜单,选择“其他窗口”>“属性管理器”,打开属性管理器窗口,如图1所示。图1步骤3:双击指定运行环境,打开配......
  • MacOS15+Xcode版本16+对ReactNative项目进行编译和上传到APPStore的踩坑记录
    作者:Kovli重要通知:红宝书第5版2024年12月1日出炉了,感兴趣的可以去看看,https://u.jd.com/saQw1vP红宝书第五版中文版红宝书第五版英文原版pdf下载(访问密码:9696)1、编译报错如下项目名/ios/Pods/FlipperKit/iOS/FlipperKit/FlipperPlatformWebSocket.mm:57:46Calledobjec......
  • 安卓编译报错Execution failed for task ‘:expo-modules-core:prepareBoost‘. Not i
    作者:Kovli重要通知:红宝书第5版2024年12月1日出炉了,感兴趣的可以去看看,https://u.jd.com/saQw1vP红宝书第五版中文版红宝书第五版英文原版pdf下载(访问密码:9696)报错如下[RUN_GRADLEW]Executionfailedfortask':expo-modules-core:prepareBoost'.[RUN_GRADLEW]>Cou......
  • 【Vue.js 2.x源码解析】第22章 从解析到 AST:Vue 模板编译的实现
    第22章从解析到AST:Vue模板编译的实现parse的神秘面纱解析的整体流程正则驱动的HTML解析栈结构管理DOM层级小结Vue编译原理|AST解析|前端基础你会不会在用Vue2写一个组件时,忽然想到,模板字符串是怎么变成DOM的?深入研究一番你会发现,发现背......
  • 【汇总】Android 编译命令
    一、变量、命令、参数排序变量、命令、参数英文说明中文说明备注、示例A    B    C    D    E    F    G    H    I    J    K    L ......
  • 编译时插桩,Go 应用监控最佳选择
    可观测性是以系统的指标、日志、链路追踪、持续剖析四大数据支柱为基础,从宏观到微观,通过不同数据之间互相关联,衍生出如数据监控、问题分析、系统诊断等一系列的能力。Java[1]可以通过字节码增强的技术实现无侵入的应用监控(开源社区有非常多的无侵入Agent实现方案,技术非常成熟),可......
  • 编译Ubuntu 24.04 LTS 内核(BuildYourOwnKernel)
    1、配置环境修改apt源修改/etc/apt/sources.list.d/ubuntu.sources,添加"deb-src"到Types:,修改后的文件内容如下:Types:debdeb-srcURIs:http://cn.archive.ubuntu.com/ubuntu/Suites:noblenoble-updatesnoble-backportsComponents:mainrestricteduniversemult......
  • Android13编译错误FAILED: SYSTEM_BUILD/out/target/product/qssi_au/system/vendor
    前言全局说明FAILED:SYSTEM_BUILD/out/target/product/qssi_au/system/vendorQSSI:notenabledforqssi_autargetas/release/QSSI/QSSI_enforced_targets_list.txtwasnotfound.YoucannotinstallfilestoSYSTEM_BUILD/out/target/product/qssi_au/system/vendorw......
  • [转]Android lunch添加自定义项目编译
    前言全局说明Androidlunch添加自定义项目编译一、说明原文:https://blue-bird1.github.io/posts/aosp-3/二、新建device和product在编译时已经知道编译时需要选择编译目标.而编译目标在AndroidProducts.mk这种文件下设置参考redroid可知要新建一个device首先在devic......