编译器构造中自底向上的LALR语法分析的语法分析表生成的实现

Posted wskit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编译器构造中自底向上的LALR语法分析的语法分析表生成的实现相关的知识,希望对你有一定的参考价值。

提示:阅读本文需掌握编译原理的相关基础知识

本文中使用C++语言系统地实现了龙书中LALR(1)语法分析表的构造算法,首先计算增广文法的LR(0)项集族,每一个项集只包含内核项,计算过程中自动生成了LR(0)自动机,该自动机使用基于十字链表存储结构的有向图表示。然后通过确定自发生成和传播的向前看符号算法计算各LR(0)内核项集自发生成的向前看符号(增广文法新增产生式的向前看符号不包括在内)并确定LR(0)内核项集之间向前看符号的传播关系。最后一遍扫描前将为增广文法新增产生式添加向前看符号即输入结束符$,然后传播向前看符号直到不能传播为止,扫描结束后就生成了LALR(1)内核项集族。随后调用函数计算各LALR(1)项集的非内核项集确定LALR(1)项集族,并得到LALR(1)自动机。最后根据LALR(1)自动机填写LALR(1)语法分析表完成语法分析表的生成工作。

程序测试用例为博主自行编写的正则表达式文法(文法部分地方写得较别扭,而且并非反映正则表达式全部特性的文法,对正反向预查的支持存在一些问题,请读者见谅),由于文法保存在文本中,需要由计算机读入分析,为了便于计算机理解需要将书写格式标准化,博主自行设计了书写格式,具体如下:

#1b 非终结符 非终结符 ---- #1e (非终结符号集合)
#2b 终结符 终结符 ---- #2e   (终结符号集合)
#3b 增广文法开始符号 原文法开始符号 #3e
#4b
#b 非终结符(产生式头) $1($2) 非终结符或终结符 $1($2) 非终结符或终结符 ---- #e  (产生式体)   ($1标志非终结符,$2标志终结符,第一个产生式必须为增广产生式,第二个产生式必须为原文法以原文法开始符号为头的产生式)
----
#4e

其中省略号表示相同格式子项的重复出现,按照以上格式书写的文法(该文法修改了无数遍,说多了都是泪)为:

#1b S‘ S preSurvey E T M F G outSquare B V C B‘ inSquare inSquareRange #1e
#2b \ SPECTRANMETA POSITIVE-SURE-PRE POSITIVE-NEGA-PRE NEGATIVE-SURE-PRE NEGATIVE-NEGA-PRE ) | CLOSURE ? GIVEN LBOUND ULBOUND CLOSURE-NONGREEDY LBOUND-NONGREEDY ULBOUND-NONGREEDY CAP NONPRECAP SPECTRAN TRANMETA UPPERALPHA LOWERALPHA DIGIT SPECMETA REVERSEREF ^ [ ] - OTHERMETA $ #2e
#3b S‘ S #3e
#4b
#b S‘ $1 S #e
#b S $1 E #e
#b S $1 preSurvey #e
#b preSurvey $1 E $2 POSITIVE-SURE-PRE $1 E $2 ) #e
#b preSurvey $1 E $2 POSITIVE-NEGA-PRE $1 E $2 ) #e
#b preSurvey $2 NEGATIVE-SURE-PRE $1 E $2 ) $1 E #e
#b preSurvey $2 NEGATIVE-NEGA-PRE $1 E $2 ) $1 E #e
#b E $1 E $2 | $1 T #e
#b E $1 T #e
#b T $1 T $1 M #e
#b T $1 M #e
#b M $1 M $2 CLOSURE #e
#b M $1 M $2 ? #e
#b M $1 M $2 GIVEN #e
#b M $1 M $2 LBOUND #e
#b M $1 M $2 ULBOUND #e
#b M $1 M $2 CLOSURE-NONGREEDY #e
#b M $1 M $2 LBOUND-NONGREEDY #e
#b M $1 M $2 ULBOUND-NONGREEDY #e
#b M $1 F #e
#b F $2 CAP $1 E $2 ) #e
#b F $1 G #e
#b F $2 NONPRECAP $1 E $2 ) #e
#b F $1 outSquare #e
#b outSquare $2 SPECTRAN #e
#b outSquare $2 TRANMETA #e
#b outSquare $2 \ #e
#b outSquare $2 SPECTRANMETA #e
#b outSquare $2 UPPERALPHA #e
#b outSquare $2 LOWERALPHA #e
#b outSquare $2 DIGIT #e
#b outSquare $2 SPECMETA #e
#b outSquare $2 REVERSEREF #e
#b outSquare $2 ^ #e
#b G $2 [ $1 B $1 V $1 C $2 ] #e
#b V $2 ^ #e
#b V #e
#b B $1 B $1 B‘ #e
#b B $1 B‘ #e
#b B‘ $1 V $1 inSquareRange $2 - $1 inSquareRange #e
#b inSquareRange $2 SPECTRAN #e
#b inSquareRange $2 SPECMETA #e
#b inSquareRange $2 OTHERMETA #e
#b inSquareRange $2 UPPERALPHA #e
#b inSquareRange $2 LOWERALPHA #e
#b inSquareRange $2 DIGIT #e
#b inSquareRange $2 CLOSURE #e
#b inSquareRange $2 \ #e
#b inSquareRange $2 SPECTRANMETA #e
#b inSquareRange $2 ? #e
#b inSquareRange $2 CAP #e
#b inSquareRange $2 | #e
#b inSquareRange $2 ) #e
#b C $1 C $1 inSquare #e
#b C $1 inSquare #e
#b inSquare $1 inSquareRange #e
#b inSquare $2 NONPRECAP #e
#b inSquare $2 POSITIVE-SURE-PRE #e
#b inSquare $2 POSITIVE-NEGA-PRE #e
#b inSquare $2 NEGATIVE-SURE-PRE #e
#b inSquare $2 NEGATIVE-NEGA-PRE #e
#b inSquare $2 ULBOUND #e
#b inSquare $2 LBOUND #e
#b inSquare $2 ULBOUND-NONGREEDY #e
#b inSquare $2 LBOUND-NONGREEDY #e
#b inSquare $2 CLOSURE-NONGREEDY #e
#b inSquare $2 GIVEN #e
#b G $2 [ $1 B $2 ] #e
#b G $2 [ $1 V $1 C $2 ] #e
#4e

#1b和#1e之间的部分为文法非终结符,#2b和#2e之间的部分为文法终结符,S‘为增广文法开始符,S为原文法开始符

#4b和#4e之间的部分为产生式,紧跟于#b之后的是产生式头,随后为产生式体, $2表示紧跟其后的文法符号为终结符,$1表示紧跟其后的文法符号为非终结符,所有这些构成了对上下文无关文法的完整描述。这里非终结符、终结符以及产生式的含义博主会在将来发布的有关构建正则表达式引擎的文章中详解,现在只需着眼于文法本身,不必关心它们的具体含义。

需要另外说明的是,文法设计不当会导致一些异常现象的发生,例如如果把以上文法第三道产生式的产生式头的非终结符S改为F(这样就允许了预查表达式任意的自嵌套),程序会在计算follow集时陷入死循环,原因是修改过的文法第6,7道产生式直接导致程序在计算出非终结符E的follow集前必须先计算出E的follow集,导致循环计算,这样计算follow集时会陷入死循环。可以验证,如果去掉产生式6、7程序就可以正常运行并输出结果(但是存在语法分析动作冲突)。

下面贴出代码,代码只有1500多行不算多,称不上严格意义的项目,没有放在github上的必要,就在博客园上分享吧。

代码清单(C++):

