语法和自上而下解析

时间:2017-02-10 19:54:13

标签: parsing grammar topdown

有一段时间我一直在努力学习LL解析器是如何工作的,如果我理解正确的话,当手动编写自上而下的递归下降解析器时,我应该为每个非终端符号创建一个函数。所以对于这个例子:

Imputer()

我必须为每个S,A,B和D创建一个函数,如下所示:

S -> AB
A -> aA|ε
B -> bg|dDe
D -> ab|cd

然后我尝试使用我创建的以下语法来生成相同的语言,以生成与(a | b | c)*正则表达式相同的语言:

Token B()
{
    if (Lookahead(1) == 'b')
    {
        Eat('b');
        Eat('g');
    }
    else if (Lookahead(1) == 'd')
    {
        Eat('d');
        D();
        Eat('e');
    }
    else
    {
        Error();
    }

    return B_TOKEN;
}

这给了我以下功能:

S -> Ma
M -> aM|bM|cM|ε

它似乎并不好,因为输入'bbcaa'M将消耗所有内容,之后S将找不到最后一个'a'并报告错误,即使语法接受它。感觉M缺少ε案例,或者可能是以错误的方式处理,但我不知道如何处理它。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:2)

自上而下预测解析器的行为与您在问题中记下的完全一样。换句话说,你的第二个语法不适合自上而下的解析(使用一个令牌前瞻)。许多语法不是;其中包括无法根据有限前瞻预测要使用哪种生产的任何语法。

在这种情况下,如果您要预测两个令牌而不是一个令牌,您可以解决冲突; from uitest import Ui_MainWindow from PyQt5.QtWidgets import ( QApplication, QMainWindow, QLabel, QTreeWidgetItem, ) MENUS = ... class window(QMainWindow): def __init__(self, parent=None): super(window, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.loadMenus(MENUS) self.ui.Menutree.itemChanged.connect(self.handleItemChanged) def loadMenus(self, menus): def recurse(parent, items): for text, children in items: item = QTreeWidgetItem(parent) item.setText(0, text) item.setCheckState(0, Qt.Checked) recurse(item, children) recurse(self.ui.Menutree, menus) self.ui.Menutree.expandAll() def handleItemChanged(self, item, column): def recurse(parent, state): for index in range(parent.childCount()): child = parent.child(index) # child.setCheckState(0, state) child.setDisabled(state == Qt.Unchecked) recurse(child, state) recurse(item, item.checkState(0)) if __name__ == "__main__": app = QApplication(['']) gui = window() gui.show() app.exec_() 应该预测前瞻 a END 上的M生成,以及所有其他双令牌前瞻中的ε生成第一个标记是 a