首页 > 解决方案 > 向解析器/解释器添加故意的歧义

问题描述

我编写了一个解析器,它可以正确地接受一个表达式并从中创建一个 AST。然后,我的解释器获取该 AST,对其进行评估,然后返回一个解决方案。但是,我希望解析器(或解释器)解释表达式中的歧义(缺少括号)。

例如,如果我将 R ∩ G - B 之类的东西写成表达式,我希望看到 (R ∩ G) - B 和 R ∩ (G - B) 返回的 AST。在解析表达式时,我已经看到了许多消除歧义的解决方案,但我希望能够看到表达式的所有可能解释。

这是我的解析器类的一个片段:

    def eat(self, token_type):
        if self.current_token.type == token_type:
            self.current_token = self.lexer.get_next_token()
        else:
            self.error()

    def factor(self):
        token = self.current_token

        if token.type in (COLOR, EMPTY_S, UNIVERSE_OP):
            self.eat(token.type)
            return Num(token)
        elif token.type == L_PAREN:
            self.eat(L_PAREN)
            node = self.expr()
            self.eat(R_PAREN)
            return node

    def term(self):
        node = self.factor()

        while self.current_token.type is COMPLIMENT:
            token = self.current_token
            self.eat(COMPLIMENT)

            node = BinOp(left = node, op = token, right = self.expr())

        return node

    def expr(self):
        node = self.term()

        while self.current_token.type in (UNION, INTERSECT, MINUS, SUBSET, EQUALS):
            token = self.current_token

            if token.type == UNION:
                self.eat(UNION)
            elif token.type == INTERSECT:
                self.eat(INTERSECT)
            elif token.type == MINUS:
                self.eat(MINUS)
            elif token.type == SUBSET:
                self.eat(SUBSET)
            elif token.type == EQUALS:
                self.eat(EQUALS)

            else:
                self.error()

            node = BinOp(left = node, op = token, right = self.expr())

        return node

    def parse(self):
        return self.expr()

使用我当前的设置,解析器将只返回 R ∩ (G - B) 的 AST。

标签: pythonalgorithmparsingabstract-syntax-treeinterpreter

解决方案


对于模棱两可的语法,有一些解析算法会找到解析给定字符串的所有可能方法:Earley、CYK、Tomita、GLR、GLL。但是它们都与您现在拥有的递归下降解析器相去甚远。(GLL 声称是递归下降的,但这似乎有点牵强。)


推荐阅读