技术分享图片
   1 #include "pch.h"
   2 #include <iostream>
   3 #include <string>
   4 #include <vector>
   5 #include <map>
   6 #include <set>
   7 #include <tuple>
   8 #include <memory>
   9 #include <functional>
  10 #include <deque>
  11 #include <fstream>
  12 #include <cctype>
  13 #include <stack>
  14 #include <algorithm>
  15 #include <list>
  16 #include "Priority_Queue.h"
  17 #include "assistfunction.h"
  18 using namespace std;      //注意.被定义为匹配任意字符,实际上应为除/r,/n以外的任意字符,单词被定义为大小写字母序列,实际上应为字母、数字和下划线组成的序列,行结束符被定义为/r/n,只适合windows系统
  19 
  20 template <typename V, typename E>  //V,E必须定义拷贝构造函数和复制赋值运算符以及析构函数
  21 class Graph   //有向图类,存储结构为十字链表
  22 {
  23     friend class RELALRParsing;
  24 public:
  25     class GraphVertexNode;
  26     struct GraphEdgeNode    //边节点类
  27     {
  28         typename vector<GraphVertexNode *>::size_type head = 0;  //弧头对应顶点
  29         typename vector<GraphVertexNode *>::size_type tail = 0;  //弧尾对应顶点
  30         E  *Edgedatafield = nullptr;   //指向边节点数据域的指针
  31         GraphEdgeNode *sameheadptr = nullptr;   //指向弧头相同的下一个边节点
  32         GraphEdgeNode *sametailptr = nullptr;   //指向弧尾相同的下一个边节点
  33 
  34         GraphEdgeNode() = default;
  35         GraphEdgeNode(typename vector<GraphVertexNode *>::size_type sh, typename vector<GraphVertexNode *>::size_type st, E *Edge) :head(sh), tail(st), Edgedatafield(Edge) {}
  36         ~GraphEdgeNode() { delete Edgedatafield; }
  37     };
  38 
  39     struct GraphVertexNode
  40     {
  41         typename vector<GraphVertexNode *>::size_type number = 0;   //顶点序号
  42         V *Vertexdatafield = nullptr;   //指向顶点数据域的指针
  43         GraphEdgeNode *firstheadptr = nullptr;   //指向以顶点为弧头的第一个边节点
  44         GraphEdgeNode *firsttailptr = nullptr;   //指向以顶点为弧尾的第一个边节点
  45         GraphVertexNode *seilring = nullptr;     //如果顶点上有自环,该指针指向顶点本身,否则为空
  46         E  *Edgeseilring = nullptr;     //指向附着在顶点上的自环边数据域的指针
  47 
  48         GraphVertexNode() = default;
  49         GraphVertexNode(typename vector<GraphVertexNode *>::size_type num, V *Ver) :Vertexdatafield(Ver), number(num) {}
  50         ~GraphVertexNode() { delete Vertexdatafield; delete Edgeseilring; }
  51     };
  52 
  53     Graph() = default;
  54     Graph(typename vector<GraphVertexNode *>::size_type n) :SetOfVertex(n, nullptr) {}   //将SetOfVertex初始化为大小为n的顶点数组,数组元素中指向顶点的指针为空
  55     virtual ~Graph();
  56     Graph<V, E> *Copy();   //拷被作为目的对象的有向图对象,返回指向拷贝得到的有向图的指针
  57     typename vector<typename Graph<V, E>::GraphVertexNode *>::size_type addVertex(V *vertex);   //向有向图中新增一个顶点,该顶点数据域为vertex指向内容,返回新增的顶点序号
  58     bool addEdge(typename vector<GraphVertexNode *>::size_type vertex1, typename vector<GraphVertexNode *>::size_type vertex2, E *edge);   //向有向图中添加以vertex1为弧尾,vertex2为弧头的边,vertex1,vertex2必须存在,可以相等,添加成功返回true,否则返回false
  59     Graph<V, E> *merge(Graph<V, E>& Bemerged, bool copyOrNot);   //将作为目的对象的有向图和Bemerged合并,copyOrNot=true则拷贝目的对象并将Bemerged副本和目的对象副本合并,返回合并后新图指针,否则将Bemerged副本直接合并至目的对象,返回nullptr
  60     typename vector<GraphVertexNode *>::size_type getVertexNum() { return SetOfVertex.size(); }   //返回图中顶点个数
  61     void ReversalGraph();   //将作为目的对象的有向图的每条边翻转方向,即调换弧头和弧尾
  62 
  63 protected:
  64     vector<GraphVertexNode *> SetOfVertex;    //有向图顶点构成的集合
  65 };
  66 
  67 template <typename V, typename E>
  68 void Graph<V, E>::ReversalGraph()
  69 {
  70     for (typename vector<GraphVertexNode *>::size_type scan = 0; scan < SetOfVertex.size(); ++scan)
  71     {
  72         for (GraphEdgeNode *q = SetOfVertex[scan]->firsttailptr; q != nullptr; )
  73         {
  74             swap(q->head, q->tail);
  75             GraphEdgeNode * temp = q->sametailptr;
  76             swap(q->sameheadptr, q->sametailptr);
  77             q = temp;
  78         }
  79         swap(SetOfVertex[scan]->firstheadptr, SetOfVertex[scan]->firsttailptr);
  80     }
  81 }
  82 
  83 template <typename V, typename E>
  84 Graph<V, E> *Graph<V, E>::Copy()
  85 {
  86     Graph<V, E> *temp = new Graph<V, E>(SetOfVertex.size());
  87     for (typename vector<GraphVertexNode *>::size_type scan = 0; scan < SetOfVertex.size(); ++scan)
  88     {
  89         temp->SetOfVertex[scan] = new GraphVertexNode(SetOfVertex[scan]->number, new V(*(SetOfVertex[scan]->Vertexdatafield)));
  90         if (SetOfVertex[scan]->seilring != nullptr)
  91         {
  92             temp->SetOfVertex[scan]->seilring = temp->SetOfVertex[scan];
  93             temp->SetOfVertex[scan]->Edgeseilring = new E(*(SetOfVertex[scan]->Edgeseilring));
  94         }
  95         GraphEdgeNode *p = nullptr;
  96         for (GraphEdgeNode *q = SetOfVertex[scan]->firsttailptr; q != nullptr; q = q->sametailptr)
  97         {
  98             if (p == nullptr)
  99             {
 100                 p = temp->SetOfVertex[scan]->firsttailptr = new GraphEdgeNode(q->head, q->tail, new E(*(q->Edgedatafield)));
 101             }
 102             else
 103             {
 104                 p = p->sametailptr = new GraphEdgeNode(q->head, q->tail, new E(*(q->Edgedatafield)));
 105             }
 106         }
 107     }
 108 
 109     for (typename vector<GraphVertexNode *>::size_type scan = 0; scan < SetOfVertex.size(); ++scan)
 110     {
 111         GraphEdgeNode *p = nullptr;
 112         for (GraphEdgeNode *q = SetOfVertex[scan]->firstheadptr; q != nullptr; q = q->sameheadptr)
 113         {
 114             GraphEdgeNode *m = temp->SetOfVertex[q->tail]->firsttailptr;
 115             for (; ; m = m->sametailptr)
 116             {
 117                 if (m->head == scan)
 118                     break;
 119             }
 120 
 121             if (p == nullptr)
 122             {
 123                 p = temp->SetOfVertex[scan]->firstheadptr = m;
 124             }
 125             else
 126             {
 127                 p = p->sameheadptr = m;
 128             }
 129         }
 130     }
 131     return temp;
 132 }
 133 
 134 template <typename V, typename E>
 135 Graph<V, E>::~Graph()
 136 {
 137     for (typename vector<GraphVertexNode *>::size_type scan = 0; scan < SetOfVertex.size(); ++scan)
 138     {
 139         GraphEdgeNode *ptr = nullptr;
 140         while (SetOfVertex[scan]->firsttailptr != nullptr)
 141         {
 142             ptr = SetOfVertex[scan]->firsttailptr;
 143             SetOfVertex[scan]->firsttailptr = ptr->sametailptr;
 144             SetOfVertex[ptr->head]->firstheadptr = ptr->sameheadptr;
 145             delete ptr;
 146         }
 147     }
 148 
 149     while (SetOfVertex.empty() == false)
 150     {
 151         delete SetOfVertex.back();
 152         SetOfVertex.pop_back();
 153     }
 154 }
 155 
 156 template <typename V, typename E>
 157 typename vector<typename Graph<V, E>::GraphVertexNode *>::size_type Graph<V, E>::addVertex(V *vertex)
 158 {
 159     SetOfVertex.push_back(new GraphVertexNode(SetOfVertex.size(), vertex));
 160     return SetOfVertex.size() - 1;
 161 }
 162 
 163 template <typename V, typename E>
 164 bool Graph<V, E>::addEdge(typename vector<GraphVertexNode *>::size_type vertex1, typename vector<GraphVertexNode *>::size_type vertex2, E *edge)  //vertex1为弧尾,vertex2为弧头
 165 {
 166     if (vertex1 == vertex2)
 167     {
 168         SetOfVertex[vertex1]->seilring = SetOfVertex[vertex1];
 169         SetOfVertex[vertex1]->Edgeseilring = new E(*edge);
 170         return true;
 171     }
 172 
 173     GraphEdgeNode *start = SetOfVertex[vertex1]->firsttailptr;
 174     GraphEdgeNode *pre = nullptr;
 175     if (start == nullptr)
 176     {
 177         SetOfVertex[vertex1]->firsttailptr = new GraphEdgeNode(vertex2, vertex1, edge);
 178         if (SetOfVertex[vertex2]->firstheadptr == nullptr)
 179         {
 180             SetOfVertex[vertex2]->firstheadptr = SetOfVertex[vertex1]->firsttailptr;
 181             return true;
 182         }
 183     }
 184     else
 185     {
 186         for (; start != nullptr; )
 187         {
 188             if (start->head == vertex2)
 189                 return false;
 190             else if (start->head < vertex2)
 191             {
 192                 pre = start;
 193                 start = start->sametailptr;
 194             }
 195             else
 196             {
 197                 if (pre == nullptr)
 198                 {
 199                     pre = SetOfVertex[vertex1]->firsttailptr;
 200                     SetOfVertex[vertex1]->firsttailptr = new GraphEdgeNode(vertex2, vertex1, edge);
 201                     SetOfVertex[vertex1]->firsttailptr->sametailptr = pre;
 202                     if (SetOfVertex[vertex2]->firstheadptr == nullptr)
 203                     {
 204                         SetOfVertex[vertex2]->firstheadptr = SetOfVertex[vertex1]->firsttailptr;
 205                         return true;
 206                     }
 207                     pre = SetOfVertex[vertex1]->firsttailptr;
 208                 }
 209                 else
 210                 {
 211                     pre->sametailptr = new GraphEdgeNode(vertex2, vertex1, edge);
 212                     pre->sametailptr->sametailptr = start;
 213                     if (SetOfVertex[vertex2]->firstheadptr == nullptr)
 214                     {
 215                         SetOfVertex[vertex2]->firstheadptr = pre->sametailptr;
 216                         return true;
 217                     }
 218                     pre = pre->sametailptr;
 219                 }
 220                 break;
 221             }
 222         }
 223         if (start == nullptr)
 224         {
 225             if (pre->head == vertex2)
 226                 return false;
 227             pre->sametailptr = new GraphEdgeNode(vertex2, vertex1, edge);
 228             if (SetOfVertex[vertex2]->firstheadptr == nullptr)
 229             {
 230                 SetOfVertex[vertex2]->firstheadptr = pre->sametailptr;
 231                 return true;
 232             }
 233             pre = pre->sametailptr;
 234         }
 235     }
 236 
 237     if (pre == nullptr)
 238     {
 239         pre = SetOfVertex[vertex1]->firsttailptr;
 240     }
 241 
 242     GraphEdgeNode *p = nullptr;
 243     for (GraphEdgeNode *start = SetOfVertex[vertex2]->firstheadptr; start != nullptr; )
 244     {
 245         if (start->tail < vertex1)
 246         {
 247             p = start;
 248             start = start->sameheadptr;
 249         }
 250         else
 251         {
 252             if (p == nullptr)
 253             {
 254                 p = SetOfVertex[vertex2]->firstheadptr;
 255                 SetOfVertex[vertex2]->firstheadptr = pre;
 256                 pre->sameheadptr = p;
 257             }
 258             else
 259             {
 260                 p->sameheadptr = pre;
 261                 pre->sameheadptr = start;
 262             }
 263             return true;
 264         }
 265     }
 266     p->sameheadptr = pre;
 267     return true;
 268 }
 269 
 270 template <typename V, typename E>
 271 Graph<V, E> *Graph<V, E>::merge(Graph<V, E>& Bemerged, bool copyOrNot/*true拷贝目的对象,fasle不拷贝,直接合并至目的对象*/)
 272 {
 273     Graph<V, E> *temp1 = nullptr;
 274     typename vector<GraphVertexNode *>::size_type Ca1 = 0;
 275     if (copyOrNot)
 276     {
 277         temp1 = Copy();
 278         Ca1 = temp1->SetOfVertex.size();
 279     }
 280     else
 281     {
 282         Ca1 = SetOfVertex.size();
 283     }
 284 
 285     {
 286         Graph<V, E> *temp2 = Bemerged.Copy();
 287         for (typename vector<GraphVertexNode *>::size_type p = 0; p < temp2->SetOfVertex.size(); ++p)
 288         {
 289             if (copyOrNot)
 290             {
 291                 temp1->SetOfVertex.push_back(temp2->SetOfVertex[p]);
 292             }
 293             else
 294             {
 295                 SetOfVertex.push_back(temp2->SetOfVertex[p]);
 296             }
 297         }
 298         while (temp2->SetOfVertex.empty() == false)
 299         {
 300             temp2->SetOfVertex.pop_back();
 301         }
 302         delete temp2;
 303     }
 304 
 305     for (typename vector<GraphVertexNode *>::size_type p = Ca1; ; ++p)
 306     {
 307         Graph<V, E>::GraphEdgeNode *q = nullptr;
 308         if (copyOrNot)
 309         {
 310             if (p >= temp1->SetOfVertex.size())
 311                 break;
 312             temp1->SetOfVertex[p]->number = p;
 313             q = temp1->SetOfVertex[p]->firsttailptr;
 314         }
 315         else
 316         {
 317             if (p >= SetOfVertex.size())
 318                 break;
 319             SetOfVertex[p]->number = p;
 320             q = SetOfVertex[p]->firsttailptr;
 321         }
 322 
 323         for (; q != nullptr; q = q->sametailptr)
 324         {
 325             q->head = q->head + Ca1;
 326             q->tail = q->tail + Ca1;
 327         }
 328     }
 329 
 330     if (copyOrNot)
 331         return temp1;
 332     else
 333         return nullptr;
 334 }
 335 
 336 struct LALRState   //LALR状态
 337 {
 338     struct attribute
 339     {
 340         int dotposition;  //每一个产生式点号位置
 341         set<string> ForwardLookingSign;  //产生式向前看符号集合
 342         attribute() = default;
 343         attribute(int dot) : dotposition(dot) {}
 344     };
 345 
 346     map<long, map<int, set<string>>> kernel;  //内核项集合,键为产生式编号,值键点号位置,值向前看符号集合
 347     map<long, attribute> nonkernel;  //非内核项集合, 键为产生式编号
 348 };
 349 
 350 struct LALRTableItem   //LALR语法分析表项
 351 {
 352     enum action { MOVE, REDUCTION, ACCEPT, ERROR } ActionType;   //该项的语法分析动作
 353     union
 354     {
 355         vector<Graph<LALRState, string>::GraphVertexNode *>::size_type LALRStateNumber;  //该项为移入时应移入的LALR状态
 356         long production;   //该项为归约时应选则的产生式编号
 357         string NULLLable;  //该项为报错时表示错误消息的字符串,语法分析程序中为预留,没有填写具体内容
 358     };
 359     LALRTableItem() :ActionType(action::ERROR), NULLLable("") {}
 360     LALRTableItem(action A, long p) :ActionType(A), production(p) {}
 361     LALRTableItem(action A, vector<Graph<LALRState, string>::GraphVertexNode *>::size_type L) :ActionType(A), LALRStateNumber(L) {}
 362     LALRTableItem(action A) :NULLLable("") {}
 363     LALRTableItem(const LALRTableItem &copy);
 364     ~LALRTableItem()
 365     {
 366         if (NULLLable != "")
 367             NULLLable.~string();
 368     }
 369 };
 370 
 371 LALRTableItem::LALRTableItem(const LALRTableItem &copy)
 372 {
 373     ActionType = copy.ActionType;
 374     switch (copy.ActionType)
 375     {
 376     case ACCEPT:
 377     case ERROR: new (&NULLLable) string(copy.NULLLable); break;
 378     case MOVE: LALRStateNumber = copy.LALRStateNumber; break;
 379     case REDUCTION: production = copy.production; break;
 380 
 381     }
 382 }
 383 
 384 class LALRAutomata : public  Graph<LALRState, string>  //LALR(1)自动机类,自动机用有向图表示,该有向图来自Graph类
 385 {
 386     friend class RELALRParsing;
 387     friend void output(LALRAutomata &test, ofstream &output);
 388 public:
 389     struct ProductionBodySymbol   //产生式体中的文法符号
 390     {
 391         string symbol;   //终结符或非终结符
 392         bool TerminalOrNot;  //true终结符,false非终结符
 393         ProductionBodySymbol() = default;
 394         ProductionBodySymbol(string s, bool T) :symbol(s), TerminalOrNot(T) {}
 395     };
 396     LALRAutomata(ifstream &input);
 397     static bool isSubSet(const map<string, set<string>> &left, const set<string> &right);  //判断right是否为left键集的子集,返回true是返回false不是
 398 private:
 399     shared_ptr<map<string, set<string>>> calculateFirst(); //构造各非终结符及其first集的映射表
 400     shared_ptr<set<string>> calculateFirst(const vector<ProductionBodySymbol> &Pro, vector<ProductionBodySymbol>::size_type left, vector<ProductionBodySymbol>::size_type right); //返回给定文法符号串的first集
 401     shared_ptr<map<string, set<string>>> calculateFollow(); //构造各非终结符及其follow集的映射表
 402     void calculateClosureLALR(map<long, map<int, set<string>>> &kernelset, map<long, LALRState::attribute> &nonkernelset); //第一个参数内核项集,由内核项集生成非内核项构成的闭包存放至第二个参数,函数功能为计算LALR内核项集闭包,计算开始前nonkernelset会被清空
 403     void calculateClosureLR(map<long, map<int, set<string>>> &kernelset, map<long, LALRState::attribute> &nonkernelset);  //计算LR(0)内核项集(存放于kernelset)闭包(只包括非内核项),计算结果存放至nonkernelset,计算开始前nonkernelset会被清空
 404     void constructLRKernel(); //构造LR(0)项集族,每个项集只包含LR(0)内核项
 405     pair<shared_ptr<map<string, int>>, shared_ptr<vector<vector<LALRTableItem>>>> constructLALR(); //构造LALR(1)项集族,返回的pair第一分量为文法符号和LALR语法分析表列表映射关系的智能指针,第二分量为指向LALR语法分析表的智能指针
 406     void initgrammar(ifstream &input); //初始化文法各组成要素
 407     set<string> Nonterminal; //非终结符号集合(增广文法)
 408     set<string> terminnal;  //终结符号集合
 409     string StartSymbol; //原文法开始符号
 410     string AugGraSS;  //增广文法开始符号
 411     map<long, tuple<string, vector<ProductionBodySymbol>, set<string>>> productionSet; //产生式集合(增广文法),键为产生式编号,值tuple第一分量为非终结符号,第二分量为产生式代表的终结符号和非终结符号的序列,增广文法新增唯一产生式编号必须为1,第三分量为产生式体中非终结符号的集合
 412     map<string, set<long>> TerToPro; //键为非终结符,值为对应产生式编号集
 413     vector<Graph<LALRState, string>::GraphVertexNode>::size_type start; //LALR(1)自动机开始状态
 414     vector<Graph<LALRState, string>::GraphVertexNode>::size_type accept; //读入向前看符号$后结束语法分析的接受态
 415     shared_ptr<map<string, set<string>>> first; //指向各非终结符及其first集的映射表
 416     shared_ptr<map<string, set<string>>> follow;  //指向各非终结符及其follow集的映射表
 417     pair<shared_ptr<map<string, int>>, shared_ptr<vector<vector<LALRTableItem>>>> LALRTable; //LALR(1)语法分析动作表
 418 
 419 };
 420 
 421 void LALRAutomata::initgrammar(ifstream &input)  //根据从input读入的文法信息初始化Nonterminal、terminnal、StartSymbol、AugGraSS、productionSet以及TerToPro
 422 {
 423     enum T { TERMINAL, NONTERMINAL } flag;
 424     string current;
 425     stack<string> stackforparse;
 426     bool TF = true;
 427     map<long, tuple<string, vector<ProductionBodySymbol>, set<string>>> ::iterator itp;
 428     map<string, set<long>>::iterator itT;
 429     while (input >> current)
 430     {
 431         if (current == "#1b" || current == "#2b" || current == "#3b" || current == "#4b")
 432         {
 433             stackforparse.push(current);
 434             if (current == "#3b")
 435             {
 436                 TF = true;
 437             }
 438         }
 439         else if (current == "#1e" || current == "#2e" || current == "#3e" || current == "#4e")
 440         {
 441             stackforparse.pop();
 442         }
 443         else if (current == "#b" || current == "$1")
 444         {
 445             if (current == "#b")
 446                 TF = true;
 447             flag = NONTERMINAL;
 448         }
 449         else if (current == "#e")
 450         {
 451             continue;
 452         }
 453         else if (current == "$2")
 454         {
 455             flag = TERMINAL;
 456         }
 457         else
 458         {
 459             if (stackforparse.top() == "#4b")
 460             {
 461                 if (flag == NONTERMINAL)
 462                 {
 463                     if (TF == true)
 464                     {
 465                         TF = false;
 466                         if (productionSet.empty())
 467                         {
 468                             itp = productionSet.insert(make_pair(1, tuple<string, vector<ProductionBodySymbol>, set<string>>(current, vector<ProductionBodySymbol>(), set<string>()))).first;
 469                             TerToPro.insert(make_pair(current, set<long>())).first->second.insert(1);
 470                         }
 471                         else
 472                         {
 473                             itp = productionSet.insert(make_pair(itp->first + 1, tuple<string, vector<ProductionBodySymbol>, set<string>>(current, vector<ProductionBodySymbol>(), set<string>()))).first;
 474                             itT = TerToPro.find(current);
 475                             if (itT == TerToPro.end())
 476                             {
 477                                 TerToPro.insert(make_pair(current, set<long>())).first->second.insert(itp->first);
 478                             }
 479                             else
 480                             {
 481                                 itT->second.insert(itp->first);
 482                             }
 483                         }
 484                     }
 485                     else
 486                     {
 487                         get<1>(itp->second).push_back(ProductionBodySymbol(current, false));
 488                         get<2>(itp->second).insert(current);
 489                     }
 490                 }
 491                 else
 492                 {
 493                     get<1>(itp->second).push_back(ProductionBodySymbol(current, true));
 494                 }
 495             }
 496             else if (stackforparse.top() == "#3b")
 497             {
 498                 if (TF)
 499                 {
 500                     TF = false;
 501                     AugGraSS = current;
 502                 }
 503                 else
 504                 {
 505                     StartSymbol = current;
 506                 }
 507             }
 508             else if (stackforparse.top() == "#2b")
 509             {
 510                 terminnal.insert(current);
 511             }
 512             else
 513             {
 514                 Nonterminal.insert(current);
 515             }
 516         }
 517     }
 518 }
 519 
 520 LALRAutomata::LALRAutomata(ifstream &input)
 521 {
 522     initgrammar(input);
 523     first = calculateFirst();  //计算first集
 524     follow = calculateFollow();   //计算follow集
 525     constructLRKernel();
 526     LALRTable = constructLALR();   //构造LALR(1)语法分析表
 527 }
 528 
 529 pair<shared_ptr<map<string, int>>, shared_ptr<vector<vector<LALRTableItem>>>> LALRAutomata::constructLALR()
 530 {
 531     shared_ptr<map<string, int>> symbolToIndex = make_shared<map<string, int>>();
 532     {
 533         int count = 0;
 534         setToMap(terminnal, *symbolToIndex, count);    //建立文法符号到语法分析表第二维的映射
 535         setToMap(Nonterminal, *symbolToIndex, count);
 536     }
 537     shared_ptr<vector<vector<LALRTableItem>>>LALRTablePtr = make_shared<vector<vector<LALRTableItem>>>(SetOfVertex.size(), vector<LALRTableItem>((*symbolToIndex).size()));
 538     for (vector<Graph<LALRState, string>::GraphVertexNode *>::size_type i = 0; i < SetOfVertex.size(); ++i)    //根据LR(0)项集族向语法分析表中填入移入动作
 539     {
 540         if (SetOfVertex[i]->seilring != nullptr)
 541         {
 542             map<string, int>::iterator temp = symbolToIndex->find(*(SetOfVertex[i]->Edgeseilring));
 543             (*LALRTablePtr)[i][temp->second].ActionType = LALRTableItem::action::MOVE;
 544             (*LALRTablePtr)[i][temp->second].LALRStateNumber = i;
 545         }
 546         for (Graph<LALRState, string>::GraphEdgeNode *p = SetOfVertex[i]->firsttailptr; p != nullptr; p = p->sametailptr)
 547         {
 548             map<string, int>::iterator temp = symbolToIndex->find(*(p->Edgedatafield));
 549             (*LALRTablePtr)[i][temp->second].ActionType = LALRTableItem::action::MOVE;
 550             (*LALRTablePtr)[i][temp->second].LALRStateNumber = p->head;
 551         }
 552     }
 553     vector<map<long, map<int, map<vector<Graph<LALRState, string>::GraphVertexNode *>::size_type, map<long, set<int>>>>>> FLKSymbolTran;
 554     for (vector<Graph<LALRState, string>::GraphVertexNode *>::size_type i = 0; i < SetOfVertex.size(); ++i)   //计算各LR(0)内核项自发生成的向前看符号并确定LR(0)内核项集之间向前看符号的传播关系
 555     {
 556         FLKSymbolTran.push_back(map<long, map<int, map<vector<Graph<LALRState, string>::GraphVertexNode *>::size_type, map<long, set<int>>>>>());
 557         for (map<long, map<int, set<string>>>::iterator p = SetOfVertex[i]->Vertexdatafield->kernel.begin(); p != SetOfVertex[i]->Vertexdatafield->kernel.end(); ++p)
 558         {
 559             auto x1 = FLKSymbolTran.back().insert(make_pair(p->first, map<int, map<vector<Graph<LALRState, string>::GraphVertexNode *>::size_type, map<long, set<int>>>>())).first;
 560             for (map<int, set<string>>::iterator q = p->second.begin(); q != p->second.end(); ++q)
 561             {
 562                 if (q->first != get<1>(productionSet[p->first]).size())
 563                 {
 564                     auto x2 = x1->second.insert(make_pair(q->first, map<vector<Graph<LALRState, string>::GraphVertexNode *>::size_type, map<long, set<int>>>())).first;
 565                     vector<Graph<LALRState, string>::GraphVertexNode *>::size_type index = (*LALRTablePtr)[i][(*symbolToIndex)[get<1>(productionSet[p->first])[q->first].symbol]].LALRStateNumber;
 566                     if (get<1>(productionSet[p->first])[q->first].TerminalOrNot == false)
 567                     {
 568                         map<long, map<int, set<string>>> kernelitem;
 569                         kernelitem.insert(make_pair(p->first, map<int, set<string>>())).first->second.insert(make_pair(q->first, set<string>())).first->second.insert("#");
 570                         map<long, LALRState::attribute> nonkernelitem;
 571                         calculateClosureLALR(kernelitem, nonkernelitem);
 572                         for (map<long, LALRState::attribute>::iterator m = nonkernelitem.begin(); m != nonkernelitem.end(); ++m)
 573                         {
 574                             if (m->second.dotposition != get<1>(productionSet[m->first]).size())
 575                             {
 576                                 vector<Graph<LALRState, string>::GraphVertexNode *>::size_type index = (*LALRTablePtr)[i][(*symbolToIndex)[get<1>(productionSet[m->first])[m->second.dotposition].symbol]].LALRStateNumber;
 577                                 set<string>::const_iterator temp = m->second.ForwardLookingSign.find("#");
 578                                 if (temp != m->second.ForwardLookingSign.cend())
 579                                 {
 580                                     ((SetOfVertex[index]->Vertexdatafield->kernel)[m->first])[m->second.dotposition + 1].insert(m->second.ForwardLookingSign.cbegin(), temp);
 581                                     ((SetOfVertex[index]->Vertexdatafield->kernel)[m->first])[m->second.dotposition + 1].insert(++temp, m->second.ForwardLookingSign.cend());
 582                                     auto x3 = x2->second.find(index);
 583                                     if (x3 != x2->second.end())
 584                                     {
 585                                         auto x4 = x3->second.find(m->first);
 586                                         if (x4 != x3->second.end())
 587                                         {
 588                                             x4->second.insert(m->second.dotposition + 1);
 589                                         }
 590                                         else
 591                                         {
 592                                             x3->second.insert(make_pair(m->first, set<int>())).first->second.insert(m->second.dotposition + 1);
 593                                         }
 594                                     }
 595                                     else
 596                                     {
 597                                         x2->second.insert(make_pair(index, map<long, set<int>>())).first->second.insert(make_pair(m->first, set<int>())).first->second.insert(m->second.dotposition + 1);
 598                                     }
 599                                 }
 600                                 else
 601                                 {
 602                                     ((SetOfVertex[index]->Vertexdatafield->kernel)[m->first])[m->second.dotposition + 1].insert(m->second.ForwardLookingSign.cbegin(), m->second.ForwardLookingSign.cend());
 603                                 }
 604                             }
 605                         }
 606                         auto x3 = x2->second.find(index);
 607                         if (x3 != x2->second.end())
 608                         {
 609                             auto x4 = x3->second.find(p->first);
 610                             if (x4 != x3->second.end())
 611                             {
 612                                 x4->second.insert(q->first + 1);
 613                             }
 614                             else
 615                             {
 616                                 x3->second.insert(make_pair(p->first, set<int>())).first->second.insert(q->first + 1);
 617                             }
 618                         }
 619                         else
 620                         {
 621                             x2->second.insert(make_pair(index, map<long, set<int>>())).first->second.insert(make_pair(p->first, set<int>())).first->second.insert(q->first + 1);
 622                         }
 623                     }
 624                     else
 625                     {
 626                         (x2->second)[index] = map<long, set<int>>();
 627                         ((x2->second)[index])[p->first] = set<int>();
 628                         ((x2->second)[index])[p->first].insert(q->first + 1);
 629                     }
 630                 }
 631             }
 632             if (x1->second.empty())
 633             {
 634                 FLKSymbolTran.back().erase(x1);
 635             }
 636         }
 637     }
 638 
 639     (SetOfVertex[start]->Vertexdatafield->kernel[*(TerToPro[AugGraSS].begin())])[0].insert("$");  //为增广文法新增的产生式填写向前看符号输入结束符$,它是自发生成的
 640     while (true)    //不断扫描所有LR(0)项集传播向前看符号,直到某一轮再也没有向前看符号被传播为止
 641     {
 642         bool continueTran = false; //
 643         for (vector<Graph<LALRState, string>::GraphVertexNode *>::size_type i = 0; i < SetOfVertex.size(); ++i)
 644         {
 645             if (FLKSymbolTran[i].empty() == false)
 646             {
 647                 map<long, map<int, map<vector<Graph<LALRState, string>::GraphVertexNode *>::size_type, map<long, set<int>>>>>::iterator p1 = FLKSymbolTran[i].begin();
 648                 map<long, map<int, set<string>>>::iterator p2 = SetOfVertex[i]->Vertexdatafield->kernel.begin();
 649                 while (p1 != FLKSymbolTran[i].end() && p2 != SetOfVertex[i]->Vertexdatafield->kernel.end())
 650                 {
 651                     if (p1->first == p2->first)
 652                     {
 653                         map<int, map<vector<Graph<LALRState, string>::GraphVertexNode *>::size_type, map<long, set<int>>>>::iterator q1 = p1->second.begin();
 654                         map<int, set<string>>::iterator q2 = p2->second.begin();
 655                         while (q1 != p1->second.end() && q2 != p2->second.end())
 656                         {
 657                             if (q1->first == q2->first)
 658                             {
 659                                 if (q2->second.empty() == false)
 660                                 {
 661                                     for (map<vector<Graph<LALRState, string>::GraphVertexNode *>::size_type, map<long, set<int>>>::iterator w1 = q1->second.begin(); w1 != q1->second.end(); ++w1)
 662                                     {
 663                                         map<long, set<int>>::iterator m1 = w1->second.begin();
 664                                         map<long, map<int, set<string>>>::iterator m2 = SetOfVertex[w1->first]->Vertexdatafield->kernel.begin();
 665                                         while (m1 != w1->second.end() && m2 != SetOfVertex[w1->first]->Vertexdatafield->kernel.end())
 666                                         {
 667                                             if (m1->first == m2->first)
 668                                             {
 669                                                 set<int>::const_iterator v1 = m1->second.cbegin();
 670                                                 map<int, set<string>>::iterator v2 = m2->second.begin();
 671                                                 while (v1 != m1->second.cend() && v2 != m2->second.end())
 672                                                 {
 673                                                     if (*v1 == v2->first)
 674                                                     {
 675                                                         set<string>::size_type temp = v2->second.size();
 676                                                         v2->second.insert(q2->second.cbegin(), q2->second.cend());
 677                                                         if (temp != v2->second.size())
 678                                                         {
 679                                                             continueTran = true;
 680                                                         }
 681                                                         ++v1;
 682                                                         ++v2;
 683                                                     }
 684                                                     else if (*v1 < v2->first)
 685                                                     {
 686                                                         ++v1;
 687                                                     }
 688                                                     else
 689                                                     {
 690                                                         ++v2;
 691                                                     }
 692                                                 }
 693                                                 ++m1;
 694                                                 ++m2;
 695                                             }
 696                                             else if (m1->first < m2->first)
 697                                             {
 698                                                 ++m1;
 699                                             }
 700                                             else
 701                                             {
 702                                                 ++m2;
 703                                             }
 704                                         }
 705 
 706                                     }
 707                                 }
 708                                 ++q1;
 709                                 ++q2;
 710                             }
 711                             else if (q1->first < q2->first)
 712                             {
 713                                 ++q1;
 714                             }
 715                             else
 716                             {
 717                                 ++q2;
 718                             }
 719                         }
 720                         ++p1;
 721                         ++p2;
 722                     }
 723                     else if (p1->first < p2->first)
 724                     {
 725                         ++p1;
 726                     }
 727                     else
 728                     {
 729                         ++p2;
 730                     }
 731                 }
 732             }
 733         }
 734         if (continueTran == false)
 735             break;
 736     }
 737 
 738     for (vector<Graph<LALRState, string>::GraphVertexNode *>::size_type i = 0; i < SetOfVertex.size(); ++i)
 739     {
 740         calculateClosureLALR(SetOfVertex[i]->Vertexdatafield->kernel, SetOfVertex[i]->Vertexdatafield->nonkernel);  //为每个LALR(1)内核项集计算闭包得到LALR(1)项集
 741         for (map<long, map<int, set<string>>>::iterator p = SetOfVertex[i]->Vertexdatafield->kernel.begin(); p != SetOfVertex[i]->Vertexdatafield->kernel.end(); ++p)   //为LALR(1)语法分析表填入归约动作
 742         {
 743             for (map<int, set<string>>::iterator q = p->second.begin(); q != p->second.end(); ++q)
 744             {
 745                 if (q->first == get<1>(productionSet[p->first]).size())
 746                 {
 747                     for (set<string>::const_iterator m = q->second.cbegin(); m != q->second.cend(); ++m)
 748                     {
 749                         map<string, int>::iterator temp = symbolToIndex->find(*m);
 750                         if ((*LALRTablePtr)[i][temp->second].ActionType == LALRTableItem::action::MOVE)
 751                         {
 752                             cout << "ERROR:移入归约冲突" << endl;
 753                             cout << "状态" << i << "要求在文法符号" << temp->first << "下移入状态" << (*LALRTablePtr)[i][temp->second].LALRStateNumber;
 754                             cout << "同时状态" << i << "要求在文法符号" << temp->first << "下用产生式" << p->first << "归约" << endl;
 755                             continue;
 756                         }
 757                         else if ((*LALRTablePtr)[i][temp->second].ActionType == LALRTableItem::action::REDUCTION)
 758                         {
 759                             cout << "ERROR:归约归约冲突" << endl;
 760                             cout << "状态" << i << "要求在文法符号" << temp->first << "下用产生式" << (*LALRTablePtr)[i][temp->second].production << "归约" << endl;
 761                             cout << "同时状态" << i << "要求在文法符号" << temp->first << "下用产生式" << p->first << "归约" << endl;
 762                             continue;
 763                         }
 764                         (*LALRTablePtr)[i][temp->second].ActionType = LALRTableItem::action::REDUCTION;   //移入归约,归约归约冲突处理
 765                         (*LALRTablePtr)[i][temp->second].production = p->first;
 766                     }
 767                 }
 768             }
 769         }
 770 
 771         for (map<long, LALRState::attribute>::iterator temp = SetOfVertex[i]->Vertexdatafield->nonkernel.begin(); temp != SetOfVertex[i]->Vertexdatafield->nonkernel.end(); ++temp)
 772         {
 773             if (temp->second.dotposition == 0 && get<1>(productionSet[temp->first]).empty() == true)
 774             {
 775                 for (set<string>::const_iterator m = temp->second.ForwardLookingSign.cbegin(); m != temp->second.ForwardLookingSign.cend(); ++m)
 776                 {
 777                     map<string, int>::iterator temp1 = symbolToIndex->find(*m);
 778                     if ((*LALRTablePtr)[i][temp1->second].ActionType == LALRTableItem::action::MOVE)
 779                     {
 780                         cout << "ERROR:移入归约冲突" << endl;
 781                         cout << "状态" << i << "要求在文法符号" << temp1->first << "下移入状态" << (*LALRTablePtr)[i][temp1->second].LALRStateNumber;
 782                         cout << "同时状态" << i << "要求在文法符号" << temp1->first << "下用产生式" << temp->first << "归约" << endl;
 783                         continue;
 784                     }
 785                     else if ((*LALRTablePtr)[i][temp1->second].ActionType == LALRTableItem::action::REDUCTION)
 786                     {
 787                         cout << "ERROR:归约归约冲突" << endl;
 788                         cout << "状态" << i << "要求在文法符号" << temp1->first << "下用产生式" << (*LALRTablePtr)[i][temp1->second].production << "归约" << endl;
 789                         cout << "同时状态" << i << "要求在文法符号" << temp1->first << "下用产生式" << temp->first << "归约" << endl;
 790                         continue;
 791                     }
 792                     (*LALRTablePtr)[i][temp1->second].ActionType = LALRTableItem::action::REDUCTION;    //移入归约,归约归约冲突处理
 793                     (*LALRTablePtr)[i][temp1->second].production = temp->first;
 794                 }
 795             }
 796         }
 797     }
 798     (*LALRTablePtr)[((*LALRTablePtr)[start][(*symbolToIndex)[StartSymbol]].LALRStateNumber)][(*symbolToIndex)["$"]].ActionType = LALRTableItem::action::ACCEPT;  //向语法分析表中填入接受项
 799     accept = (*LALRTablePtr)[start][(*symbolToIndex)[StartSymbol]].LALRStateNumber;
 800     (*LALRTablePtr)[((*LALRTablePtr)[start][(*symbolToIndex)[StartSymbol]].LALRStateNumber)][(*symbolToIndex)["$"]].NULLLable = "";
 801     return { symbolToIndex, LALRTablePtr };  //返回LALR(1)语法分析表
 802 }
 803 
 804 void LALRAutomata::constructLRKernel()   //计算出的LR(0)项集族保存在继承而来的有向图中
 805 {
 806     struct Vertex
 807     {
 808         LALRState *state = new LALRState();
 809         vector<Graph<LALRState, string>::GraphVertexNode *>::size_type index = 0;   //LALR状态及其对应序号
 810         Vertex(LALRState *s, vector<Graph<LALRState, string>::GraphVertexNode *>::size_type i) :state(s), index(i) {}
 811         Vertex(const Vertex &copy)
 812         {
 813             state = new LALRState(*(copy.state));
 814             index = copy.index;
 815         }
 816         Vertex() = default;
 817         ~Vertex() { delete state; }
 818     };
 819     deque<Vertex> workqueue;
 820     workqueue.push_back(Vertex());
 821     workqueue.back().state->kernel.insert(make_pair(*(TerToPro[AugGraSS].begin()), map<int, set<string>>())).first->second.insert(make_pair(0, set<string>()));
 822     start = addVertex(new LALRState(*(workqueue.back().state)));
 823 
 824     while (workqueue.empty() == false)
 825     {
 826         calculateClosureLR(workqueue.front().state->kernel, workqueue.front().state->nonkernel);
 827         map<string, LALRState *> temp;
 828         for (map<long, map<int, set<string>>>::iterator p = workqueue.front().state->kernel.begin(); p != workqueue.front().state->kernel.end(); ++p)
 829         {
 830             for (map<int, set<string>>::iterator p2 = p->second.begin(); p2 != p->second.end(); ++p2)
 831             {
 832                 if (static_cast<vector<ProductionBodySymbol>::size_type>(p2->first) < get<1>(productionSet[p->first]).size())
 833                 {
 834                     map<string, LALRState *>::iterator q = temp.find(get<1>(productionSet[p->first])[p2->first].symbol);
 835                     if (q == temp.end())
 836                     {
 837                         q = temp.insert(make_pair(get<1>(productionSet[p->first])[p2->first].symbol, new LALRState())).first;
 838                     }
 839                     q->second->kernel.insert(make_pair(p->first, map<int, set<string>>())).first->second.insert(make_pair(p2->first + 1, set<string>()));
 840                 }
 841             }
 842         }
 843 
 844         for (map<long, LALRState::attribute>::iterator p = workqueue.front().state->nonkernel.begin(); p != workqueue.front().state->nonkernel.end(); ++p)
 845         {
 846             if (static_cast<vector<ProductionBodySymbol>::size_type>(p->second.dotposition) < get<1>(productionSet[p->first]).size())
 847             {
 848                 map<string, LALRState *>::iterator q = temp.find(get<1>(productionSet[p->first])[p->second.dotposition].symbol);
 849                 if (q == temp.end())
 850                 {
 851                     q = temp.insert(make_pair(get<1>(productionSet[p->first])[p->second.dotposition].symbol, new LALRState())).first;
 852                 }
 853                 q->second->kernel.insert(make_pair(p->first, map<int, set<string>>())).first->second.insert(make_pair(p->second.dotposition + 1, set<string>()));
 854             }
 855         }
 856 
 857 
 858         for (map<string, LALRState *>::iterator p = temp.begin(); p != temp.end(); )
 859         {
 860             vector<Graph<LALRState, string>::GraphVertexNode *>::size_type i = 0;
 861             for (; i < SetOfVertex.size(); ++i)
 862             {
 863                 map<long, map<int, set<string>>>::iterator left = p->second->kernel.begin();
 864                 map<long, map<int, set<string>>>::iterator right = SetOfVertex[i]->Vertexdatafield->kernel.begin();
 865                 while (left != p->second->kernel.end() && right != SetOfVertex[i]->Vertexdatafield->kernel.end())
 866                 {
 867                     if (left->first == right->first)
 868                     {
 869                         map<int, set<string>>::iterator inleft = left->second.begin();
 870                         map<int, set<string>>::iterator inright = right->second.begin();
 871                         while (inleft != left->second.end() && inright != right->second.end())
 872                         {
 873                             if (inleft->first == inright->first)
 874                             {
 875                                 ++inleft;
 876                                 ++inright;
 877                             }
 878                             else
 879                             {
 880                                 break;
 881                             }
 882                         }
 883                         if (inleft != left->second.end() || inright != right->second.end())
 884                             break;
 885                         ++left;
 886                         ++right;
 887                     }
 888                     else
 889                     {
 890                         break;
 891                     }
 892                 }
 893                 if (left == p->second->kernel.end() && right == SetOfVertex[i]->Vertexdatafield->kernel.end())
 894                 {
 895                     addEdge(workqueue.front().index, i, new string(p->first));
 896                     break;
 897                 }
 898             }
 899             if (i == SetOfVertex.size())
 900             {
 901                 vector<Graph<LALRState, string>::GraphVertexNode *>::size_type s = addVertex(new LALRState(*(p->second)));
 902                 addEdge(workqueue.front().index, s, new string(p->first));
 903                 workqueue.push_back(Vertex(p->second, s));
 904             }
 905             p = temp.erase(p);
 906         }
 907         workqueue.pop_front();
 908     }
 909 }
 910 
 911 void LALRAutomata::calculateClosureLR(map<long, map<int, set<string>>> &kernelset, map<long, LALRState::attribute> &nonkernelset)  //kernelset的arrtribute属性的ForwardLookingSign为空,nonkernelset同样,由内核项算出的闭包项保存在nonkernelset中
 912 {
 913     nonkernelset.clear();
 914     deque<pair<long, LALRState::attribute>> workqueue;
 915     for (map<long, map<int, set<string>>>::iterator m = kernelset.begin(); m != kernelset.end(); ++m)
 916     {
 917         for (map<int, set<string>>::iterator m2 = m->second.begin(); m2 != m->second.end(); ++m2)
 918         {
 919             workqueue.push_back(make_pair(m->first, LALRState::attribute(m2->first)));
 920         }
 921     }
 922 
 923     while (workqueue.empty() == false)
 924     {
 925         if (static_cast<vector<ProductionBodySymbol>::size_type>(workqueue.front().second.dotposition) < get<1>(productionSet[workqueue.front().first]).size())
 926         {
 927             if (get<1>(productionSet[workqueue.front().first])[workqueue.front().second.dotposition].TerminalOrNot == false)
 928             {
 929                 pair<long, LALRState::attribute> maxp = workqueue.front();
 930                 workqueue.pop_front();
 931                 for (set<long>::iterator m = TerToPro[get<1>(productionSet[maxp.first])[maxp.second.dotposition].symbol].begin(); m != TerToPro[get<1>(productionSet[maxp.first])[maxp.second.dotposition].symbol].end(); ++m)
 932                 {
 933                     map<long, LALRState::attribute>::iterator temp2 = nonkernelset.find(*m);
 934                     if (temp2 == nonkernelset.end())
 935                     {
 936                         temp2 = nonkernelset.insert(make_pair(*m, LALRState::attribute(0))).first;
 937                         workqueue.push_back(*temp2);
 938                     }
 939                 }
 940                 continue;
 941             }
 942         }
 943         workqueue.pop_front();
 944     }
 945 }
 946 
 947 void LALRAutomata::calculateClosureLALR(map<long, map<int, set<string>>> &kernelset, map<long, LALRState::attribute> &nonkernelset)
 948 {
 949     nonkernelset.clear();
 950     Priority_Queue<pair<long, LALRState::attribute>> workqueue(function<bool(const pair<long, LALRState::attribute>&, const pair<long, LALRState::attribute>&)>([](const pair<long, LALRState::attribute> &left, const pair<long, LALRState::attribute> &right)->bool {return left.first < right.first; }));  //使用lambda表达式根据产生式编号维护优先级队列
 951     for (map<long, map<int, set<string>>>::iterator m = kernelset.begin(); m != kernelset.end(); ++m)
 952     {
 953         for (map<int, set<string>>::iterator m2 = m->second.begin(); m2 != m->second.end(); ++m2)
 954         {
 955             workqueue.Insert(make_pair(m->first, LALRState::attribute(m2->first))).second->second.ForwardLookingSign.insert(m2->second.cbegin(), m2->second.cend());
 956         }
 957     }
 958 
 959     while (workqueue.isEmpty() == false)
 960     {
 961         if (static_cast<vector<ProductionBodySymbol>::size_type>(workqueue.begin()->second.dotposition) < get<1>(productionSet[workqueue.begin()->first]).size())
 962         {
 963             if (get<1>(productionSet[workqueue.begin()->first])[workqueue.begin()->second.dotposition].TerminalOrNot == false)
 964             {
 965                 shared_ptr<set<string>> temp = calculateFirst(get<1>(productionSet[workqueue.begin()->first]), workqueue.begin()->second.dotposition + 1, get<1>(productionSet[workqueue.begin()->first]).size() - 1);
 966                 if (temp->empty() == true)
 967                 {
 968                     temp->insert(workqueue.begin()->second.ForwardLookingSign.cbegin(), workqueue.begin()->second.ForwardLookingSign.cend());
 969                 }
 970                 else
 971                 {
 972                     if (*(temp->begin()) == "")
 973                     {
 974                         temp->erase(temp->begin());
 975                         temp->insert(workqueue.begin()->second.ForwardLookingSign.cbegin(), workqueue.begin()->second.ForwardLookingSign.cend());
 976                     }
 977                 }
 978 
 979                 pair<long, LALRState::attribute> maxp = *(workqueue.begin());
 980                 workqueue.erase(workqueue.begin());
 981                 for (set<long>::iterator m = TerToPro[get<1>(productionSet[maxp.first])[maxp.second.dotposition].symbol].begin(); m != TerToPro[get<1>(productionSet[maxp.first])[maxp.second.dotposition].symbol].end(); ++m)
 982                 {
 983                     map<long, LALRState::attribute>::iterator temp2 = nonkernelset.find(*m);
 984                     if (temp2 == nonkernelset.end())
 985                     {
 986                         temp2 = nonkernelset.insert(make_pair(*m, LALRState::attribute(0))).first;
 987                         temp2->second.ForwardLookingSign.insert(temp->cbegin(), temp->cend());
 988                         workqueue.Insert(*temp2);
 989                     }
 990                     else
 991                     {
 992                         set<string>::size_type q = temp2->second.ForwardLookingSign.size();
 993                         temp2->second.ForwardLookingSign.insert(temp->cbegin(), temp->cend());
 994                         if (temp2->second.ForwardLookingSign.size() != q)
 995                         {
 996                             Priority_Queue<pair<long, LALRState::attribute>>::iterator q2 = workqueue.Insert(*temp2).second;
 997                             if (q2 != workqueue.begin())
 998                             {
 999                                 --q2;
1000                                 if (q2->first == temp2->first)
1001                                 {
1002                                     if (q2->second.dotposition == 0 && q2->first != *(TerToPro[AugGraSS].begin()))
1003                                     {
1004                                         workqueue.erase(q2);
1005                                     }
1006                                 }
1007                             }
1008                         }
1009                     }
1010                 }
1011                 continue;
1012             }
1013         }
1014         workqueue.erase(workqueue.begin());
1015     }
1016 }
1017 
1018 bool LALRAutomata::isSubSet(const map<string, set<string>> &left, const set<string> &right)
1019 {
1020     map<string, set<string>>::const_iterator leftit = left.cbegin();
1021     set<string>::const_iterator rightit = right.cbegin();
1022 
1023     while (leftit != left.cend() && rightit != right.cend())
1024     {
1025         if (*rightit < leftit->first)
1026             return false;
1027         else if (*rightit > leftit->first)
1028         {
1029             ++leftit;
1030         }
1031         else
1032         {
1033             ++leftit;
1034             ++rightit;
1035         }
1036     }
1037 
1038     if (rightit != right.cend())
1039         return false;
1040     return true;
1041 
1042 }
1043 
1044 shared_ptr<map<string, set<string>>> LALRAutomata::calculateFollow()
1045 {
1046     shared_ptr<map<string, set<string>>> result = make_shared<map<string, set<string>>>();
1047     map<string, pair<set<string>, set<string>>> temp;
1048     {
1049         auto h = temp.insert(make_pair(AugGraSS, pair<set<string>, set<string>>())).first;
1050         h->second.first.insert("$");
1051     }
1052 
1053     for (map<long, tuple<string, vector<ProductionBodySymbol>, set<string>>>::iterator p = productionSet.begin(); p != productionSet.end(); ++p)
1054     {
1055         for (vector<ProductionBodySymbol>::size_type i = 0; i < get<1>(p->second).size(); ++i)
1056         {
1057             if (get<1>(p->second)[i].TerminalOrNot == false)
1058             {
1059                 if (i == get<1>(p->second).size() - 1)
1060                 {
1061                     map<string, pair<set<string>, set<string>>>::iterator it = temp.find(get<1>(p->second)[i].symbol);
1062                     if (it == temp.end())
1063                     {
1064                         temp.insert(make_pair(get<1>(p->second)[i].symbol, make_pair(set<string>(), set<string>()))).first->second.second.insert(get<0>(p->second));
1065                     }
1066                     else
1067                     {
1068                         it->second.second.insert(get<0>(p->second));
1069                     }
1070                 }
1071                 else
1072                 {
1073                     shared_ptr<set<string>> q = calculateFirst(get<1>(p->second), i + 1, get<1>(p->second).size() - 1);
1074                     set<string>::iterator w = q->find("");
1075                     map<string, pair<set<string>, set<string>>>::iterator it = temp.find(get<1>(p->second)[i].symbol);
1076                     if (w != q->end())
1077                     {
1078                         if (it == temp.end())
1079                         {
1080                             (it = temp.insert(make_pair(get<1>(p->second)[i].symbol, make_pair(set<string>(), set<string>()))).first)->second.second.insert(get<0>(p->second));
1081                         }
1082                         else
1083                         {
1084                             it->second.second.insert(get<0>(p->second));
1085                         }
1086                         it->second.first.insert(q->cbegin(), w);
1087                         it->second.first.insert(++w, q->end());
1088                     }
1089                     else
1090                     {
1091                         if (it == temp.end())
1092                         {
1093                             temp.insert(make_pair(get<1>(p->second)[i].symbol, make_pair(set<string>(), set<string>()))).first->second.first.insert(q->begin(), q->end());
1094                         }
1095                         else
1096                         {
1097                             it->second.first.insert(q->begin(), q->end());
1098                         }
1099                     }
1100                 }
1101             }
1102         }
1103     }
1104 
1105     for (map<string, pair<set<string>, set<string>>>::iterator p = temp.begin(); p != temp.end(); )
1106     {
1107         if (p->second.second.empty() == true)
1108         {
1109             result->insert(make_pair(p->first, p->second.first));
1110             p = temp.erase(p);
1111         }
1112         else
1113         {
1114             if (p->second.second.find(p->first) != p->second.second.end())
1115             {
1116                 p->second.second.erase(p->first);
1117                 if (p->second.second.empty() == true)
1118                 {
1119                     result->insert(make_pair(p->first, p->second.first));
1120                     p = temp.erase(p);
1121                     continue;
1122                 }
1123             }
1124             ++p;
1125         }
1126     }
1127 
1128     while (temp.empty() == false)
1129     {
1130         for (map<string, pair<set<string>, set<string>>>::iterator p = temp.begin(); p != temp.end();)
1131         {
1132             if (isSubSet(*(result), p->second.second))
1133             {
1134                 map<string, set<string>>::iterator m = result->insert(make_pair(p->first, set<string>())).first;
1135                 map<string, set<string>>::iterator itleft = result->begin();
1136                 set<string>::const_iterator itright = p->second.second.cbegin();
1137                 while (itleft != result->end() && itright != p->second.second.cend())
1138                 {
1139                     if (itleft->first == *itright)
1140                     {
1141                         m->second.insert(itleft->second.cbegin(), itleft->second.cend());
1142                         ++itleft;
1143                         ++itright;
1144                     }
1145                     else if (itleft->first < *itright)
1146                     {
1147                         ++itleft;
1148                     }
1149                     else
1150                     {
1151                         ++itright;
1152                     }
1153                 }
1154                 m->second.insert(p->second.first.cbegin(), p->second.first.cend());
1155                 p = temp.erase(p);
1156             }
1157             else
1158             {
1159                 ++p;
1160             }
1161         }
1162     }
1163     return result;
1164 }
1165 
1166 shared_ptr<map<string, set<string>>> LALRAutomata::calculateFirst()
1167 {
1168     shared_ptr<map<long, tuple<string, vector<ProductionBodySymbol>, set<string>>>> temp = make_shared<map<long, tuple<string, vector<ProductionBodySymbol>, set<string>>>>(productionSet);
1169     shared_ptr<map<string, set<string>>> result = make_shared<map<string, set<string>>>();
1170 
1171     for (map<long, tuple<string, vector<ProductionBodySymbol>, set<string>>>::iterator p = temp->begin(); p != temp->end(); )
1172     {
1173         if (get<2>(p->second).empty() == true)
1174         {
1175             map<string, set<string>>::iterator q = result->find(get<0>(p->second));
1176             if (q == result->end())
1177             {
1178                 if (get<1>(p->second).empty())
1179                 {
1180                     result->insert(make_pair(get<0>(p->second), set<string>())).first->second.insert("");
1181                 }
1182                 else
1183                 {
1184                     result->insert(make_pair(get<0>(p->second), set<string>())).first->second.insert(get<1>(p->second)[0].symbol);
1185                 }
1186             }
1187             else
1188             {
1189                 if (get<1>(p->second).empty())
1190                 {
1191                     q->second.insert("");
1192                 }
1193                 else
1194                 {
1195                     q->second.insert(get<1>(p->second)[0].symbol);
1196                 }
1197             }
1198             p = temp->erase(p);
1199         }
1200         else
1201         {
1202             ++p;
1203         }
1204     }
1205     while (true)
1206     {
1207         bool stopOrNot = true;
1208         for (map<long, tuple<string, vector<ProductionBodySymbol>, set<string>>>::iterator p = temp->begin(); p != temp->end(); ++p)
1209         {
1210             if (isSubSet(*result, get<2>(p->second)) == true)
1211             {
1212                 for (vector<ProductionBodySymbol>::size_type q = 0; q < get<1>(p->second).size(); ++q)
1213                 {
1214                     if (get<1>(p->second)[q].TerminalOrNot == true)
1215                     {
1216                         map<string, set<string>>::iterator v = result->find(get<0>(p->second));
1217                         if (v == result->end())
1218                         {
1219                             result->insert(make_pair(get<0>(p->second), set<string>())).first->second.insert(get<1>(p->second)[q].symbol);
1220                             stopOrNot = false;
1221                         }
1222                         else
1223                         {
1224                             if (v->second.insert(get<1>(p->second)[q].symbol).second == true)
1225                                 stopOrNot = false;
1226                         }
1227                         break;
1228                     }
1229                     else
1230                     {
1231                         set<string>::const_iterator m;
1232                         if ((m = (*result)[get<1>(p->second)[q].symbol].find("")) == (*result)[get<1>(p->second)[q].symbol].cend())
1233                         {
1234                             map<string, set<string>>::iterator v = result->find(get<0>(p->second));
1235                             if (v == result->end())
1236                             {
1237                                 result->insert(make_pair(get<0>(p->second), set<string>())).first->second.insert((*result)[get<1>(p->second)[q].symbol].cbegin(), (*result)[get<1>(p->second)[q].symbol].cend());
1238                                 stopOrNot = false;
1239                             }
1240                             else
1241                             {
1242                                 if (get<0>(p->second) != get<1>(p->second)[q].symbol)
1243                                 {
1244                                     for (const string &item : (*result)[get<1>(p->second)[q].symbol])
1245                                     {
1246                                         if (v->second.insert(item).second == true)
1247                                         {
1248                                             stopOrNot = false;
1249                                         }
1250                                     }
1251                                 }
1252                             }
1253                             break;
1254                         }
1255                         else
1256                         {
1257                             map<string, set<string>>::iterator v = result->find(get<0>(p->second));
1258                             if (v == result->end())
1259                             {
1260                                 (v = result->insert(make_pair(get<0>(p->second), set<string>())).first)->second.insert((*result)[get<1>(p->second)[q].symbol].cbegin(), m);
1261                                 v->second.insert(++m, (*result)[get<1>(p->second)[q].symbol].cend());
1262                                 stopOrNot = false;
1263                             }
1264                             else
1265                             {
1266                                 if (get<0>(p->second) != get<1>(p->second)[q].symbol)
1267                                 {
1268                                     set<string>::iterator item = (*result)[get<1>(p->second)[q].symbol].cbegin();
1269                                     for (; item != m; ++item)
1270                                     {
1271                                         if (v->second.insert(*item).second == true)
1272                                         {
1273                                             stopOrNot = false;
1274                                         }
1275                                     }
1276 
1277                                     for (++item; item != (*result)[get<1>(p->second)[q].symbol].cend(); ++item)
1278                                     {
1279                                         if (v->second.insert(*item).second == true)
1280                                         {
1281                                             stopOrNot = false;
1282                                         }
1283                                     }
1284                                 }
1285                             }
1286                         }
1287                     }
1288                 }
1289             }
1290             else
1291             {
1292                 stopOrNot = false;
1293             }
1294         }
1295         if (stopOrNot == true)
1296             break;
1297     }
1298     return result;
1299 
1300 }
1301 
1302 shared_ptr<set<string>> LALRAutomata::calculateFirst(const vector<ProductionBodySymbol> &Pro, vector<ProductionBodySymbol>::size_type left, vector<ProductionBodySymbol>::size_type right)
1303 {
1304     shared_ptr<set<string>> result = make_shared<set<string>>();
1305     if (left <= right)
1306     {
1307         for (vector<ProductionBodySymbol>::size_type temp = left; temp <= right; ++temp)
1308         {
1309             if (Pro[temp].TerminalOrNot == true)
1310             {
1311                 result->insert(Pro[temp].symbol);
1312                 return result;
1313             }
1314             else
1315             {
1316                 set<string>::const_iterator p;
1317                 if ((p = (*first)[Pro[temp].symbol].find("")) == (*first)[Pro[temp].symbol].cend())
1318                 {
1319                     result->insert((*first)[Pro[temp].symbol].cbegin(), (*first)[Pro[temp].symbol].cend());
1320                     return result;
1321                 }
1322                 else
1323                 {
1324                     result->insert((*first)[Pro[temp].symbol].cbegin(), p);
1325                     result->insert(++p, (*first)[Pro[temp].symbol].cend());
1326                 }
1327             }
1328         }
1329         result->insert("");
1330     }
1331     return result;
1332 }
1333 
1334 void output(LALRAutomata &test, ofstream &output)  //将语法分析表,LALR自动机状态和其他文法信息输出至文件
1335 {
1336     cout << "非终结符:";
1337     output << "非终结符:,";
1338     for (set<string>::iterator temp = test.Nonterminal.begin(); temp != test.Nonterminal.end(); ++temp)
1339     {
1340         cout << *temp << " ";
1341         output << *temp << ",";
1342     }
1343     cout << endl;
1344     output << endl;
1345     cout << "终结符:";
1346     output << "终结符:,";
1347     for (set<string>::iterator temp = test.terminnal.begin(); temp != test.terminnal.end(); ++temp)
1348     {
1349         cout << *temp << " ";
1350         output << *temp << ",";
1351     }
1352     cout << endl;
1353     output << endl;
1354     cout << "原文法开始符号:" << test.StartSymbol << endl;
1355     output << "原文法开始符号:," << test.StartSymbol << endl;
1356     cout << "增广文法开始符号:" << test.AugGraSS << endl;
1357     output << "增广文法开始符号:," << test.AugGraSS << endl;
1358     cout << endl;
1359     output << endl;
1360     cout << "产生式:" << endl;
1361     output << "产生式:" << endl;
1362     for (map<long, tuple<string, vector<LALRAutomata::ProductionBodySymbol>, set<string>>>::iterator temp = test.productionSet.begin(); temp != test.productionSet.end(); ++temp)
1363     {
1364         cout << "产生式" << temp->first << ":";
1365         output << "产生式" << temp->first << ":,";
1366         cout << get<0>(temp->second) << "->";
1367         output << get<0>(temp->second) << ",->,";
1368         for (auto p = get<1>(temp->second).begin(); p != get<1>(temp->second).end(); ++p)
1369         {
1370             cout << p->symbol;
1371             output << p->symbol << ",";
1372         }
1373         cout << "非终结符号集合:";
1374         output << ",非终结符号集合:,";
1375         if (get<2>(temp->second).begin() == get<2>(temp->second).end())
1376         {
1377             cout << "";
1378             output << "无,";
1379         }
1380         for (set<string>::iterator p = get<2>(temp->second).begin(); p != get<2>(temp->second).end(); ++p)
1381         {
1382             cout << *p << " ";
1383             output << *p << ",";
1384         }
1385         cout << endl;
1386         output << endl;
1387     }
1388 
1389     cout << endl;
1390     output << endl;
1391     cout << "非终结符号对应的产生式编号:" << endl;
1392     output << "非终结符号对应的产生式编号:" << endl;
1393     for (map<string, set<long>>::iterator temp = test.TerToPro.begin(); temp != test.TerToPro.end(); ++temp)
1394     {
1395         cout << "非终结符号:" << temp->first << " ";
1396         output << "非终结符号:" << temp->first << ",";
1397         for (set<long>::iterator p = temp->second.begin(); p != temp->second.end(); ++p)
1398         {
1399             cout << *p << " ";
1400             output << *p << ",";
1401         }
1402         cout << endl;
1403         output << endl;
1404     }
1405 
1406     cout << endl;
1407     output << endl;
1408     cout << "各非终结符first集:" << endl;
1409     output << "各非终结符first集:" << endl;
1410     for (map<string, set<string>>::iterator temp = test.first->begin(); temp != test.first->end(); ++temp)
1411     {
1412         cout << "非终结符" << temp->first << ":";
1413         output << "非终结符" << temp->first << ":,";
1414         for (set<string>::iterator p = temp->second.begin(); p != temp->second.end(); ++p)
1415         {
1416             cout << *p << " ";
1417             output << *p << ",";
1418         }
1419         cout << endl;
1420         output << endl;
1421     }
1422 
1423     cout << endl;
1424     output << endl;
1425     cout << "各非终结符follow集:" << endl;
1426     output << "各非终结符follow集:" << endl;
1427     for (map<string, set<string>>::iterator temp = test.follow->begin(); temp != test.follow->end(); ++temp)
1428     {
1429         cout << "非终结符" << temp->first << ":";
1430         output << "非终结符" << temp->first << ":,";
1431         for (set<string>::iterator p = temp->second.begin(); p != temp->second.end(); ++p)
1432         {
1433             cout << *p << " ";
1434             output << *p << ",";
1435         }
1436         cout << endl;
1437         output << endl;
1438     }
1439 
1440     cout << endl;
1441     output << endl;
1442     cout << "LALR自动机状态:" << endl;
1443     output << "LALR自动机状态:" << endl;
1444     for (vector<Graph<LALRState, string>::GraphVertexNode *>::size_type i = 0; i < test.SetOfVertex.size(); ++i)
1445     {
1446         cout << "状态" << i << ":" << endl;
1447         output << "状态" << i << ":" << endl;
1448         for (auto p = test.SetOfVertex[i]->Vertexdatafield->kernel.begin(); p != test.SetOfVertex[i]->Vertexdatafield->kernel.end(); ++p)
1449         {
1450             cout << "产生式" << p->first << ":" << get<0>(test.productionSet[p->first]) << "->";
1451             output << "产生式" << p->first << ":," << get<0>(test.productionSet[p->first]) << ",->,";
1452             for (auto m = get<1>(test.productionSet[p->first]).begin(); m != get<1>(test.productionSet[p->first]).end(); ++m)
1453             {
1454                 cout << m->symbol;
1455                 output << m->symbol << ",";
1456             }
1457             cout << endl;
1458             output << endl;
1459             for (auto m = p->second.begin(); m != p->second.end(); ++m)
1460             {
1461                 cout << "点号位置" << m->first << " ";
1462                 output << "点号位置" << m->first << ",";
1463                 cout << "向前看符号集合 ";
1464                 output << "向前看符号集合,";
1465                 for (auto v = m->second.begin(); v != m->second.end(); ++v)
1466                 {
1467                     cout << *v << " ";
1468                     output << *v << ",";
1469                 }
1470                 cout << endl;
1471                 output << endl;
1472             }
1473         }
1474 
1475         for (auto p = test.SetOfVertex[i]->Vertexdatafield->nonkernel.begin(); p != test.SetOfVertex[i]->Vertexdatafield->nonkernel.end(); ++p)
1476         {
1477             cout << "产生式" << p->first << ":" << get<0>(test.productionSet[p->first]) << "->";
1478             output << "产生式" << p->first << ":," << get<0>(test.productionSet[p->first]) << ",->,";
1479             for (auto m = get<1>(test.productionSet[p->first]).begin(); m != get<1>(test.productionSet[p->first]).end(); ++m)
1480             {
1481                 cout << m->symbol;
1482                 output << m->symbol << ",";
1483             }
1484             cout << endl;
1485             output << endl;
1486             cout << "点号位置" << p->second.dotposition << " ";
1487             output << "点号位置" << p->second.dotposition << ",";
1488             cout << "向前看符号集合 ";
1489             output << "向前看符号集合,";
1490             for (auto v = p->second.ForwardLookingSign.begin(); v != p->second.ForwardLookingSign.end(); ++v)
1491             {
1492                 cout << *v << " ";
1493                 output << *v << ",";
1494             }
1495             cout << endl;
1496             output << endl;
1497         }
1498     }
1499 
1500     cout << endl;
1501     output << endl;
1502     cout << "LALR语法分析表:" << endl;
1503     output << "LALR语法分析表:" << endl;
1504     vector<string> temp(test.LALRTable.first->size());
1505     for (auto p = test.LALRTable.first->begin(); p != test.LALRTable.first->end(); ++p)
1506     {
1507         temp[p->second] = p->first;
1508     }
1509     output << " ,";
1510     for (const auto &m : temp)
1511     {
1512         cout << m << " ";
1513         output << m << ",";
1514     }
1515     cout << endl;
1516     output << endl;
1517     for (vector<vector<LALRTableItem>>::size_type i = 0; i < test.LALRTable.second->size(); ++i)
1518     {
1519         cout << "状态" << i << " ";
1520         output << "状态" << i << ",";
1521         for (const auto &m : (*(test.LALRTable.second))[i])
1522         {
1523             if (m.ActionType == m.MOVE)
1524             {
1525                 cout << "m" << m.LALRStateNumber << " ";
1526                 output << "m" << m.LALRStateNumber << ",";
1527             }
1528             else if (m.ActionType == m.REDUCTION)
1529             {
1530                 cout << "r" << m.production << " ";
1531                 output << "r" << m.production << ",";
1532             }
1533             else if (m.ActionType == m.ACCEPT)
1534             {
1535                 cout << "A ";
1536                 output << "A,";
1537             }
1538             else
1539             {
1540                 cout << "ERR ";
1541                 output << "ERR,";
1542             }
1543         }
1544         cout << endl;
1545         output << endl;
1546     }
1547 }
1548 int main()
1549 {
1550     ifstream input("inputexample1.txt");   //文法描述
1551     ofstream dataoutput("output.txt");   //输出结果
1552     LALRAutomata test(input);  //根据和input绑定的文法描述生成LALR(1)语法分析信息
1553     output(test, dataoutput);  //将语法分析信息输出至和dataoutput绑定的文件
1554     return 0;
1555 }
LALR(1)语法分析表的构造

