编译原理实验(词法分析器+语法分析器(递归下降法))

2023-11-19

1.分析C++词法,判断首位为数字的错误变量
通过对C++词法分析程序(GETSYM)的分析,并在此基础上按照教材附录A中给出的C++语言的语法描述,编写一个C++语言的词法分析程序。此程序应具有如下功能:
输入为字符串(待进行词法分析的源程序),输出为单词串,即由(单词、类别)所组成的二元组序列。
有一定检查错误的能力,例如发现2A这类不能作为单词的字符串。

这里借鉴了一些其他博主的,然后我进行了一些改进,适用于我们实验课

#include<bits/stdc++.h>
using namespace std;
string KEYWORD[19]={"if","else","void","return","while","then","for","do",      //关键字
                    "int","char","double","float","case","cin","cout","include","using","namespace","iostream"};
char SEPARATER[8]={';',',','{','}','[',']','(',')'};    //分隔符
char OPERATOR[9]={'+','-','*','/','>','<','=','!','#'};     //运算符
char Muloperator[9][2]={{'+','='},{'-','='},{'*','='},{'/','='},{'+','+'},{'-','-'},{'<','='},{'>','='},{'=','='}};
char FILTER[4]={' ','\t','\r','\n'};                    //过滤符
const int IDENTIFIER=100;         //标识符值
const int CONSTANT=101;           //常数值
const int FILTER_VALUE=102;       //过滤字符值
/**判断是否为关键字**/
bool IsKeyword(string word){
    for(int i=0;i<19;i++){
        if(KEYWORD[i]==word){
            return true;
        }
    }
    return false;
}
/**判断是否为分隔符**/
bool IsSeparater(char ch){
    for(int i=0;i<8;i++){
        if(SEPARATER[i]==ch){
            return true;
        }
    }
    return false;
}
/**判断是否为运算符**/
bool IsOperator(char ch){
    for(int i=0;i<9;i++){
        if(OPERATOR[i]==ch){
            return true;
        }
    }
    return false;
}
/**判断是否为多位运算符**/
bool IsMuloperator(char ch[]){
    for(int i=0;i<9;i++){
        if(ch[0]==Muloperator[i][0]&&ch[1]==Muloperator[i][1])return true;
    }
    return false;
}
/**判断是否为过滤符**/
bool IsFilter(char ch){
    for(int i=0;i<4;i++){
        if(FILTER[i]==ch){
            return true;
        }
    }
    return false;
}
/**判断是否为大写字母**/
bool IsUpLetter(char ch){
    if(ch>='A' && ch<='Z') return true;
    return false;
}
/**判断是否为小写字母**/
bool IsLowLetter(char ch){
    if(ch>='a' && ch<='z') return true;
    return false;
}
/**判断是否为数字**/
bool IsDigit(char ch){
    if(ch>='0' && ch<='9') return true;
    return false;
}
/**返回每个字的值**/
template <class T>
int value(T *a,int n,T str){
	for(int i=0;i<n;i++){
		if(a[i]==str) return i+1;
	}
	return -1;
}
/**词法分析**/
void analyse(FILE * fpin){
    char ch=' ';
    string arr="";
    int hang=1;
    int i=0;
    while((ch=fgetc(fpin))!=EOF){
        i++;
        arr="";
        if(IsFilter(ch)){
            if(ch=='\n')hang++;
        }              //判断是否为过滤符
        else if(IsLowLetter(ch)){       //判断是否为关键字(变量名,或者关键字)
            while(IsLowLetter(ch)){
				arr += ch;
				ch=fgetc(fpin);
            }
            if(ch!=' ')fseek(fpin,-1L,SEEK_CUR);
			if(IsKeyword(arr))cout<<hang<<"   关键字   "<<arr<<endl;
			else cout<<hang<<"   标识符   "<<arr<<endl;
        }
        else if(IsDigit(ch)){       //判断是否为数字(整数或者浮点数)     2b等不可识别符
            bool dian=false;
            bool worry=false;
            while(IsDigit(ch)||ch=='.'){//||(ch=='.'&&IsDigit(fgetc(fpin)))){
                arr += ch;
                ch=fgetc(fpin);
                if(ch=='.')dian=true;
                if(IsUpLetter(ch)||IsLowLetter(ch)){
                    worry=true;
                    arr+=ch;ch=fgetc(fpin);
                    while(IsUpLetter(ch)||IsLowLetter(ch)||IsDigit(ch)){
                        arr+=ch;ch=fgetc(fpin);
                    }
                    break;
                }
            }
            if(ch!=' ')fseek(fpin,-1L,SEEK_CUR);
            if(worry)cout<<hang<<"   不可识别符   "<<arr<<endl;
            else if(!dian)cout<<hang<<"   整形数   "<<arr<<endl;
            else cout<<hang<<"   浮点数   "<<arr<<endl;
        }
        else if(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'){//是否为山峰变量名(push_back())
            while(IsUpLetter(ch)||IsLowLetter(ch)||ch=='_'||IsDigit(ch)){
                arr += ch;
                ch=fgetc(fpin);
            }
            if(ch!=' ')fseek(fpin,-1L,SEEK_CUR);
            cout<<hang<<"   标识符   "<<arr<<endl;
        }
        else if(IsOperator(ch)){
            char noo[2];
            int cur=0;
            noo[cur++]=ch;
            arr+=ch;
            ch=fgetc(fpin);
            if(IsOperator(ch)){//下一个是字符
                noo[cur++]=ch;
                arr+=ch;
                if(IsMuloperator(noo))cout<<hang<<"   运算符   "<<arr<<endl;
                else {
                    if(ch!=' ')fseek(fpin,-1L,SEEK_CUR);
                    cout<<hang<<"   不可识别符   "<<arr<<endl;
                }
            }
            else {
                if(ch!=' ')fseek(fpin,-1L,SEEK_CUR);
                cout<<hang<<"   运算符   "<<arr<<endl;
            }
        }
        else if(IsSeparater(ch)){
            arr+=ch;
            cout<<hang<<"   分隔符   "<<arr<<endl;
        }
        else cout<<hang<<"   不可识别符   "<<ch<<endl;
    }

}
int main()
{
    char inFile[40];
    FILE *fpin;
    fpin=fopen("input.c","r");
    cout<<"------词法分析如下------"<<endl;
    analyse(fpin);
    return 0;
}
/*
cout<<"请输入源文件名(包括路径和后缀):";
    while(true){
        cin>>inFile;
        if(()!=NULL)
            break;
        else{
            cout<<"文件名错误!"<<endl;
            cout<<"请输入源文件名(包括路径和后缀):";
        }

    }
    */

