吉首大学_编译原理实验题_基于预测方法的语法分析程序的设计【通过代码】

2023-11-06

一、实验要求

实验二  基于预测方法的语法分析程序的设计

一、实验目的

了解预测分析器的基本构成及用自顶向下的预测法对表达式进行语法分析的方法,掌握预测语法分析程序的手工构造方法。

二、实验内容

1、了解编译程序的基于预测方法的语法分析过程。

2、根据预测分析原理设计一个基于预测方法的语法分析程序。

三、实验要求

对给定文法G[S]:

S->AT       A->BU     T->+AT|$      U->*BU|$    B->(S)|m

 

其中,$表示空串。

1、判断上述文法G[S]是否LL(1)文法,若不是,将其转变为LL(1)文法;

2、对转变后的LL(1)文法建立预测分析表;

3、根据清华大学出版编译原理教材教材第五章P94的图5.11手工构造预测分析程序;

4、用预测分析程序对任意给定的键盘输入串m+m*m#进行语法分析,并根据栈的变化状态输出给定串的具体分析过程。

四、运行结果

从任意给定的键盘输入串:

m+m*m#;

输出:

用预测分析法分析符号串m+m*m#的过程

Step

Stack

String

Rule

Step

Stack

String

Rule

1

#S

m+m*m#

S->AT

10

#TUm

m*m#

M匹配

2

#TA

m+m*m#

A->BU

11

#TU

*m#

U->*BU

3

#TUB

m+m*m#

B->m

12

#TUB*

*m#

*匹配

4

#TUm

m+m*m#

M匹配

13

#TUB

m#

B->m

5

#TU

+m*m#

U->$

14

#TUm

m#

M匹配

6

#T

+m*m#

T->+AT

15

#TU

#

U->$

7

#TA+

+m*m#

+匹配

16

#T

#

T->$

8

#TA

m*m#

A->BU

17

#

#

接受

9

#TUB

m*m#

B->m

 

 

 

 

五、提示

本实验重点有两个:一是如何用适当的数据结构实现预测分析表存储和使用;二是如何实现各规则右部串的逆序入栈处理。

建议:使用结构体数组。

六、分析与讨论

1、若输入串不是指定文法的句子,会出现什么情况?

2、总结预测语法分析程序的设计和实现的一般方法。


二、通过代码

#include<stdio.h>
#include<iostream>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<vector>
using namespace std;
string fir[5][6]={"","","AT","","AT","",
                  "","","BU","","BU","",
                  "+AT","","","$","","$",
                  "$","*BU","","$","","$",
                  "","","(S)","","m",""};  //first值表
map<char,int> vn;  //first表索引[非终结符]
map<char,int> vt;  //first表索引[终结符]
stack<char> Stack;  //分析栈
stack<char> String;  //剩余输入串栈
string s;   //语句存放
void inital(){
    vn['S']=1;//初始化first变索引
    vn['A']=2;
    vn['T']=3;
    vn['U']=4;
    vn['B']=5;
    vt['+']=1;
    vt['*']=2;
    vt['(']=3;
    vt[')']=4;
    vt['m']=5;
    vt['#']=6;
}
void output_stackt(){//每一步分析都得输出stack和String的值
    int n;

    s.clear();
    while(!Stack.empty()){
        s+=Stack.top();
        Stack.pop();
    }
    n=0;
    for(n=s.length()-1;n>=0;n--){
         Stack.push(s[n]);
         cout<<s[n];
    }
     cout<<"\t\t";
    s.clear();
    while(!String.empty()){
        s+=String.top();
        String.pop();
    }
    cout<<s<<"\t\t";
    n=0;
    for(n=s.length()-1;n>=0;n--)
        String.push(s[n]);
}
void ann()//程序核心程序,语法分析函数
{
    int len=0,count=0;
    char Stack_top,String_top;   //分析栈与余串栈栈顶元素
    Stack.push('#');    //#s进分析栈
    Stack.push('S');
    for(len =s.length()-1;len>=0;len--) //输入串进剩余输出栈
        String.push(s[len]);
    while(++count){    //ann 一直分析,直到接受或报错
        cout<<count<<"\t";
        output_stackt();
        if(Stack.empty()){//缺“#”【基本不会出现】
            cout<<"报错\nerror---the stack is empty\n";
            break;
        }
        if(String.empty()){//输入的串中没有“#”
            cout<<"报错\nerror---the sting is empty\n";
            break;
        }

        Stack_top=Stack.top();//取分析栈栈顶元素
        Stack.pop();    //栈顶已经要处理了,现在弹出
        String_top=String.top();//取待分析串栈顶元素
        if(vt[Stack_top]!=0&&Stack_top!='#')//没有分析道栈底
        {
            if(Stack_top==String_top){//能匹配字符
                cout<<"'"<<Stack_top<<"'匹配\n";
                String.pop();
                continue;
            }
            else{
                cout<<"报错\nerror---Stack_top!=String_top\n";
                break;
            }
        }
        if(Stack_top=='#')//分析到栈底了
        {
            if(Stack_top==String_top)   //栈底是#,接受
            {
                cout<<"接受\n";
                break;
            }
            else{
                 cout<<"报错\nerror---Stack_top=='#',but Stack_top!=String_top\n";
                break;
            }
        }
        else
        {
           if(vn[Stack_top]!=0&&vt[String_top]!=0){
                s=fir[vn[Stack_top]-1][vt[String_top]-1];
                if(s!="")
                {
                    if(s!="$")
                        for(len =s.length()-1;len>=0;len--) //公式进分析栈
                            Stack.push(s[len]);
                    cout<<Stack_top<<"->"<<s<<endl;
                }
                else
                {
                    cout<<"报错\nerror---fir[vn[Stack_top]-1][vt[String_top]-1] is null!\n";
                    break;
                }
           }
           else
           {
               cout<<"报错\nerror---vn[Stack_top]==0||vt[String_top]==0\n";
               break;
           }
        }
    }
}
void start()
{
    while(!Stack.empty())Stack.pop();
    while(!String.empty())String.pop();
    cout<<"please input the annli string:";
    cin>>s;
    cout<<"step\tstack\t\tstring\t\trule\n";
    ann();
    cout<<"\n\nthe annli is finish!\n";
}
int main(){//主函数,运行入口
    while(true){
        inital();   //初始化变量
        start();    //开始分析,并且输出分析情况
    }
    return 0;
}