注意,这里有两个头文件Priority_Queue.h和assistfunction.h。Priority_Queue.h存放的是博主自己实现的优先级队列类,之所以没有使用标准库提供的容器适配器是因为适配器实现的优先级队列缺少一些操作队列成员的必要方法,如以下代码中的begin(),end()且容器适配器提供的接口的调用约定和返回值不符号程序编写要求,此外优先级队列是用堆实现的,但计算LALR闭包的算法要求优先队列必须用数组实现,其成员按优先级从小到大排序,故楼主自行实现了优先级队列。Priority_Queue.h代码如下:

技术分享图片
  1 #include <iostream>
  2 #include <list>
  3 #include <functional>
  4 using namespace std;
  5 
  6 template <typename T>
  7 class Priority_Queue    //设备等待队列类(优先级队列),队列数据元素为t
  8 {
  9 public:
 10     typedef typename list<T>::iterator iterator;
 11     Priority_Queue() = default;
 12     Priority_Queue(const function<bool(const T&,const T&)> &com) :comparator(com) {}
 13     ~Priority_Queue() = default;
 14     pair<bool, typename Priority_Queue<T>::iterator> Insert(const T &x);  //插入操作,返回的pair的first指示插入是否成功,second为指向插入元素的迭代器
 15     bool RemoveTop(T &x);     //删除最高优先级元素并用x将其返回
 16     bool GetTop(T &x) const;  //获取最高优先级元素并用x将其返回 
 17     void MakeEmpty() { Queue.clear(); }    //清空队列
 18     bool isEmpty() const { return Queue.empty(); }   //判断队列是否为空
 19     bool isFull() const { return Queue.size() == Queue.max_size(); }   //判断队列是否已满
 20     typename Priority_Queue<T>::iterator erase(const typename Priority_Queue<T>::iterator &p) { return Queue.erase(p); }  //删除队列中p所指元素返回被删元素的下一元素
 21     typename Priority_Queue<T>::iterator insert(const typename Priority_Queue<T>::iterator &p, const T &c) { return Queue.insert(p, c); }  //将c插入至p所指位置,返回指向插入元素的迭代器
 22     typename list<T>::size_type  GetSize() const { return Queue.size(); }   //获取队列实际大小
 23     iterator begin() { return Queue.begin(); }   //获取指向队列最高优先级元素的迭代器
 24     iterator end() { return Queue.end(); }   //获取队列尾后迭代器
 25 
 26 private:
 27     function<bool(const T&, const T&)> comparator;  //比较T类型的可调用对象,左操作数小于右操作数返回true
 28     typename list<T>::iterator adjust();   //新元素加入队列后调整元素位置,使队列中各元素保持优先级关系
 29     list<T> Queue;
 30 };
 31 
 32 template <typename T>
 33 typename list<T>::iterator Priority_Queue<T>::adjust()
 34 {
 35     T temp = Queue.back();
 36     auto p = Queue.end();
 37     --p;
 38     p = Queue.erase(p);
 39 
 40     if (Queue.begin() != p)
 41         --p;
 42     else
 43     {
 44         return Queue.insert(p, temp);
 45     }
 46 
 47     while (true)
 48     {
 49         if (comparator(temp, (*p)))
 50         {
 51             if (p != Queue.begin())
 52             {
 53                 --p;
 54                 if (p == Queue.begin())
 55                     continue;
 56             }
 57         }
 58         else
 59         {
 60             ++p;
 61             return Queue.insert(p, temp);
 62         }
 63 
 64         if (p == Queue.begin())
 65             break;
 66     }
 67     return Queue.insert(p, temp);
 68 }
 69 
 70 template <typename T>
 71 pair<bool, typename Priority_Queue<T>::iterator> Priority_Queue<T>::Insert(const T &x)
 72 {
 73     if (isFull())
 74         return { false, end() };
 75     else
 76     {
 77         Queue.push_back(x);
 78         return { true, adjust() };
 79     }
 80 }
 81 
 82 template <typename T>
 83 bool Priority_Queue<T>::RemoveTop(T &x)
 84 {
 85     if (isEmpty())
 86         return false;
 87     else
 88     {
 89         x = Queue.front();
 90         Queue.pop_front();
 91         return true;
 92     }
 93 }
 94 
 95 template <typename T>
 96 bool Priority_Queue<T>::GetTop(T &x) const
 97 {
 98     if (isEmpty())
 99         return false;
100     else
101     {
102         x = Queue.front();
103         return true;
104     }
105 }
优先级队列实现