2.语法分析器,分析LL(1)文法,用递归下降法(就是递归写。。。)
(1)本分析程序所分析的文法如下:
G[E]:
E→eBaA
A→a|bAcB
B→dEd|aC
C→e|dC
(2)针对上述文法编写一递归子程序分析程序,该程序的输入是任意符号串,输出是本次输入的符号串是否是该文法的句子的结论。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3;
string a;
int pos,len;
int A(int x);
int B(int x);
int C(int x);
int E(int x);
int A(int pos){
    //if(a[pos]=='#')return pos+1;
    if(a[pos]=='a')return pos+1;
    if(a[pos]=='b'){
        pos=A(pos+1);
        if(pos<0)return -1;
        if(a[pos]=='c'){
            pos=B(pos+1);
            if(pos<0)return -1;
            else return pos;
        }
        else return -1;
    }
    else return -1;
}

int B(int pos){
    //if(a[pos]=='#')return pos+1;
    if(a[pos]=='d'){
        pos=E(pos+1);
        if(pos<0)return -1;
        if(a[pos]=='d')return pos+1;
        else return -1;
    }
    else if(a[pos]=='a'){
        pos=C(pos+1);
        if(pos<0)return -1;
        return pos;
    }
    else return -1;
}

int C(int pos){
    //if(a[pos]=='#')return pos+1;
    if(a[pos]=='e'){
       return pos+1;
    }
    else if(a[pos]=='d'){
        pos=C(pos+1);
        if(pos<0)return -1;
        return pos;
    }
    else return -1;
}

int  E(int pos){
    //if(a[pos]=='#')return pos+1;
    if(a[pos]=='e'){
        pos++;
        pos=B(pos);
        if(pos<0)return -1;
        if(a[pos]=='a'){
            pos++;
            pos=A(pos);
            if(pos<0)return -1;
            else return pos;
        }
        else return -1;
    }
    else return -1;
}