三、运行结果


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

吉首大学_编译原理实验题_基于预测方法的语法分析程序的设计【通过代码】 的相关文章

  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • 查找进程的完整路径

    我已经编写了 C 控制台应用程序 当我启动应用程序时 不使用cmd 我可以看到它列在任务管理器的进程列表中 现在我需要编写另一个应用程序 在其中我需要查找以前的应用程序是否正在运行 我知道应用程序名称和路径 所以我已将管理对象搜索器查询写入
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • unordered_map 中字符串的 C++ 哈希函数

    看起来 C 标准库中没有字符串的哈希函数 这是真的 在任何 c 编译器上使用字符串作为 unordered map 中的键的工作示例是什么 C STL提供模板专业化 http en cppreference com w cpp string
  • 使用 GCP 的数据存储区时如何区分代码是在模拟器中运行还是在 GKE 中运行

    按照中给出的说明进行操作后 我不确定是否遗漏了任何内容https cloud google com datastore docs tools datastore emulator https cloud google com datasto
  • 使用 LINQ to SQL 时避免连接超时的最佳实践

    我需要知道在 net 应用程序中使用 LINQ to SQL 时避免连接超时的最佳实践 特别是在返回时IQueryable
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动
  • IQueryable 单元或集成测试

    我有一个 Web api 并且公开了一个端点 如下所示 api 假期 name name 这是 Web api 的控制器 get 方法 public IQueryable
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • C++ int 前面加 0 会改变整个值

    我有一个非常奇怪的问题 如果我像这样声明一个 int int time 0110 然后将其显示到控制台返回的值为72 但是当我删除前面的 0 时int time 110 然后控制台显示110正如预期的那样 我想知道两件事 首先 为什么它在
  • 保护 APK 中的字符串

    我正在使用 Xamarin 的 Mono for Android 开发一个 Android 应用程序 我目前正在努力使用 Google Play API 添加应用内购买功能 为此 我需要从我的应用程序内向 Google 发送公共许可证密钥
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 打印大型 WPF 用户控件

    我有一个巨大的数据 我想使用 WPF 打印 我发现WPF提供了一个PrintDialog PrintVisual用于打印派生的任何 WPF 控件的方法Visual class PrintVisual只会打印一页 因此我需要缩放控件以适合页面
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 在 Windows Phone silverlight 8.1 上接收 WNS 推送通知

    我有 Windows Phone 8 1 silverlight 应用程序 我想使用新框架 WNS 接收通知 我在 package appxmanifest 中有
  • 使用 omp_set_num_threads() 将线程数设置为 2,但 omp_get_num_threads() 返回 1

    我有以下使用 OpenMP 的 C C 代码 int nProcessors omp get max threads if argv 4 NULL printf argv 4 s n argv 4 nProcessors atoi argv
  • 为boost python编译的.so找不到模块

    我正在尝试将 C 代码包装到 python 中 只需一个类即可导出两个函数 我编译为map so 当我尝试时import map得到像噪音一样的错误 Traceback most recent call last File
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有
  • 灵气序列解析问题

    我在使用 Spirit Qi 2 4 编写解析器时遇到一些问题 我有一系列键值对以以下格式解析

