【编译技术实验】LL(1)预测分析(C++实现)

【编译原理】LL(1)分析方法 生成语法树(c++实现) 基本流程 输入文法->消除左递归->提取左公共因子->求FIRST集->求FOLLOW集->LL(1)分析表->表驱动的预测语法分析过程->输出语法分析结果和语法树 阅读详情

代码易懂,无需注释就能看懂。

#include<iostream>
#include<unordered_map>
#include<vector>
#include<fstream>
#include<sstream>
#include<unordered_set>
#include<map>
#include<iomanip>

using namespace std;

class OutPut{
public:
    OutPut(string step,string symbolStack,string inputString,string production,string action):
        step(std::move(step)),symbolStack(std::move(symbolStack)),inputString(std::move(inputString)),
        production(std::move(production)),action(std::move(action)){};
    void run(){
        cout << setiosflags(ios::left) << setw(14) << step << setiosflags(ios::left) << setw(14) << symbolStack
                << setiosflags(ios::left) << setw(14) << inputString<< setiosflags(ios::left) << setw(14) << production
                << setiosflags(ios::left) << setw(14) << action<<endl;
    }
private:
    string step,symbolStack,inputString,production,action;
};

class LL1Analyzer{
public:
    explicit LL1Analyzer(const string& path){
        startchar='$';
        ifstream readFile(path);
        string grammar;
        while(!readFile.eof()){
            getline(readFile,grammar,'\n');
            stringstream ss(grammar);
            string left,right;
            getline(ss,left,'>');
            if(startchar=='$') startchar=left[0];
            while(getline(ss,right,'|')){
                production[left[0]].emplace_back(right);
                for(char & ch:right)
                    if(!isupper(ch) && ch != '$') vt.insert(ch);
            }
        }
        generateFirstSet();
        generateFollowSet();
        generateM();
    }

    void solve(const string& input){
        vector<OutPut> outPutVec={OutPut("步骤","符号栈","输入串","所用产生式","动作")};
        int step=0;
        string inputstring=input+"#",symbolStack="#"+string(1,startchar),aproduciton,action="初始化";
        outPutVec.emplace_back(OutPut(to_string(step),symbolStack,input,aproduciton,action));
        int i=0;
        while(i<inputstring.size()-1){
            if(symbolStack.back()==inputstring[i]){
                symbolStack.pop_back();
                aproduciton="";
                action="GETNEXT("+string(1,inputstring[i++])+")";
            }else if(M.find({symbolStack.back(),inputstring[i]})==M.end()) break;
            else{
                aproduciton=M[{symbolStack.back(),inputstring[i]}];
                action="pop";
                symbolStack.pop_back();
                if(aproduciton.back()!='$'){
                    int point=aproduciton.find('>')+1;
                    action+=",push("+aproduciton.substr(point)+")";
                    for(int j=aproduciton.size()-1;j>=point;--j) symbolStack.push_back(aproduciton[j]);
                }
            }
            outPutVec.emplace_back(OutPut(to_string(++step),symbolStack,inputstring.substr(i),aproduciton,action));
        }
        for(OutPut aOutPut:outPutVec) aOutPut.run();
        if(inputstring[i]!='#') cout<<"出错"<<endl;
    }

private:
    void generateFirstSet(){
        int lastnum=-1,curnum=0;
        while(lastnum!=curnum){
            for(const pair<const char, vector<string>>& aProduction : production){
                for(const string& candidate:aProduction.second){
                    for(char ch : candidate) if(!isupper(ch)) first[ch].insert(ch);
                    unordered_set<char> candidateFirst= FIRST(candidate);
                    for(char item:candidateFirst)
                        if(candidate=="$"||item!='$') first[aProduction.first].insert(item);
                }
            }
            lastnum=curnum;
            curnum= tableSize(first);
        }
    }
    
