编译原理课后作业【自顶向下分析法】语法分析

实验二:

题目:语法分析

目的:通过该实验掌握描述语法的文法和自顶向下分析法中的预测分析法。

要求:对给定的文法建立预测分析表;利用预测分析法对实验一的结果进行语法分析,对不符合给定文法的表达式给出出错位置信息。

内容:给定描述语法的文法为:

E->E+T|T

T->T*F|F

F->i|(E)

题目如上描述。

用了STL里的MAP写了个程序,写的比较简单也可能有BUG,欢迎大家指出修正

Source code:

  1 //Jeremy Wu {Wushuaiyi} CS1301
  2 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
  3 #include <stdio.h>
  4 #include <iostream>
  5 #include <climits>
  6 #include <cstring>
  7 #include <stack>
  8 #include <vector>
  9 #include <map>
 10 #include <algorithm>
 11 #define ll long long
 12 using namespace std;
 13
 14 const int INF = 0x3f3f3f3f;
 15 const int MAXN = 8;
 16 const int LEN = 10000;
 17 int iCount;
 18 string ee = "e";                //Epsilon express
 19 string hh;                      //Handle
 20 string now, cur;                //Solve Handle
 21 vector <string> a, b;           //Stack and input array
 22 map <string, int> Map;          //Map
 23 map <int, string> Map_out;      //Map_out
 24 int Real[MAXN][MAXN];           //Map_realation
 25 void init(){
 26     iCount = 1;
 27     a.clear();
 28     b.clear();
 29     Map.clear();
 30     Map_out.clear();
 31     memset(Real, 0, sizeof(Real));
 32     Map["E"] = 1, Map["E‘"] = 2, Map["T"] = 3, Map["T‘"] = 4, Map["F"] = 5;
 33     Map["i"] = 6, Map["+"] = 7, Map["*"] = 8, Map["("] = 9, Map["#"] = 10;
 34     Map_out[11] = "TE‘", Map_out[12] = "+TE‘", Map_out[13] = "e";
 35     Map_out[14] = "FT‘", Map_out[15] = "*FT‘", Map_out[16] = "(E)", Map_out[17] = "i";
 36     Real[Map["E"]][Map["i"]] = 11, Real[Map["E"]][Map["("]] = 11,
 37     Real[Map["E‘"]][Map["+"]] = 12, Real[Map["E‘"]][Map[")"]] = 13,
 38     Real[Map["E‘"]][Map["#"]] = 13, Real[Map["T"]][Map["i"]] = 14,
 39     Real[Map["T"]][Map["("]] = 14, Real[Map["T‘"]][Map["+"]] = 13,
 40     Real[Map["T‘"]][Map["*"]] = 15, Real[Map["T‘"]][Map[")"]] = 13,
 41     Real[Map["T‘"]][Map["#"]] = 13, Real[Map["F"]][Map["i"]] = 17,
 42     Real[Map["F"]][Map["("]] = 16;
 43 }
 44
 45 void LookAhead(){
 46     for(int i = hh.size() - 1; i >= 0; --i){
 47         string tt;
 48            if(hh[i] == ‘\‘‘ && hh[i - 1] == ‘E‘){
 49                b.push_back("E‘");
 50             --i;
 51         } else if(hh[i] == ‘\‘‘ && hh[i - 1] == ‘T‘){
 52                b.push_back("T‘");
 53             --i;
 54         } else{
 55                tt = hh[i];
 56             b.push_back(tt);
 57         }
 58     }
 59 }
 60
 61 void print(){
 62     cout << "iCount = " << iCount << endl;
 63     cout << "Stack : " ;
 64     for(int i = 0; i < b.size(); ++i){
 65         cout << b[i];
 66     }
 67     cout << endl << "Input : ";
 68     for(int i = a.size()- 1; i >= 0; --i){
 69         cout << a[i];
 70     }
 71     cout << endl << endl;
 72 }
 73
 74 bool ErrorReport(){
 75     map<int, string>::iterator iter;
 76     iter = Map_out.find(Real[Map[now]][Map[cur]]);
 77     if(iter == Map_out.end()){
 78         cout << "Error" << endl;
 79         return true;
 80     }
 81     return false;
 82 }
 83
 84 int main(){
 85     int i;
 86     char ch[LEN];
 87     init();
 88     cin >> ch;
 89         a.push_back("#");
 90     for(i = strlen(ch); i >= 0; --i){
 91         string temp;
 92         temp = ch[i];
 93         a.push_back(temp);
 94     }
 95     b.push_back("#");
 96     b.push_back("E");
 97     print();
 98     while(!a.empty()){
 99         ++iCount;
100         cur = a.back();
101         now = b.back();
102         b.pop_back();
103         if(cur == now){                                     //Reduce
104             a.pop_back();
105         } else{                                             //Shift
106             if(ErrorReport()){
107                 return 0;                                    //Exit Program
108             }
109             hh = Map_out[Real[Map[now]][Map[cur]]];
110             if(hh == ee){
111                 print();
112                 if(b.back() == "#"){
113                     cout << "Accecpt" << endl;              //Exit Program
114                     return 0;
115                 }
116                 continue;
117             }
118             LookAhead();
119         }
120         print();
121     }
122     return 0;
123 }
时间: 2024-10-28 08:46:18