头文件assistfunction.h中定义了一些算法需要使用的辅助例程(只有第一个函数和算法有关,其他例程用于正则表达式引擎,后续会解读),由于代码简洁易懂,不是很重要,这里就不详细解说了。

技术分享图片
 1 #include<set>
 2 #include<map>
 3 #include<string>
 4 void setToMap(const set<string> &source, map<string, int> &goal, int &count)
 5 {
 6     for (set<string>::iterator p = source.cbegin(); p != source.cend(); ++p)
 7     {
 8         goal.insert(make_pair(*p, count++));
 9     }
10 }
11 
12 char strToChar(const string &m)
13 {
14     if (m.size() == 1)
15         return m[0];
16     else if (m.size() == 2)
17     {
18         switch (m[1])
19         {
20         casef:    return f;
21         casen:    return 
;
22         caser:    return 
;
23         caset:    return	;
24         casev:    returnv;
25         case^:    return^;
26         case-:    return-;
27         case\:    return\;
28         case*:    return*;
29         case+:    return+;
30         case?:    return?;
31         case$:    return$;
32         case.:    return.;
33         case(:    return(;
34         case):    return);
35         case::    return:;
36         case=:    return=;
37         case!:    return!;
38         case<:    return<;
39         case|:    return|;
40         case[:    return[;
41         case]:    return];
42         case{:    return{;
43         case}:    return};
44         }
45     }
46 }
47 
48 void insertIntoSet(map<size_t, set<size_t>> &beinserted, const size_t &source, const size_t &goal)
49 {
50     map<size_t, set<size_t>>::iterator it = beinserted.find(goal);
51     if (it == beinserted.end())
52     {
53         beinserted.insert(make_pair(goal, set<size_t>())).first->second.insert(source);
54     }
55     else
56     {
57         it->second.insert(source);
58     }
59 }
60 
61 void insertIntoMap(map<size_t, set<size_t>> &beinserted, map<size_t, map<size_t, set<size_t>>> &from)
62 {
63     for (map<size_t, map<size_t, set<size_t>>>::iterator p = from.begin(); p != from.end(); ++p)
64     {
65         for (map<size_t, set<size_t>>::iterator q = p->second.begin(); q != p->second.end(); ++q)
66         {
67             map<size_t, set<size_t>>::iterator m = beinserted.find(q->first);
68             if (m == beinserted.end())
69             {
70                 beinserted.insert(make_pair(q->first, set<size_t>(q->second)));
71             }
72             else
73             {
74                 m->second.insert(q->second.begin(), q->second.end());
75             }
76         }
77     }
78 }
79 
80 void insertIntoMap(map<size_t, map<size_t, map<size_t, size_t>>> &end, size_t substart, size_t subend, size_t sub_start_stackindex, size_t sub_end_stackindex)
81 {
82     map<size_t, map<size_t, map<size_t, size_t>>>::iterator p = end.find(subend);
83     if (p == end.end())
84     {
85         end.insert(make_pair(subend, map<size_t, map<size_t, size_t>>())).first->second.insert(make_pair(substart, map<size_t, size_t>())).first->second.insert(make_pair(sub_start_stackindex, sub_end_stackindex));
86     }
87     else
88     {
89         map<size_t, map<size_t, size_t>>::iterator q = p->second.find(substart);
90         if (q == p->second.end())
91         {
92             p->second.insert(make_pair(substart, map<size_t, size_t>())).first->second.insert(make_pair(sub_start_stackindex, sub_end_stackindex));
93         }
94         else
95         {
96             q->second[sub_start_stackindex] = sub_end_stackindex;
97         }
98     }
99 }
辅助例程

 程序的使用方法请参看main函数中的注释,分析结果会输出至指定文件,文件中加入了必要的逗号分隔符,将其扩展名改为csv用excel打开即可看到经整理的分析结果,如果文法不是LALR(1)的,程序运行时在命令行窗口上会打印语法分析动作冲突的相关信息。注意如果自定义文法进行测试文法需设计合理,避免存在逻辑错误,否则程序可能会陷入死循环或抛出异常。博主给出的示例文法可以得到分析结果且无语法分析冲突,可以把示例文法拷贝至输入文件中测试。

PS:本人微信号memoryundersun,欢迎各位同仁主动联系我,大家一起学习一起进步
















































































以上是关于编译器构造中自底向上的LALR语法分析的语法分析表生成的实现的主要内容,如果未能解决你的问题,请参考以下文章

编译原理语法分析之自底向上分析之算符优先分析法

编译原理语法分析

编译原理语法分析

编译原理自底向上分析之LR分析法

编译原理语法分析

编译原理语法分析