    void generateFollowSet(){
        follow[startchar]={'#'};
        int lastnum=-1,curnum=0;
        while(lastnum!=curnum){
            for(const pair<const char, vector<string>>& aProduction : production){
                for(const string& candidate:aProduction.second){
                    for(int i=0;i<candidate.size();++i){
                        unordered_set<char> tempFirst= FIRST(candidate.substr(i+1));
                        for(char item:tempFirst)   follow[candidate[i]].insert(item);
                        if(tempFirst.find('$')!=tempFirst.end()||i==candidate.size()-1)
                            for(char item:follow[aProduction.first])
                                if(item!='$') follow[candidate[i]].insert(item);
                    }
                }
            }
            lastnum=curnum;
            curnum= tableSize(follow);
        }
    }

    void generateM(){
        for(const pair<const char, vector<string>>& aProduction : production){
            for(const string& candidate:aProduction.second) {
                string formula=string(1,aProduction.first)+"->"+candidate;
                unordered_set<char> candidateFirst= FIRST(candidate);
                for(char ftitem:candidateFirst)
                    if(ftitem != '$') M[{aProduction.first,ftitem}]=formula;
                    else for(char fwitem:follow[aProduction.first]) M[{aProduction.first, fwitem}]=formula;
            }
        }
    }

    unordered_set<char> FIRST(const string& txt){
       unordered_set<char> res;
        for(char ch : txt){
            unordered_set<char> cur = first[ch];
            for(char item : cur) res.insert(item);
            if(cur.find('$')==cur.end()) return res;
        }
        return res;
    }

    static int tableSize(unordered_map<char,unordered_set<char>> & table){
        int res=0;
        for(const pair<const char, unordered_set<char>>& map:table) res+=map.second.size();
        return res;
    }

    char startchar;
    unordered_map<char,unordered_set<char>> first,follow;
    unordered_map<char,vector<string>> production;
    unordered_set<char> vt;
    map<pair<char,char>,string> M; //pair不能作为无序表的key
};

int main(){
    LL1Analyzer ll1Analyzer("D://2019215055LL(1)//grammar.txt");
    ll1Analyzer.solve("i*i+i");
}
编译原理实验二:LL(1)分析法(附C/C++完整代码) 本文讲述了LL(1)文法的原理及如何用C语言实现。并在给出的代码中实现了消除文法的左递归,First集,Follow集,select集的输出,构造预测分析表并输出,和对任意输入字符串的分析。程序总流程为:从文件读取文法 -> 输出文法信息 -> 消除左递归并输出消除后的文法 -> 计算First集并输出 -> 计算Follow集并输出 ->计算select集并输出 -> 判断是否是LL(1)文法 -> 构造预测分析表并输出 ->手动输入要分析的字符串 -> 输出分析过程和结果读取文件。 阅读详情

相关推荐

编译原理:自上而下LL(1)分析法实验(c++代码实现)

程序输入/输出示例: 对下列文法,用LL(1)分析法对任意输入的符号串进行分析: (1)E->TG (2)G->+TG (3)G->ε (4)T->FS (5)S->*FS (6)S->ε (7)F->(E) (8)F->i 读文件:i+i*i# 输出结果:i+i*i#为合法符号串 代码: #include <stdio.h> #include <stdlib.h> #include <string.

nicec1的博客 5072

编译原理之LL(1)语法分析实验(附完整C/C++代码与测试)

编译原理实验之LL(1)语法分析实验,使用C语言实现,附带详细注释并测试结果

人生处处是围城,一切都是最好的安排! 2万+

辽宁大学编译原理实验全套C/C++工程:词法分析、LL1、LR1等可直接运行的调试项目

这套资源整理自辽宁大学编译原理课程实验,包含完整的C/C++实现项目,覆盖词法分析基础功能(如关键字识别、无符号数提取)、关键字排序、递归下降分析、LL(1)预测分析和LR(1)移进归约分析等核心编译器前端模块。每个实验都提供VS解决方案文件(.sln)、工程配置(.vcxproj.filters)、调试支持文件(.pdb、.ilk)以及清晰的README说明。UNumAndKeyWord.exe、UnsignedNum.exe、KeywordSort.exe、RecursionLL.exe、LL1.exe

ik678901234的博客 196

【编译原理】LL(1)分析法:C/C++实现