int main(){
    freopen("1.txt","r",stdin);
    while(cin>>a){
        a+='#';
        len=a.size()-1;
        if(E(0)==len)cout<<a<<"\n\tis\tTrue\n";
        else cout<<a<<"\n\tis\tFalse\n";
    }
    return 0;
}

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

编译原理实验(词法分析器+语法分析器(递归下降法)) 的相关文章

  • Linux 文件共享(两种方法)

    一 实验目的 快速掌握Linux文件共享 共享文件夹 的两种方法 1 通过虚拟机ubuntu在 mnt hgfs下的共享文件夹映射到物理机实现 2 通过物理机的映射网络驱动器连接到虚拟机ubuntu的共享文件夹实现 二 实验环境 工具软件
  • 《算法图解》——第八章 贪婪算法

    第八章 贪婪算法 1 简单的贪婪算法 每步都采取最优的做法 每步都选择局部最优解 2 背包问题 有些情况下 完美是优秀的敌人 如果你只需要找到一个大致解决问题的算法 贪婪算法挺不错 因为实现容易 结果与正确结果相当接近 练习8 1 你在一家
  • 一文了解Clickhouse

    ClickHouse是什么 ClickHouse是一个存储计算一体的工具 其与spark flink等大数据框架不同的在于它有自己的存储层 在数据压缩 存储上做了更多的优化 所以导致它在某些数据处理能力上比其他工具快上了不少 毕竟一般框架只
  • OpenWrt的SR9000有线网卡驱动

    SR9000芯片的有线网卡驱动可以直接使用kmod usb net CDC ether 若为编译 可采取如下措施 make menuconfig kernel module usb support kmod usb net CDC ethe
  • PAT (Basic Level) Practice 1033 旧键盘打字 Python

    根据题意 这道题让我们根据要求去除第二行输入的字符串中的部分内容 1 判断上档键是否损坏 以进行下一步处理 2 根据要求去除字符串中特定字符 3 sys模块 可用于大量输入的加速 4 operator 可用于运算时的加速 代码如下 impo
  • Eclipse搭建stm32+jlink开发环境全攻略(高级篇)

    Eclipse搭建stm32 jlink开发环境全攻略 高级篇 一 问题概况 通过初级篇的学习 我们知道了一个Eclipse工程的配置以及调试 貌似使用也没什么问题 然而 当我们抛弃掉Eclipse自带的工程模版是 也抛弃的他的一些其他的功
  • 机器学习:多分类的logistic回归

    机器学习 多分类的logistic回归 Multi Class Logistic 多分类的Logistic问题 它适用于那些类别数大于2的分类问题 并且在分类结果中 样本x不是一定只属于某一个类可以得到样本x分别属于多个类的概率 也可以说样
  • Unity3D【脚本】 按键盘Esc弹出退出面板 确定退出游戏 取消关闭面板

    按键盘Esc弹出退出面板 确定退出游戏 取消关闭面板 效果图 脚本 using UnityEngine using System Collections public class Exit MonoBehaviour public Game
  • 【Xilinx】SynchronousInterruptHandler错误排查笔记

    SynchronousInterruptHandler错误排查笔记 一 ArmV8的异常处理 二 64位lscript ld的修改 三 asm vectors S的修改 四 SynchronousInterruptHandler函数解析 五
  • 一篇文章学会使用摩斯密码,简单易懂,你也可以使用“降维打击”

    阅读之前 大家请先看一行符号 看看大家能不能猜出这段符号所代表的含义 相信能看出这段符号含义的人还是占少数 没关系 通过阅读久见菌的这篇文章保证让你能看懂这是什么意思 摩尔斯电码的发明 上面这一串符号就是使用摩尔斯电码打出来的英语单词 摩尔
  • Latex特殊符号大全(高清)

    Latex符号大全 转载内容供自己阅读 原文 Latex特殊符号大全 高清
  • Cmake学习

    Cmake学习 CMake调用boost的编译脚本 cmake minimum required VERSION 3 14 project boost python 设置支持C 11特性 set CMAKE CXX STANDARD 11
  • 鸟哥的Linux私房菜PDF在线阅读

    鸟哥的Linux私房菜在线阅读 我在网上查了好久都没有找到正经的关于鸟哥的linux私房菜的PDF版本 要么就是耍流氓的要钱 给了钱 也不一定能得到完整版的PDF 我也只找到了在线版的 在这里供献出来 仅供大家学习参考之用 至于PDF版的
  • 如何查看linux服务器是否为amd64架构还是x86_64架构

    前言 环境 centos 7 9 我们在下载软件时 软件包后面通常带有amd64的字样 那么如何知道我们的服务器是不是amd64架构呢 下面的这些命令可以查看linux的版本及其他信息 查看linux内核版本 root master cat
  • 计算机网络-应用层协议2(FTP)

    1 文件传输协议 FTP 原理 如图所示 FTP工作原理如下 用户或主机通过FTP用户接口与FTP客户进程交互 该用户首先提供远程主机的主机名 使本地主机的FTP客户进程建立一个到远程FTP服务器进程的TCP连接 紧接着该用户提供用户标识和
  • 各种Java加密算法

    如基本的单向加密算法 BASE64 严格地说 属于编码格式 而非加密算法 MD5 Message Digest algorithm 5 信息摘要算法 SHA Secure Hash Algorithm 安全散列算法 HMAC Hash Me
  • 华为Atlas200dk使用第三步------只用一根网线登录华为开发板

    华为开发板Atlas200DK ARES500DK开发板 开发板使用心得系列文章目录 第三章 一根线登录华为开发板 目录 前言 同时使用网线和串口线连接开发板有点多余 线多显得乱 串口连接开发板也比较繁琐 因此本文给大家提供两种使用一根网线
  • FLutter Error: ADB exited with exit code 1 Performing Streamed Install

    出现这个原因是模拟器存储空间满了没办法安装运行新的应用 打开模拟器界面将原先一些不要的应用卸载了就能安装了
  • C语言中的基本输入输出

    目录 1 字符输出函数putchar 2 字符输入函数getchar 3 格式化输出函数printf 4 格式化输入函数scanf 5 字符串接收函数gets 6 字符串接收函数fgets 7 字符串输出函数puts 8 格式化转换为字符串

