예제 #1
0
파일: Parser.py 프로젝트: vinayakvivek/aplc
    def p_return_statement(self, p):
        '''return_statement : RETURN expression
                            | RETURN'''

        f_symtable = self.tableptr.items[1]
        f_name = f_symtable.name
        ret_type = self.tableptr.items[0].symbols[f_name]['ret_type']

        if len(p) > 2:
            p[0] = ReturnStmt(p[2])
            if p[2].dtype != ret_type:
                print('invalid return.')
                print('expected %s, got %s.' %
                      (str(ret_type), str(p[2].dtype)))
                sys.exit(0)
        else:
            p[0] = ReturnStmt(None)
            if ret_type != ('void', 0):
                print('invalid return.')
                print('expected %s, got %s.' % (str(ret_type), 'void'))
                sys.exit(0)
예제 #2
0
    def create_function_node(self, ast):

        assert isinstance(ast, Function)

        if ast.has_def is False:
            # function prototype;
            return

        if not isinstance(ast.body[-1], ReturnStmt):
            ast.body.append(ReturnStmt(None))

        self.create_nodes(ast.body, func=ast)
예제 #3
0
    def stmt(self):
        """ try an assign, print, return, if or eval statement """
        self.dbg_msg(" STMT ")
        ptok = self.peek()
        self.dbg_msg("stmt: peeking at " + str(ptok))
        if (ptok.kind == Token.RETURN):
            ## return <expression>
            ret_tok = self.dequeue()
            [l, c] = ret_tok.get_line_col()
            rstmt = ReturnStmt(self.expr(), l, c, self.debug)
            self.dbg_msg("return statement parsed")
            return rstmt
        elif (ptok.kind == Token.PRINT):
            ## print <expression>
            print_tok = self.dequeue()
            [l, c] = print_tok.get_line_col()
            return PrintStmt(self.exprlist(), l, c, self.debug)
        elif (ptok.kind == Token.IF):
            ## if <expression> stmtlist end
            if_tok = self.dequeue()
            [l, c] = if_tok.get_line_col()
            exp = self.expr()
            ifstmt = IfStmt(exp, None, None, l, c, self.debug)
            self.if_stack.append(ifstmt)
            body = self.stmtlist()
            ifstmt.set_body(body)
            ptok = self.peek()
            if (ptok.kind in [Token.ELSEIF, Token.ELSE]):
                self.inside_if = True
                next_stmt = self.stmtlist()
                self.inside_if = False
                ifstmt.append_stmt(next_stmt)
            self.match(Token.END)
            return ifstmt
        elif (ptok.kind == Token.ELSEIF):
            ## elseif <expression> stmtlist
            elseif_tok = self.dequeue()
            [l, c] = elseif_tok.get_line_col()
            self.check_if_stack()
            exp = self.expr()
            elseif_stmt = IfStmt(exp, None, None, l, c, self.debug)
            ifstmt = self.if_stack[-1]
            ifstmt.append_stmt(elseif_stmt)
            self.if_stack.pop()
            self.if_stack.append(elseif_stmt)
            body = self.stmtlist()
            elseif_stmt.set_body(body)
            return elseif_stmt
        elif (ptok.kind == Token.ELSE):
            ## else stmtlist
            self.check_if_stack()
            ifstmt = self.if_stack.pop()
            self.dbg_msg("stmt-else: ")
            else_tok = self.dequeue()
            [l, c] = else_tok.get_line_col()
            body = self.stmtlist()
            else_stmt = ElseStmt(body, l, c, self.debug)
            ifstmt.append_stmt(else_stmt)
            return else_stmt
        elif (ptok.kind == Token.FOR):
            ## Fixme : empty for loops not allowed.
            """ For ( exp1 ; exp2 ; exp3 ) stmtlist  end"""
            self.loop_stack.append(True)
            self.dbg_msg("for-statement")
            for_tok = self.dequeue()
            self.match(Token.LPAREN)

            lhs = self.expr()
            init = lhs
            ptok = self.peek()
            if (ptok.kind in Token.ASSIGNOP):
                assign_tok = self.dequeue()
                [l, c] = assign_tok.get_line_col()
                rhs = self.expr()
                init = AssignStmt(lhs, assign_tok, rhs, l, c, self.debug)

            self.match(Token.COMMA)

            cond = self.expr()
            self.match(Token.COMMA)

            lhs = self.expr()
            update = lhs
            ptok = self.peek()
            if (ptok.kind in Token.ASSIGNOP):
                assign_tok = self.dequeue()
                [l, c] = assign_tok.get_line_col()
                rhs = self.expr()
                update = AssignStmt(lhs, assign_tok, rhs, l, c, self.debug)

            self.match(Token.RPAREN)
            body = self.stmtlist()
            self.match(Token.END)
            [l, c] = for_tok.get_line_col()
            forstmt = ForStmt(init, cond, update, body, l, c, self.debug)
            self.loop_stack.pop()
            return forstmt
        elif (ptok.kind == Token.WHILE):
            ## while ( expr ) body end
            self.loop_stack.append(True)
            self.dbg_msg("while-statement")
            while_tok = self.dequeue()
            [l, c] = while_tok.get_line_col()
            wexpr = self.expr()
            body = self.stmtlist()
            self.match(Token.END)
            whilestmt = WhileStmt(wexpr, body, l, c, self.debug)
            self.loop_stack.pop()
            return whilestmt
        elif (ptok.kind == Token.BREAK):
            ## break, must be in loop-environment
            self.dbg_msg("break-statement")
            break_tok = self.dequeue()
            [l, c] = break_tok.get_line_col()
            self.check_loop_stack()
            ##raises a parse error
            brkstmt = BreakStmt(l, c, self.debug)
            return brkstmt

        elif (ptok.kind == Token.CONTINUE):
            ## continue, must be in loop-environment
            self.dbg_msg("continue-statement")
            cont_tok = self.dequeue()
            [l, c] = cont_tok.get_line_col()
            self.check_loop_stack()
            ##raises a parse error
            cntstmt = ContinueStmt(l, c, self.debug)
            return cntstmt

        else:
            ## lval := rval
            ptok = self.peek()
            [l, c] = ptok.get_line_col()
            lhs = self.expr()
            self.dbg_msg("parsing expr: " + str(lhs))
            ptok = self.peek()
            if (ptok.kind in Token.ASSIGNOP):
                assign_tok = self.dequeue()
                rhs = self.expr()
                [l, c] = assign_tok.get_line_col()
                return AssignStmt(lhs, assign_tok, rhs, l, c, self.debug)
            return EvalStmt(lhs, l, c, self.debug)
        raise ParseException("parsing Statement, unkown operators" + str(ptok))