编译原理课后作业【自顶向下分析法】语法分析的相关文章

编译原理课程作业1 消除无用产生式

前言: 一年前在知乎上看到一个回答,答主说自己学了两天Python,用十几个小时做完了全部的编译原理课程作业,当时吓傻了我,现在看来,虽然两天学会比不上,但Python做课程作业的速度简直是快,课程作业1里我还傻傻的用list的extend和append,加上set函数,到第二次作业里我才发现, 没有什么结构体是一个list不能解决的,如果有,那就再套一个list 课程作业题: 消除无用产生式 # -*- coding: utf-8 -*- class Solution: def __init_

编译原理第一次作业

一.编译原理是什么?原理我们的计算机系的一门课程,它在我们的科学发展中起到了很重要的作用,也可以说是计算机系统的核心部分之一.它运用编译器.编译系统将我们的语言和计算机的语言进行转换等.内容包括语言和文法.词法分析.语法分析.语法制导翻译.中间代码生成.存储管理.代码优化和目标代码生成. 二.学习编译原理有什么好处? 1.语法分析,语义分析,和代码优化的知识,还有技巧,思想能让我终生受益. 2.我得以学习大量优美的算法,并得以欣赏理论和实践在编译器开发中如何美妙地结合在一起. 3.我可以了解怎样

编译原理随笔4(自下而上的语法分析-递归法)

0.基础知识 推导 自上而下的语法分析过程 预测分析程序,递归下降分析法(最左推导) 注:要求文法是LL(1)文法 规约 自下而上的语法分析过程 简单优先分析法,算符优先分析法,LR分析法 1.自下而上的语法分析方法 过程思想: 最左规约的过程 由输入串开始,朝着文法的开始符号进行规约 规约成非终结符 注:输入串是指词法分析器送过来的二元式序列 下推自动机PDA 语法分析程序执行动作 移入:读入一个单词,入栈,读头后移 规约:检查栈顶 若干个符号能否规约,若能,则以产生式左部替代该符号,同时输出

编译原理大作业(用java编写小型GCC 编译器)

以前只用编译器编译程序,现在学完编译原理这门课以后,通过编译大作业,我对编译器的工作原理有了比较清晰的认识 编译器的工作原理 编译器 (Compiler) 是一种将由一种语言编写的程序转换为另一种编程语言的可执行程序. 现代软件对于编译器的需求远甚从前, 究其原因很简单: 作为中间层, 编译器是构建更高层抽象的基础设施. 编译器意欲将人类可阅读的高阶代码, 翻译为机器能运行的低阶代码. 现代编译器的主要工作流程为: 源代码(source code)→ 预处理器(preprocessor)→ 编译

编译原理实验代码(词法分析,语法分析,中间代码生成)

花了一天写出的程序没有顾及很多层面,但对于理解基本的实验道理和交上实验还是有点帮助的.代码实现了基于有限自动机的词法分析,采用递归下降分析法和EBNF文法实现语法分析并生成中间代码. lexAnalysis.h /* * lexAnalysis.h * * Created on: 2014-12-2 * Author: liuqiushan */ #ifndef LEXANALYSIS_H_ #define LEXANALYSIS_H_ #include <stdio.h> #include

现代编译原理--第二章(语法分析之LR(1))

前面已经介绍过LL(1),以及如何使用LL(1)文法.但是LL(K)文法要求在看到K个字母的情况下必须做出预测,这相比于LR(K)文法而言就逊色很多. LR(K)文法的定义是:从左至右分析,最右推导,超前查看K个单词.先看一个例子,来对LR文法有个大致的印象. 以上就是使用LR文法对源码进行分析的例子.注意到在LR文法中只有三个动作:移进,规约和接受,这三个动作也是通过查表来得到的.任何时候如果都是唯一确定这三个动作中的一个,我们就能让LR文法正确的运行.为了更好的理解LR(K)文法,我们先介绍

现代编译原理--第二章(语法分析之LL(K))

LL(K)语法分析技术是建立在预测分析的技术之上的.我们先来了解预测分析技术.考虑以下文法: 当使用该文法对(1*2-3)+4和(1*2-3)进行分析,前者因该调用E->E+T,而后者应该调用E->T,怎么确定到底使用哪个产生式呢?这就要使用预测分析技术来构建预测分析语法分析器,LL(k)是其一种.预测分析技术的关键是构建一个无冲突的预测分析表.所谓预测分析表就是程序可以根据当前的状态来查询该表,然后确定下一步使用哪个产生式. 构建预测分析表要要用到两个集合,分别是first集合和follow

编译原理之算符优先分析

1. 已知算符优先关系矩阵如下表:   + * i ( ) # + > < < < > > * > > < < > > i > >     > > ( < < < < =   ) > >     > > # < < < <   =  写出符号串(i+i)*i#的算符优先分析过程. 2.接上个文章两个步骤. 1)计算FIRSTVT和 LAST

编译原理课程作业2

NFA匹配字符串,突然意识到可以用多层的list,然后整个作业就没有难度了,递归部分一直错我都怀疑人生了,结果发现是类里的递归声明要加类名.. # -*- coding: utf-8 -*- import sys class io(): """read the NFA from file""" def __init__(self,strlist): self.strlist = strlist def i(self): if(len(sys.ar