首先,如果您还没有阅读过,您应该阅读 McPeak 关于 GLR 的论文http://www.cs.berkeley.edu/~smcpeak/papers/elkhound_cc04.ps。这是一篇学术论文,但它提供了有关 GSS、GLR 以及用于实现它们的技术的详细信息。它还解释了实现 GLR 解析器的一些棘手问题。
您需要三个部分来实现图形结构的堆栈。
一、图数据结构本身
二、堆栈
三、GLR 对 GSS 的使用
你是对的,谷歌没有多大帮助。除非您喜欢阅读算法书籍,否则它们也不会有太大帮助。
一、图数据结构
Rob 关于“直接表示”的回答将最容易实现。它很像一个链表,除了每个节点都有一个下一个节点的列表,而不仅仅是一个。
此数据结构是有向图,但正如 McPeak 所述,GSS 可能具有用于 epsilon-grammars 的循环。
二、堆栈
图结构堆栈在概念上只是常规堆栈的列表。对于明确的语法,您只需要一个堆栈。当存在解析冲突时,您需要更多堆栈,以便您可以同时执行两个解析操作并保持两个操作创建的不同状态。使用图表可以让您利用这些堆栈共享元素的事实。
首先了解如何使用链表实现单个堆栈可能会有所帮助。链表的头部是栈顶。将元素压入堆栈只是创建一个新头并将其指向旧头。从堆栈中弹出一个元素只是将指针移动到 head->next。
在 GSS 中,原理是相同的。推送一个元素只是创建一个新的头节点并将其指向旧的头。如果您有两个移位操作,您会将两个元素推送到旧头上,然后有两个头节点。从概念上讲,这只是两个不同的堆栈,它们共享除顶部元素之外的每个元素。弹出一个元素只是通过跟随每个下一个节点将头指针向下移动到堆栈中。
三、GLR 对 GSS 的使用
这就是 McPeak 的论文值得一读的地方。
GLR 算法通过合并具有相同状态元素的堆栈头来利用 GSS。这意味着一个状态元素可能有多个孩子。在归约时,GLR 算法必须从栈头探索所有可能的路径。
您可以通过保持每个节点的确定性深度来优化 GLR。这只是与堆栈中拆分的距离。这样您就不必总是搜索堆栈拆分。
这是一项艰巨的任务!祝你好运!