随机推荐

  • 记录一下浏览器缩放和移动端缩放的区别,其实两者是有很大的不同的,之前一直搞不明白。

    直接问AI它们之间的区别的话 是这么回答的 浏览器缩放和移动端缩放是两种不同的概念 它们涉及到用户在不同设备上改变网页内容大小的方式 以下是它们的主要区别 浏览器缩放 Desktop Browser Zoom 浏览器缩放是指在桌面计算机浏览
  • 以太坊学习计划1

    1 如果链接远程链 需要上链才可以 打开服务才可以 2 开启本地geth 服务 下载https geth ethereum org downloads 默认启动geth服务 不启动rpc服务 手动用命令行启动 geth rpc 代码端调用
  • C++的使用小教程8——多态与接口

    C 的使用小教程8 多态与接口 1 什么是多态与接口 2 实现方式 3 应用实例 学习好幸苦 1 什么是多态与接口 C 多态意味着调用成员函数时 会根据调用函数的对象的类型来执行不同的函数 接口描述了类的行为和功能 而不需要完成类的特定实现
  • Qgis国际化

    参考文章 QT实现多国语言 几点需要注意的 1 pro文件生成方法 2 ts文件生成方法 输入命令 lupdate f code QT Code QtApplication2 QtApplication2 QtApplication pro
  • Vit,DeiT,DeepViT,CaiT,CPVT,CVT,CeiT简介

    Vit 最基础的 就是将transformer的encoder取出来 输入图像大小维度 B C H W 将图片不重叠地划分为H patch height w patch weight个patch 每个patch为patch height p
  • Spark相关问题

    Spark相关问题 Hadoop FileFormat接口问题 Hadoop FileOutputFormat在写入数据的时候先写到临时目录 最后写入最终目录 临时目录到最终目录的过程中需要做文件树合并 合并过程中有大量Rename操作 F
  • Hash函数

    概述 Hash函数 散列函数 是一种将任意长度的数据映射到有限长度的域上 通俗来讲 就是将一串任意长度的数据进行打乱混合 转换为一段固定长度的数据输出 这段数据便成为输入数据的一个 指纹 特征 Hash函数的首要目标是保证数据的完整性 而不
  • css连续的纯数字或字母强制换行

    white space normal word break break all
  • 一些网站1

    N1BOOK平台 Nu1L Team Nu1L Team 0004 Median of Two Sorted Arrays LeetCode Cookbook 题库 力扣 LeetCode 全球极客挚爱的技术成长平台
  • 解决shell断开后java进程被结束

    偶尔会碰到用SecureCRT在shell启动java进程并后台运行 命令最后加 的时候 因为断电死机等原因断开shell 然后进程被结束了 运维大佬也说用他们的工具启动进程后一断开连接进程就结束了 后来查到是因为shell在断开的时候会向
  • 漫谈数据挖掘从入门到进阶

    做数据挖掘也有些年头了 写这篇文一方面是写篇文 给有个朋友作为数据挖掘方面的参考 另一方面也是有抛砖引玉之意 希望能够和一些大牛交流 相互促进 让大家见笑了 入门 数据挖掘入门的书籍 中文的大体有这些 Jiawei Han的 数据挖掘概念与
  • Day_1 Part_4 Structures of R

    1 Vector Matrix Array 1 1 What are they Collection of observations Vector 1 dimensional Matrix 2 dimensional Array 3 dim
  • 常见web漏洞及防范(转)

    单个漏洞 需要进行排查与整改 借着别人的智慧 做一个简单的收集 最好能够将常见漏洞 不限于web类的 进行一个统一的整理 这是今年的任务 进行漏洞的工具的收集 为未来的工作做好基础 一 SQL注入漏洞 SQL注入攻击 SQL Injecti
  • MMDetection 3.x中的PackDetInputs

    MMDetection 3 X 里面对pipeline有一个重点修改是新增了 PackDetInputs 有利于统一 进行检测 语义分割 全景分割任务 从配置文件中我们可以看出包含LoadImageFromFile LoadAnnotati
  • electron在BrowserWindow中禁止右键菜单

    最近使用 electron vite solid js 做一个网络流量实时监控的小工具 其中需要禁止用户在获取 BrowserWindow 焦点后弹出默认右键菜单 解决方案 在 new BrowserWindow 后中添加以下代码 禁止右键
  • 静默执行bat文件

    让bat隐藏运行需要用vbs文件才能实现 方式一 使用vbs文件 新建一个 文本文档后缀改为 vbs 可以这样写 set ws WScript CreateObject WScript Shell ws Run d yy bat 0 其中d
  • 《区块链技术与应用》学习笔记2——BTC数据结构

    Hash pointer 哈希指针 指针 在程序运行过程中 需要用到数据 最简单的是直接获取数据 但当数据本身较大 需要占用较大空间时 明显会造成一定麻烦 因此可以引用指针 每次获取相应的数据即可 实际使用中 指针实际上存储的是逻辑地址更多
  • C语言用scanf来判断键盘输入数据类型

    2 可以用来判断是否和定义的类型一致 如 int n if scanf d n 1 else 可以用来判断键盘输入的数据是否是整数
  • 打不开微软自带的软件,或者初次安装sql server 提示下载不了,版本不支持的,一定检查一下这里

    检查这里 这里一定要把代理模式关掉 血的教训啊
  • 吉首大学_编译原理实验题_基于预测方法的语法分析程序的设计【通过代码】

    一 实验要求 实验二 基于预测方法的语法分析程序的设计 一 实验目的 了解预测分析器的基本构成及用自顶向下的预测法对表达式进行语法分析的方法 掌握预测语法分析程序的手工构造方法 二 实验内容 1 了解编译程序的基于预测方法的语法分析过程 2