Esempio n. 1
0
    def parse_bracket_expression(self):
        token = self.pop_token()  # remove left bracket
        node = ASTNode(n_type=ASTNodeType.ARRAY_LIST_EXP,
                       n_line=token.get_line())
        while True:
            while self.get_token_type() == TokenType.EO_STMT:
                token = self.pop_token()  # EO_STMT
                if str(token) == "," and node.children and node.children[
                        -1].get_text() == ',':
                    raise InvalidExpressionError3(token.row, token.col)
                node.add_child(
                    ASTNode(n_type=ASTNodeType.EO_STMT,
                            n_text=token.get_text(),
                            n_line=token.get_line()))

            if self.get_token_type() is None:
                self.pop_token()
                raise IncompleteStatementError(self.last_token.row,
                                               self.last_token.col)

            node.add_child(self.parse_logic_or_expression())

            token = self.get_token()
            if token.get_type() == TokenType.R_BRACKET:
                break
        self.pop_token()  # remove right bracket
        return node
Esempio n. 2
0
 def parse_identifier_list(self):
     node = ASTNode(n_type=ASTNodeType.IDENT_LIST_EXP)
     while self.get_token_type() == TokenType.IDENTIFIER:
         token = self.pop_token()
         node.add_child(
             ASTNode(n_type=ASTNodeType.IDENTIFIER_EXP,
                     n_text=token.get_text(),
                     n_line=token.get_text()))
     return node
Esempio n. 3
0
 def parse_identifier_expression(self):
     token = self.pop_token()
     root = ASTNode(n_type=ASTNodeType.IDENTIFIER_EXP,
                    n_text=token.get_text(),
                    n_line=token.get_line())
     if self.get_token_type() == TokenType.L_PAREN:
         self.pop_token()  # remove left paren
         node = self.parse_index_list()
         self.pop_token()  # remove right paren
         root.add_child(node)
     return root
Esempio n. 4
0
 def parse_statement_list(self, terminators=('None', )):
     """
     when parse program, terminators use it default value, only if no token left will the parsing stop
     when parse code blocks like selection, iteration, function, terminators will be some specified keywords
     """
     node = ASTNode(n_type=ASTNodeType.STMT_LIST)
     while str(self.get_token()) not in terminators:
         if self.get_token() is None:
             # indicates a invalid code block error, but raise outside the block
             return None
         if self.get_token_type() == TokenType.EO_STMT:
             self.pop_token()
             continue
         node.add_child(self.parse_statement())
     return node
Esempio n. 5
0
    def parse_iteration_statement(self):
        if self.get_token().get_text() not in ('while', 'for'):
            return None
        node = ASTNode(n_type=ASTNodeType.ITR_STMT,
                       n_text=self.get_token().get_text(),
                       n_line=self.get_token().get_line())
        start_token = self.pop_token()

        clause = self.parse_iteration_clause(start_token.get_text())
        if clause is None:
            raise EndMissingError(start_token.row, start_token.col)
        node.add_child(clause)

        self.pop_token()  # remove 'end'

        return self.complete_statement(node)
Esempio n. 6
0
 def parse_level_7_expression(self):
     """
     binary/trinary colon operator (left associate): :
     """
     root = self.parse_level_6_expression()
     while self.get_token_type() == TokenType.COLON:
         token = self.pop_token()  # ':'
         node1 = self.parse_level_6_expression()
         root = ASTNode(n_type=ASTNodeType.CLN_EXP,
                        n_text=token.get_text(),
                        n_line=token.get_line(),
                        children=[root, node1])
         if self.get_token_type() == TokenType.COLON:
             self.pop_token()  # the second ':'
             node2 = self.parse_level_6_expression()
             root.add_child(node2)
     return root
Esempio n. 7
0
    def parse_iteration_clause(self, clause):
        node = ASTNode(n_type=ASTNodeType.ITR_CLS, n_text=clause)

        expression = self.parse_logic_or_expression(
        ) if clause == 'while' else self.parse_assignment_expression()
        if expression is None:
            # exception raised outside
            return None
        node.add_child(expression)

        statement_list = self.parse_statement_list(terminators=('end', ))
        if statement_list is None:
            # exception raised outside
            return None
        node.add_child(statement_list)

        return node
Esempio n. 8
0
    def parse_selection_clause(self, clause):
        node = ASTNode(n_type=ASTNodeType.SEL_ClS, n_text=clause)

        if clause not in ('else', 'otherwise'):
            expression = self.parse_logic_or_expression()
            node.add_child(expression)

        if clause != 'switch':
            statement_list = self.parse_statement_list(
                terminators=SEL_TERMINATOR_MAP[clause])
            if statement_list is None:
                # exception raised outside
                return None
            node.add_child(statement_list)
        else:
            # remove redundant EO_STMT tokens after switch before the first case
            while self.get_token_type() == TokenType.EO_STMT:
                self.pop_token()

        return node
Esempio n. 9
0
    def parse_selection_statement(self):
        if self.get_token().get_text() not in ("if", 'switch'):
            return None
        node = ASTNode(n_type=ASTNodeType.SEL_STMT,
                       n_text=self.get_token().get_text(),
                       n_line=self.get_token().get_line())

        start_token = self.pop_token()

        # firstly a if/switch
        clause = self.parse_selection_clause(start_token.get_text())
        if clause is None:
            raise EndMissingError(start_token.row, start_token.col)
        node.add_child(clause)

        a, b = SEL_CLAUSES_MAP[start_token.get_text()]
        # then unlimited elseif/case
        while self.get_token().get_text() == a:
            clause = self.parse_selection_clause(self.pop_token().get_text())
            if clause is None:
                raise EndMissingError(start_token.row, start_token.col)
            node.add_child(clause)

        # finally sometimes a else/otherwise
        if self.get_token().get_text() == b:
            clause = self.parse_selection_clause(self.pop_token().get_text())
            if clause is None:
                raise EndMissingError(start_token.row, start_token.col)
            node.add_child(clause)

        self.pop_token()  # remove 'end'

        return self.complete_statement(node)
Esempio n. 10
0
    def parse_index_list(self):
        root = ASTNode(n_type=ASTNodeType.INDEX_LIST_EXP)
        while True:
            if self.get_token_type() == TokenType.COLON:
                token = self.pop_token()  # COLON
                root.add_child(
                    ASTNode(n_type=ASTNodeType.CLN_EXP,
                            n_text=token.get_text(),
                            n_line=token.get_line()))
            else:
                child = self.parse_logic_or_expression()
                root.add_child(child)

            token = self.get_token()
            if str(token) == ",":
                # one argument finished, continue to parse another argument
                self.pop_token()
                continue
            elif token.get_type() == TokenType.R_PAREN:
                break
            else:
                raise InvalidExpressionError3(token.row, token.col)
        return root