예제 #4
0
 def stmt(self, pass_in_ATexpr=None):
     """ try an assign, print, return, if or eval statement """
     self.dbg_msg(" STMT ")
     ptok = self.peek()
     self.dbg_msg("stmt: peeking at " + str(ptok))
     if (ptok.kind == EzhilToken.RETURN):
         ## return <expression>
         self.dbg_msg('enter->return: <expression>')
         ret_tok = self.dequeue()
         [l, c] = ret_tok.get_line_col()
         rstmt = ReturnStmt(self.expr(), l, c, self.debug)
         self.dbg_msg("return statement parsed")
         return rstmt
     elif (ptok.kind == EzhilToken.PRINT):
         self.currently_parsing.append(ptok)
         ## print <expression>
         print_tok = self.dequeue()
         [l, c] = print_tok.get_line_col()
         exprlist_val = self.exprlist()
         self.currently_parsing.pop()
         return PrintStmt(exprlist_val, l, c, self.debug)
     elif (ptok.kind == EzhilToken.ATRATEOF or pass_in_ATexpr):
         ## @ <expression> {if | while | elseif}
         if not pass_in_ATexpr:
             at_tok = self.match(EzhilToken.ATRATEOF)
             self.currently_parsing.append(at_tok)
             exp = self.valuelist()
             self.currently_parsing.pop()
         else:
             exp = pass_in_ATexpr
         if (self.debug): print("return from valuelist ", str(exp))
         ptok = self.peek()
         if (ptok.kind == EzhilToken.IF):
             return self.parseIfStmt(exp)
         elif (ptok.kind == EzhilToken.WHILE):
             ## @ ( expr ) while { body } end
             self.loop_stack.append(True)
             self.dbg_msg("while-statement")
             while_tok = self.dequeue()
             self.currently_parsing.append(while_tok)
             [l, c] = while_tok.get_line_col()
             wexpr = exp[0]
             body = self.stmtlist()
             self.match(EzhilToken.END)
             whilestmt = WhileStmt(wexpr, body, l, c, self.debug)
             self.loop_stack.pop()
             self.currently_parsing.pop()
             return whilestmt
         elif (ptok.kind == EzhilToken.SWITCH):
             return self.parseSwitchStmt(exp)
         elif (ptok.kind == EzhilToken.FOREACH):
             foreach_tok = self.dequeue()
             self.currently_parsing.append(foreach_tok)
             [l, c] = foreach_tok.get_line_col()
             if (self.debug): print("parsing FOREACH stmt")
             self.loop_stack.append(True)
             self.dbg_msg("foreach-statement")
             # convert to a for statement - building Ezhil AST - transformations
             if not isinstance(exp[1], Identifier):
                 raise ParseError(" FOR-EACH statement " + str(foreach_tok))
             foreach_iter = exp[1]
             iter = Identifier("__" + foreach_iter.id, l=0, c=-1)
             eq_token = EzhilLexeme("=", EzhilToken.EQUALS)
             plus_token = EzhilLexeme("+", EzhilToken.PLUS)
             lt_token = EzhilLexeme("<", EzhilToken.LT)
             if (self.debug): print("build init assign stmt")
             init = AssignStmt(iter, eq_token, Number(0), l, c, self.debug)
             if (self.debug): print("build cond expr")
             VL1 = ValueList([exp[0]], l, c, self.debug)
             cond = Expr(
                 iter, lt_token,
                 ExprCall(Identifier("len", l, c), VL1, l, c, self.debug),
                 l, c, self.debug)
             if (self.debug): print("build plus1 stmt")
             plus1_iter = Expr(iter, plus_token, Number(1), l, c,
                               self.debug)
             if (self.debug): print("build equals stmt")
             update = AssignStmt(iter, eq_token, plus1_iter, l, c,
                                 self.debug)
             body = self.stmtlist()  #parse body
             # and insert artifical update variable in body
             VL2 = ValueList([exp[0], iter], l, c, self.debug)
             extract_foreach_iter_from_list = ExprCall(
                 Identifier("__getitem__", l, c), VL2, l, c, self.debug)
             foreach_iter_Assign = AssignStmt(
                 foreach_iter, eq_token, extract_foreach_iter_from_list, l,
                 c, self.debug)
             body.List.insert(0, foreach_iter_Assign)
             # complete FOREACH stmt
             self.match(EzhilToken.END)
             self.currently_parsing.pop()
             foreach_stmt = ForStmt(init, cond, update, body, l, c,
                                    self.debug)
             self.loop_stack.pop()
             if (self.debug):
                 print("completed parsing FOR-EACH loop", str(foreach_stmt))
             return foreach_stmt
         elif (ptok.kind == EzhilToken.FOR):
             ## Fixme : empty for loops not allowed.
             """ For ( exp1 , exp2 , exp3 ) stmtlist  end"""
             if (self.debug): print("parsing FOR stmt")
             self.loop_stack.append(True)
             self.dbg_msg("for-statement")
             for_tok = self.peek()
             self.currently_parsing.append(for_tok)
             if (self.debug): print("matching for STMT", str(self.peek()))
             self.match(EzhilToken.FOR)
             if (self.debug): print("matched for STMT", str(self.peek()))
             [l, c] = for_tok.get_line_col()
             init, cond, update = exp[0], exp[1], exp[2]
             if (self.debug):
                 print("extract 3 parts", str(init), str(cond), str(update))
             body = self.stmtlist()
             self.match(EzhilToken.END)
             self.currently_parsing.pop()
             if (self.debug): print("body of loop", str(body))
             forstmt = ForStmt(init, cond, update, body, l, c, self.debug)
             self.loop_stack.pop()
             if (self.debug):
                 print("completed parsing FOR loop", str(forstmt))
             return forstmt
     elif (ptok.kind == EzhilToken.DO):
         if (self.debug): print("parsing DO-WHILE statement")
         self.loop_stack.append(True)
         do_tok = self.dequeue()
         self.currently_parsing.append(do_tok)
         [l, c] = do_tok.get_line_col()
         body = self.stmtlist()
         if (self.debug): print("parsed body")
         self.match(EzhilToken.DOWHILE)
         self.match(EzhilToken.ATRATEOF)
         exp = self.valuelist()
         if (self.debug): print("parsed EXP", exp[0])
         doWhileStmt = DoWhileStmt(exp[0], body, l, c, self.debug)
         self.loop_stack.pop()
         self.currently_parsing.pop()
         return doWhileStmt
     elif (ptok.kind == EzhilToken.BREAK):
         ## break, must be in loop-environment
         self.dbg_msg("break-statement")
         break_tok = self.dequeue()
         [l, c] = break_tok.get_line_col()
         self.check_loop_stack()
         ##raises a parse error
         brkstmt = BreakStmt(l, c, self.debug)
         return brkstmt
     elif (ptok.kind == EzhilToken.CONTINUE):
         ## continue, must be in loop-environment
         self.dbg_msg("continue-statement")
         cont_tok = self.dequeue()
         [l, c] = cont_tok.get_line_col()
         self.check_loop_stack()
         ##raises a parse error
         cntstmt = ContinueStmt(l, c, self.debug)
         return cntstmt
     else:
         ## lval := rval
         ptok = self.peek()
         self.currently_parsing.append(ptok)
         [l, c] = ptok.get_line_col()
         lhs = self.expr()
         self.dbg_msg("parsing expr: " + str(lhs))
         ptok = self.peek()
         if (ptok.kind in EzhilToken.ASSIGNOP):
             assign_tok = self.dequeue()
             rhs = self.expr()
             [l, c] = assign_tok.get_line_col()
             self.currently_parsing.pop()
             return AssignStmt(lhs, assign_tok, rhs, l, c, self.debug)
         self.currently_parsing.pop()
         return EvalStmt(lhs, l, c, self.debug)
     raise ParseException("parsing Statement, unkown operators" + str(ptok))