递归下降子程序文法部分编写

简介: `char`和`num dotdot num`的定义。如果遇到不匹配,原本计划调用`error`函数来报告错误,但在这个例子中,`error`函数并未实现。程序通过`main`函数获取用户输入并启动解析过程。

给定文法(PASCAL语言标识符定义文法)

         type→simple|↑id|array[simple] of type

         Simple→integer|char|num dotdot num

其中:dotdot表示..

编写递归下降子程序,判定一个句子结构是否正确:array [3..5]of integer

输入:其输入数据应该为词法分析器输出的单词序列:array [ num dotdot num ] of integer

输出:分析结果

1. 输入的时候需要把每个字符串分割出来,因为用Java的时候的split比较方便,查了下C++里面也有类似的,但是用着不太方便,所以利用C++里面的find函数和substr写了一个split,舒服多了

2. 这个和上面那个类似,只不过把字符换成了字符串,当时写第一个的时候觉得match()这个函数有点多余,因为写的比较快也没深入思考,写这个的时候才意识到,其实match()也承担了判错的责任,还是有很大作用的

3. 这个有个左递归把simple()代入到第一行的文法里思路就很清晰了


#include <iostream>

#include<bits/stdc++.h>

using namespace std;

vector<string> vc;

int localhead = 0;

void match(string local);

void type();

void simple();

vector<string> split(string str, char delim);

void error();

int main() {

   string str;

   cout << "请输入:" << endl;

   getline(cin, str);

   vc = split(str, ' ');

   type();

   return 0;

}

vector<string> split(string str, char delim) {

   vector<string> vector;

   str.append(1, delim);

   while (1) {

      //找到分隔符第一次出现的位置

       int length = str.find(delim);

       if (length == str.size() - 1) {

           vector.push_back(str.substr(0, length));

           break;

       }

      //拿到第一个分隔符前的字符串

       string temp = str.substr(0, length);

      //把分割出的字符串放入到容器中

       vector.push_back(temp);

      //将剩余的字符串替换成新串继续分割

       str = str.substr(length + 1, str.size());

   }

   return vector;

}

void match(string local) {

   if (!vc[localhead].compare(local)) {

       localhead++;

   } else {

      //error();

   }

}

void type() {

   if (!vc[localhead].compare("integer") || !vc[localhead].compare("char") || !vc[localhead].compare("num")) {

       simple();

   } else if (!vc[localhead].compare("↑")) {

       match("↑");

       match("id");

   } else if (!vc[localhead].compare("array")) {

       match("array");

       match("[");

       simple();

       match("]");

       match("of");

       type();

   } else error();

}

void simple() {

   if (!vc[localhead].compare("integer")) {

       match("integer");

   } else if (!vc[localhead].compare("char")) {

       match("char");

   } else if (!vc[localhead].compare("num")) {

       match("num");

       match("dotdot");

       match("num");

   } else error();

}

void error() {

   cout << "产生错误" << endl;

}


目录
相关文章
|
监控 JavaScript 前端开发
影刀RPA(初级)(二)
影刀RPA(初级)(二)
8635 2
|
存储 JSON JavaScript
【2023-08-20】最新PDF.js PDF批注注释插件库:创建、保存和管理PDF注释批注(高亮、文本框、绘图、截屏、历史记录、橡皮檫)-pdf.js
探索基于pdf.js-dist开发的纯Javascript PDF批注插件库,支持保存、导出、导入和管理PDF文件中的批注。多个功能模块为您提供丰富的PDF注释体验。
905 0
【2023-08-20】最新PDF.js PDF批注注释插件库:创建、保存和管理PDF注释批注(高亮、文本框、绘图、截屏、历史记录、橡皮檫)-pdf.js
|
移动开发 Java 数据安全/隐私保护
C#RSA加密解密签名类,支持PEM格式解密(1024或2048位)
主要介绍了PEM PKCS#8、PKCS#1公钥和私钥在C#中的使用,并以此为基础写的C#函数方法。
3755 1
|
机器学习/深度学习 调度 计算机视觉
CompVis
【9月更文挑战第23天】
240 3
|
JSON Kubernetes 数据格式
k8s集群namespace一直处于Terminating状态不释放解决办法
k8s集群namespace一直处于Terminating状态不释放解决办法
1111 0
|
运维 监控 网络安全
ClientAliveCountMax设置0可以吗
在决定"clientalivecountmax"或类似并发控制机制时,务必进行充分的测试与评估,确保既能满足业务连续性要求,又能有效管理资源。访问[专业云服务提供商,了解更多关于优化服务器配置、提升网络应用性能的专业知识与解决方案,帮助您在复杂的网络环境中做出更明智的选择。
306 0
node的私服中Verdaccio批量发布和手动发布依赖
node的私服中Verdaccio批量发布和手动发布依赖
478 1
|
自然语言处理
递归下降子程序的编写
该内容是关于一个递归下降解析器的实现,用于判断给定的算术表达式是否符合特定的文法。文法定义如下:
92 0
|
存储 JavaScript API
LocalStorage/sessionStorage 封装 - 基于TypeScript
文章主要介绍了如何封装一个自定义 Hooks 形式的存储服务,用于在 localStorage 或者 sessionStorage 中进行持久化存储值。通过封装的方法包括 get、set、remove、clearExcept 和 clearAll,使得操作存储变得更加简单和方便。
392 1
|
SQL 数据库 数据库管理
事务管理,事务的概念(原子性、一致性、隔离性和持久性(ACID特性))、事务的控制(BEGIN、COMMIT和ROLLBACK)
事务管理,事务的概念(原子性、一致性、隔离性和持久性(ACID特性))、事务的控制(BEGIN、COMMIT和ROLLBACK)