史上最全的编译原理之LL(1)分析法实验讲解汇总,这篇万字详解是您深入了解编译原理中LL(1)分析法的最佳选择!它提供了超全面、超详细的内容,从理论到实践,从基础到高级应用,无所不包。不仅仅是一篇教材,更是一本知识宝库,不容错过!无论您是编译原理的初学者还是研究者,这篇文章都将成为您的不可或缺的参考工具。立即将它加入收藏夹,确保不会错过这个宝贵的学习资源!

朝花夕拾 2万+

LL(1)分析法实验报告及代码

1.根据某一文法编制调试LL(1)分析程序,以便对任意输入的符号串进行分析。 2.本次实验的目的主要是加深对预测分析LL(1)分析法的理解。

C++实现LL(1)语法分析器

C++实现LL(1)法分析器:构造First集、Follow集,分析语法是否符合LL(1),并构造预测分析表。

语法分析-LL(1)预测分析C++

编译原理课程实验——语法分析 一.实验目的 掌握掌握语法分析的基本概念和基本方法,正确理解LL(1)分析法 二、算法设计思想 输入: 输出:预测分析器接受i+i*i的动作结果输出如下: 算法流程描述: LL(1)文法是一种自上而下的分析,使用最左推导,从左至右扫描输入串,且对每次最左推导只需向前看一个输入符号,便可确定当前所应当选择的算法规则,分析器结构图如下(参考课本介绍所作): 1)程序中...

ScriptFlying的博客 6422

【编译原理】LL(1)文法分析全过程(FIRST/FLLOW/SELECT集等)实现(c++语言)

需要创建一个名字叫project.txt的文件来存储要识别的文法

编译原理-LL(1)文法分析法实现(扳碎了给你看)C++

LL(1)文法分析法 一、基本思路: 计算可推出ϵ\epsilonϵ的非终结符表 计算各非终结符的FIRST集 计算出各产生式右侧的FIRST集 计算各非终结符的FOLLOW集 计算各产生式的SELECT集 构造预测分析表 分析输入串 二、实现过程 文法实例: E->TA A->+TA A->= T->FB B->*FB B->= F->i F->(E) 此处用=代替ϵ\epsilonϵ,方便编程。 1、对文法进行预处理 首先我们先把该文法的终结符和非

qq_44049627的博客 1858

STM32H750_QSPI_Flash_Configuration_With_CubeMX

本文详细介绍了如何使用STM32CubeMX配置STM32H750的QSPI Flash接口,包括硬件连接、CubeMX参数设置、代码生成与初始化流程优化。通过实战示例展示了Flash ID读取、页编程与数据读取等常用操作,并提供了调试技巧与性能优化建议,帮助开发者高效实现高速外部存储扩展。

weixin_29176179的博客 274

从S参数矩阵到硬件实现:手把手教你用耦合微带线设计Marchand巴伦

本文详细介绍了使用耦合微带线设计Marchand巴伦的完整流程。从奇偶模理论和S参数矩阵分析入手,结合ADS仿真软件进行参数优化与电磁仿真验证,最终指导PCB布局、制作与实测调试。文章以2.4GHz Wi-Fi前端电路为例,手把手演示了从理论计算到硬件实现的全过程,并分享了关键的工程经验与调试技巧。

weixin_29271263的博客 537

LL(1)预测分析程序C++实现

已知文法G如下,通过已知的预测分析表,输入要分析的字符串,得到分析结构附后。 已知文法G: E-&amp;amp;amp;amp;gt;TE' E'-&amp;amp;amp;amp;gt;+TE' E'-&amp;amp;amp;amp;gt;e T-&amp;amp;amp;amp;gt;FT' T'-&amp;amp;amp;amp;gt;*FT' T'-&amp;amp;amp;amp;gt;e F-&amp

SL_World的博客 8198

合成孔径雷达(SAR)的常见工作模式

随着星载SAR技术研究的深入发展,单一的条带模式已经无法满足当今时代的需求,因此许多新的工作模式相继被提出。这些新模式在分辨率和测绘宽度等方面都有所提高,接下来将简要介绍几种常用的工作模式。

m0_51390495的博客 2317

sdut-oj-编译原理实验(A-E、N-P)