随机推荐

  • R语言【数据集的导入导出】

    目录 一 从键盘输入数据 二 函数方法读取 1 读取数据文件 2 从屏幕读取数据 1 scan 2 readline 3 读取固定宽度数据文件 三 读取csv文件 四 读取表格数据文件 五 从网络中读取表格或者CSV数据文件 一 从键盘输入
  • ip地址段分解与合并

    1 为什么要分解和合并ip地址段 无他 工作需要嘛 谁没事去划分ip地址段 优点 可以节省大量的时间 减少算错的可能性 2 工具下载 下载链接 https github com zhanhb cidr merger github在国内使用不
  • 如何查询Oracle数据库的操作日志

    Oracle数据库里有一个专门存储操作的视图 v sqlarea 可以通过它查询历史操作 select t SQL TEXT t FIRST LOAD TIME from v sqlarea t where t SQL TEXT like
  • linux下vbox+chrome os安装体验

    1 安装虚拟机 VirtualBox sudo apt install virtualbox 2 下载chrome OS ISO 文件 http www getchrome eu download 3 过程
  • CUDA小白 - NPP(6) 图像处理 Geometry Transforms (1)

    cuda小白 原始API链接 NPP GPU架构近些年也有不少的变化 具体的可以参考别的博主的介绍 都比较详细 还有一些cuda中的专有名词的含义 可以参考 详解CUDA的Context Stream Warp SM SP Kernel B
  • opencl入门

    openCL开发 绪论 知乎 OpenCL中文入门完整教程 opencl教程 其它文档类资源 CSDN下载 OpenCL中文入门完整教程 opencl教程 其它文档类资源 CSDN下载
  • 数据包的传输过程详解及TCP沾包问题

    目录 TCP沾包问题 5个基本知识点 封装报文是从上层到下层 应用层 gt 传输层 gt 网络层 gt 数据链路层 gt 物理层 解封装报文是从下层到上层 数据包传输的过程中 源IP和目标IP不会变 除非遇到NAT SNAT或DNAT 源M
  • mysql架构图

    MySQL 插件式的存储引擎架构将查询的处理和其它的系统任务以及数据的存储提取相分离 这种架构可以根据业务的需求和实际需要选择合适的存储引擎 连接层 最上层是一些客户端和连接服务 主要完成一些类似于连接处理 授权认证 及相关的安全方案 在该
  • swc的打包

    1 新建库项目 键入项目名称 2 新建类或者组件 并且键入包名 选择输出路径 3 编辑组件 4 打包一个好处在于复用 隐藏源码 5 使用的时候加载进来便可
  • mysql离散查询

    现有如下表 在刚开始学习where子句的时候 我想查找薪水30000和8000是哪些人时 我首先想到的是 select from employee where sal 30000 and sal 8000 结果mysql返回空给我 错误原因
  • 毛新生:一盘鱼香肉丝与SOA的故事

    将服务用一个业务流程组装在一起 在这里就体现了与以往IT一个巨大的不同 不只是在于它将下面这些服务整合起来成为一个业务流程 更重要的事情在哪里 是它终于让IT与业务人员有了共同的语言 那就是业务的活动和业务流程 而且在这里它是一个形式化的显
  • 解决ubuntu远程ssh连接不了问题

    安装openssh server sudo apt get install openssh server 在 etc ssh目录下 vim sshd config 发现该文件只可读 在终端输入命令 sudo passwd 然后输入当前用户的
  • 尚硅谷以太坊区块链学习之NFT智能合约(6)

    尚硅谷以太坊区块链学习之NFT智能合约 6 前言 一 NFT智能合约 1 智能合约代码 2 智能合约推送 3 具体调用 二 具体使用 三 NFT商家智能合约 前言 提示 服务外包区块链学习 5被ban了 也不知道怎么改能过 无所谓了 我以后
  • matlab 多变量 优化,matlab 多参数优化问题 求更正

    matlab 多参数优化问题 求更正 程序中问题 1 主程序提供的msg0 子程序却用msg 子程序不接受 应统一 2 msg0所示值不在VLB和VUB之间 按下面改 function f cpro msg x zeros 7 1000 y
  • 2021斯坦福CS224N课程笔记~5

    5 语言模型 LM 与循环神经网络 RNN 参考文档 https zhuanlan zhihu com p 424671205 https www showmeai tech article detail 239 https zhuanla
  • C++ 引用对象成员的三种方式

    在程序中经常需要访问对象中的成员 访问对象中的成员可以有3种方法 1 通过对象名和成员运算符访问对象中的成员 2 通过指向对象的指针访问对象中的成员 3 通过对象的引用变量访问对象中的成员 通过对象名和成员运算符访问对象中的成员 例如在程序
  • 如何经营IT项目中客户关系

    IT项目经理首要的能力是执行计划能力和客户关系能力 在实际工作中 笔者发现许多项目经理具备很好的计划执行能力 却忽视或者不太重视客户关系 给项目实施造成了许多本可以避免的不利因素 影响了项目的进度 甚至造成项目的失败 所以 如何经营好客户关
  • 网站的SEO

    网站的SEO 什么是SEO SEO指search engine optimization 既搜索引擎优化 SEO有什么用 SEO可以提高网站排名 SEO怎么做 内优化 外优化 h1 h2权重比较高 建议使用 因为里面内容容易被检索到 建议只
  • 《FLUENT 14.0超级学习手册》——第2章 FLUENT软件介绍2.1 FLUENT软件特点简介

    本节书摘来自异步社区 FLUENT 14 0超级学习手册 一书中的第2章 第2 1节 作者 唐家鹏 更多章节内容可以访问云栖社区 异步社区 公众号查看 第2章 FLUENT软件介绍 FLUENT 14 0超级学习手册CFD商业软件FLUEN
  • 编译原理实验(词法分析器+语法分析器(递归下降法))

    1 分析C 词法 判断首位为数字的错误变量 通过对C 词法分析程序 GETSYM 的分析 并在此基础上按照教材附录A中给出的C 语言的语法描述 编写一个C 语言的词法分析程序 此程序应具有如下功能 输入为字符串 待进行词法分析的源程序 输出