Exemple #1
0
 def set_parse_action_magic(rule_name: str, parser_element: pp.ParserElement) -> None:
     if rule_name == rule_name.upper():
         return
     if getattr(parser_element, 'name', None) and parser_element.name.isidentifier():
         rule_name = parser_element.name
     if rule_name in ('bin_op', ):
         def bin_op_parse_action(s, loc, tocs):
             node = tocs[0]
             if not isinstance(node, AstNode):
                 node = bin_op_parse_action(s, loc, node)
             for i in range(1, len(tocs) - 1, 2):
                 second_node = tocs[i + 1]
                 if not isinstance(second_node, AstNode):
                     second_node = bin_op_parse_action(s, loc, second_node)
                 node = BinOpNode(BinOp(tocs[i]), node, second_node, loc=loc)
             return node
         parser_element.setParseAction(bin_op_parse_action)
     else:
         cls = ''.join(x.capitalize() for x in rule_name.split('_')) + 'Node'
         with suppress(NameError):
             cls = eval(cls)
             if not inspect.isabstract(cls):
                 def parse_action(s, loc, tocs):
                     if cls is FuncNode:
                         return FuncNode(tocs[0], tocs[1], tocs[2:-1], tocs[-1], loc=loc)
                     else:
                         return cls(*tocs, loc=loc)
                 parser_element.setParseAction(parse_action)
Exemple #2
0
 def set_parse_action_magic(rule_name: str, parser: pp.ParserElement)->None:
     if rule_name == rule_name.upper():
         return
     if getattr(parser, 'name', None) and parser.name.isidentifier():
         rule_name = parser.name
     if rule_name in ('bin_op', ):
         def bin_op_parse_action(s, loc, tocs):
             node = tocs[0]
             if not isinstance(node, AstNode):
                 node = bin_op_parse_action(s, loc, node)
             for i in range(1, len(tocs) - 1, 2):
                 secondNode = tocs[i + 1]
                 if not isinstance(secondNode, AstNode):
                     secondNode = bin_op_parse_action(s, loc, secondNode)
                 node = BinOpNode(BinOp(tocs[i]), node, secondNode)
             return node
         parser.setParseAction(bin_op_parse_action)
     else:
         cls = ''.join(x.capitalize() for x in rule_name.split('_')) + 'Node' #разбитие названия переменной на куски по _, создание заглавной первой буквы и прибавление Node
         with suppress(NameError):
             cls = eval(cls)
             if not inspect.isabstract(cls):
                 def parse_action(s, loc, tocs):
                     return cls(*tocs)
                 parser.setParseAction(parse_action)
Exemple #3
0
    def set_parse_action_magic(rule_name: str,
                               parser: pp.ParserElement) -> None:
        if rule_name == rule_name.upper():
            return
        if rule_name in ('mult', 'add', 'cond', 'cond_list'):

            def bin_op_parse_action(s, loc, tocs):
                node = tocs[0]
                for i in range(1, len(tocs) - 1, 2):
                    node = BOperNode(BinOperation(tocs[i]), node, tocs[i + 1])
                return node

            parser.setParseAction(bin_op_parse_action)
        else:
            cls = ''.join(x.capitalize() or '_'
                          for x in rule_name.split('_')) + 'Node'
            with suppress(NameError):
                cls = eval(cls)
                parser.setParseAction(lambda s, loc, tocs: cls(*tocs))
Exemple #4
0
 def __set_parse_action(self, rule_name: str, rule: pp.ParserElement):
     """ Этот метод задаёт то, какой конструктор вызывается при успешном распознавании правила грамматики. """
     # если rule_name написан КАПСОМ, то никаких действий совершать не нужно,
     # потому что КАПСОМ мы обозначили названия переменных, в которых описываются различные операторы.
     if rule_name == rule_name.upper():
         return
     # Каждому правилу присваивется название соответствующего класса, если оно было задано методом setName().
     if getattr(rule, 'name', None) and rule.name.isidentifier():
         rule_name = rule.name
     # Если имя правила — "BinExpr", то определяется метод, который будет разбирать бинарное выражение.
     if rule_name in ('BinExpr', ):
         # Этот метод вернёт экземпляр класса BinExprNode.
         def bin_op_parse_action(s, loc, toks):
             # toks - список распознанных элементов
             node = toks[0]
             if not isinstance(node, TreeNode):
                 node = bin_op_parse_action(s, loc, node)
             for i in range(1, len(toks) - 1, 2):
                 secondNode = toks[i + 1]
                 if not isinstance(secondNode, TreeNode):
                     secondNode = bin_op_parse_action(s, loc, secondNode)
                 # Когда распознана правая часть, создаётся экземпляр класса BinExprNode.
                 node = BinExprNode(self._locs[loc][0], self._locs[loc][1],
                                    Operators(toks[i]), node, secondNode)
             return node
         # Задаётся действие при успешном распознавании текущего правила - вызов функции bin_op_parse_action.
         rule.setParseAction(bin_op_parse_action)
     # Если имя правила — "UnaryExpr", то определяется метод, который будет разбирать унарное выражение.
     elif rule_name in ('UnaryExpr', ):
         # Этот метод вернёт экземпляр класса UnaryExprNode.
         def un_op_parse_action(s, loc, toks):
             # toks - список распознанных элементов
             node = toks[0]
             if not isinstance(node, TreeNode):
                 node = un_op_parse_action(s, loc, node)
             for i in range(1, len(toks)):
                 # Создаётся экземпляр класса UnaryExprNode.
                 node = UnaryExprNode(self._locs[loc][0], self._locs[loc][1], Operators(toks[i]), node)
             return node
         # Задаётся действие при успешном распознавании текущего правила - вызов функции un_op_parse_action.
         rule.setParseAction(un_op_parse_action)
     # В случае, когда не выполнилось ни одно из предшествующих условий, выполняется следующий фрагмент кода:
     else:
         # cls хранит название класса в виде: название_правила + Node,
         # это соответствует названию классов в фалйе Nodes.py.
         cls = rule_name + 'Node'
         # Во избежание вызова исключения NameError используется конструкция with suppress(NameError):
         with suppress(NameError):
             # Теперь в переменой cls хранится тип узла, который соответствует разбираемому правилу.
             cls = eval(cls)
             # Если csl не является абстрактным классом, в нашем случае это EvalNode, ValueNode, ExprNode,
             # определяется метод parse_action.
             if not inspect.isabstract(cls):
                 # Этот метод вернёт экземпляр класса, который соответствует разбираемому правилу.
                 def parse_action(s, loc, toks):
                     return cls(self._locs[loc][0], self._locs[loc][1], *toks)
                 # Задаётся действие при успешном распознавании текущего правила - вызов функции parse_action.
                 rule.setParseAction(parse_action)
Exemple #5
0
    def set_parse_action_magic(rule_name: str,
                               parser: pp.ParserElement) -> None:
        if rule_name == rule_name.upper():
            return
        if rule_name in ('mult', 'add'):

            def bin_op_parse_action(s, loc, tocs):
                node = tocs[0]
                for i in range(1, len(tocs) - 1, 2):
                    node = BinOpNode(BinOp(tocs[i]), node, tocs[i + 1])
                return node

            parser.setParseAction(bin_op_parse_action)
        else:
            cls = ''.join(x.capitalize()
                          for x in rule_name.split('_')) + 'Node'
            with suppress(NameError):
                cls = eval(cls)
                if not inspect.isabstract(cls):

                    def parse_action(s, loc, tocs):
                        return cls(*tocs)

                    parser.setParseAction(parse_action)