请根据下面的表达式LL(1)文法,构造递归子程序,完成对表达式的语法分析。对于给定的输入串(长度不超过50个符号),请输出分析过程中用到的所有产生式,并指明该输入串是否为该文法能生成的表达式,输出共11行,前10行每行两个数据用空格隔开,表示推导时所用产生式顺序号(从0开始),最后一行是accept,表示i+i*i是文法能生成的合法表达式。i@i不是文法能生成的表达式,输出共5行,前5行每行两个数据用空格隔开,表示推导时所用产生式序号(从0开始),最后一行是error,表示i@i不是文法能生成的表达式。

2302_81657110的博客 1062

从零到自动化:用Python脚本搞定华为CE12800的NETCONF初始配置(含完整代码)

本文详细介绍了如何使用Python脚本实现华为CE12800交换机的NETCONF初始配置自动化。从环境准备、脚本架构设计到SSH连接与NETCONF配置实战,提供了完整的代码示例和错误处理建议,帮助运维工程师高效完成网络设备自动化配置,提升工作效率。

weixin_42525551的博客 401

自动驾驶系统研发系列—全智能驾驶新高度:深入解析车道保持辅助(ELK)功能

车道保持辅助系统(ELK)是一种基于先进视觉感知技术的主动安全系统,能够通过车载摄像头实时监测道路上的车道线、道路边缘以及周围车辆的位置。这一功能的核心在于为驾驶员提供智能化的安全辅助,尤其是在驾驶员可能因疲劳、分心或其他原因无意识地偏离车道时,系统能够主动干预,从而避免危险发生。ELK系统不仅仅依靠摄像头对道路进行感知,还结合其他传感器的数据(如雷达),实时评估自车与车道线、周边车辆的相对位置。当系统检测到车辆即将偏离车道,或越过道路边缘时,ELK会通过控制电子助力转向系统(EPS)

u013889591的专栏 1211

编译原理 LL(1)分析法 C++实现 First集合Follow集合Select集合预测分析表分析过程 实验报告

编译原理 LL(1)分析 实验报告 C++实现一、实验目的二、实验要求三、理论依据3.1 自顶向下分析与LL(1)分析法3.2 开始符号集First3.3 后跟符号集Follow3.4 可选符号集Select3.5 预测分析表四、实验步骤3.1 求解开始符号集First3.2 求解后跟符号集Follow3.3 求解可选符号集Select3.4 求解预测分析表3.5 求解分析输入串五、实验代码 写在前面: 只需要代码的童鞋滑到最后便是; 需要借鉴思路的童鞋看第四部分便是; 想搞清几个概念的童鞋看第三部分便是

weixin_45762621的博客 1万+

【深度学习新浪潮】气候预测模型的研发进展一览(2025年版)

模型类型核心优势适用场景不足ARIMA(统计模型)简单高效、可解释性强短期单变量预测非线性、长时依赖建模差随机森林(机器学习)多特征融合、抗噪声中短期多因素预测空间相关性、时序趋势捕捉弱LSTM(深度学习)长时依赖建模、端到端中长期时序预测物理一致性差、数据需求量大物理知情AI物理规律约束、高可靠性极端天气、长期气候变化模型复杂、计算成本高。

专注:太空算力、AI infra、异构调度、大模型成本工程 529

编译原理中LL(1)分析程序的设计---用c++程序语言实现

一.前言 作为当代大学生的我,我喜极而泣,最后一个编译原理实验报告了,这次是一个提高性实验报告。肝完这个,编译原理,这门课,再也没有实验报告了,我再也不要担心我没有头发了。行了,废话不多说,我直接呈现内容吧。实验心得这类的什么东西,还是留一点小小的隐私吧。直接肝!! 二.内容 1.问题描述 预测分析属于自上而下不带回溯的语法分析方法,这种分析方法要求文法是LL(1)的,语法分析程序的输入是终结符号串(即单词符号串,一一个“#”结尾),如果输入串是句子,则输出YES,否则输出NO和错误信息。 以算术表达式的文

无言月梧桐的博客 6422

RK3568平台开发系列讲解(中断及异常篇)中断下半部:中断线程化

以前用 work 来线程化地处理中断,一个 worker 线程只能由一个 CPU 执行, 多个中断的 work 都由同一个 worker 线程来处理,在单 CPU 系统中也只能忍着 了。少数中断不能线程化,典型的例子是时钟中断,有些流氓进程不主动让出处理器,内核只能依靠周期性的时钟中断夺回处理器的控制权,时钟中断是调度器的脉搏。中断处理线程是优先级为50、调度策略是SCHED_FIFO的实时内核线程,名称是“irq/”后面跟着Linux中断号,线程处理函数是。,说明是线程化的中断,那么唤醒中断处理线程。

内核笔记 435

矩阵奇异值分解算法(SVD)的导数 / 灵敏度分析

设矩阵X∈Rm×nX∈Rm×nXUΣV⊤XUΣV⊤U∈Rm×mU∈Rm×m为左奇异向量矩阵;V∈Rn×nV∈Rn×n为右奇异向量矩阵;Σdiag⁡σ1σ2σrΣdiagσ1​σ2​σr​为奇异值对角阵(rrank⁡XrrankX我们关心:当XXX发生微小扰动dXdX时,UΣVUΣV如何变化?dXdUΣV⊤dX。

qq_36812406的博客 1751

【编译原理】LL1文法的语法分析器(预测分析表)

输入LL(1)文法 #include<iostream> #include<vector> #include<map> #include<cstring> #include<stack> using namespace std; /*定义产生式的语法集结构*/ typedef struct { char formula[200];...

simle的博客 9522

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

编译原理-LL1语法分析器(消除左递归+消除回溯)

编译原理-LL1语法分析器(消除左递归+消除回溯) 实验要求: 要求一 1、 给出文法如下: G[E]: E-&gt;T|E+T; T-&gt;F|T*F; F-&gt;i|(E); 2、 根据该文法构造相应的LL(1)文法及LL(1)分析表,并为该文法设计预测分析程序,利用C语言或C++语言或Java语言实现; 3、 利用预测分析程序完成下列功能: 1) 手工将测试的表达式写入文本文件,每个表达...

Jamence的博客 3万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

编译原理实验2——语法分析(C++代码实现)

一 、实验目的 语法分析是编译程序中的核心部分。本实验通过设计一个典型的自顶向下语法分析程序——LL(1) 语法分析程序,进一步理解并掌握语法分析的原理和实现技术。 二 、实验原理 语法分析的主要任务是“组词成句”,将词法分析给出的单词序列按语法规则构成更大的语法单位,如“程序、语句、表达式”等;或者说,语法分析的作用是用来判断给定输入串是否为合乎文法的句子。 按照生成语法树的方向不同,常用的语法分析方法有两类:自顶向下分析和自底向上分析。自顶向下分析也称面向目标的分析方法,也就是从文法的开始符出发,试图推

Augenstern的博客 3万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

编译原理:LL(1)文法 语法分析器(预测分析表法)

设计要求:对于任意输入的一个LL(1)文法,构造其预测分析表,并对指定输入串分析其是否为该文法的句子。 思路:首先实现集合FIRST(X)构造算法和集合FOLLOW(A)构造算法,再根据FIRST和FOLLOW集合构造出预测分析表,并对指定的句子打印出分析栈的分析过程,判断是否为该文法的句子。 指定文法: //文法 E->TK K->+TK K->$ T->FM M->*FM M

NK_test的博客 8万+

编译原理|LL(1)语法分析实验

LL(1)语法分析实验 一、实验目的 了解 LL(1)语法分析是如何根据语法规则逐一分析词法分析所得到的单词,检查语法错误,即掌握语法分析过程。 掌握LL(1)语法分析器的设计与调试。 二、实验内容 针对CP语言中简单算术表达式文法G[E]: E→TE’ E’→ATE’|ε T→FT’ T’→MFT’ |ε F→(E) | i A → + | - M → * | / 求解相应的FIRST、FO...

匿名用户小易 6423
上一篇: 传输协议数据单元TPDU的类型及英文全称
RealWeakCoder
博客等级 码龄7年 236粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值