예제 #1
0
    def function(self):
        """ def[kw] fname[id] (arglist) {body} end[kw] """
        if (self.parsing_function):
            raise ParseException(" Nested functions not allowed! ")

        self.parsing_function = True
        def_tok = self.dequeue()
        if (def_tok.kind != Token.DEF):
            raise ParseException("unmatched 'def'  in function " +
                                 str(def_tok))

        id_tok = self.dequeue()
        if (id_tok.kind != Token.ID):
            raise ParseException("expected identifier in function" +
                                 str(id_tok))

        arglist = self.arglist()
        self.dbg_msg("finished parsing arglist")
        body = self.stmtlist()

        self.match(Token.END)
        [l, c] = def_tok.get_line_col()
        fval = Function(id_tok.val, arglist, body, l, c, self.debug)
        self.parsing_function = False
        self.dbg_msg("finished parsing function")
        return fval
예제 #2
0
파일: parser.py 프로젝트: moneytech/gypsum
    def importStmt(self):
        lead = self.leadComments()
        cg = ast.CommentGroup(lead, [])
        l = self._nextTag(IMPORT).location
        prefix = self.scopePrefix()
        if self._peekTag() is DOT:
            self._next()
            self._nextTag(UNDERSCORE)
            imp = ast.ImportStatement(prefix, None, cg, self._location(l))
            self._tailComment(imp)
            return imp

        if len(prefix) == 1:
            raise ParseException(
                prefix[0].location,
                "import statement requires a prefix before symbol to import")
        lastComponent = prefix.pop()
        if lastComponent.typeArguments is not None:
            raise ParseException(
                lastComponent.location,
                "type arguments can't be at the end of an import statement")

        bindings = []
        if self._peekTag() is AS:
            self._next()
            asName = self.ident()
            bindings.append(
                ast.ImportBinding(lastComponent.name, asName,
                                  self._location(lastComponent.location)))
        else:
            bindings.append(
                ast.ImportBinding(lastComponent.name, None,
                                  lastComponent.location))
        while self._peekTag() is COMMA:
            self._next()
            name = self.ident()
            bl = self.location
            if self._peekTag() is AS:
                self._next()
                asName = self.ident()
            else:
                asName = None
            bindings.append(ast.ImportBinding(name, asName,
                                              self._location(bl)))

        imp = ast.ImportStatement(prefix, bindings, cg, self._location(l))
        self._tailComment(imp)
        return imp
예제 #3
0
파일: parser.py 프로젝트: moneytech/gypsum
 def symbol(self):
     sym = self._nextTag(SYMBOL).text
     if sym.startswith("`"):
         sym = tryDecodeString(sym)
         if sym is None:
             raise ParseException(self.location, "invalid symbol")
     return sym
예제 #4
0
 def valuelist(self):
     """parse: ( expr_1 , expr_2, ... ) """
     valueList = list()
     self.dbg_msg("valuelist: ")
     lparen_tok = self.match(EzhilToken.LPAREN)
     while (self.peek().kind != EzhilToken.RPAREN):
         val = self.expr()
         if (self.debug): print("val = ", str(val))
         ptok = self.peek()
         if (self.debug):
             print("ptok = ", str(ptok), str(ptok.kind),
                   str(EzhilToken.ASSIGNOP))
         if (ptok.kind in EzhilToken.ASSIGNOP):
             assign_tok = self.dequeue()
             rhs = self.expr()
             [l, c] = assign_tok.get_line_col()
             lhs = val
             val = AssignStmt(lhs, assign_tok, rhs, l, c, self.debug)
             if (self.debug): print("AssignStmt = ", str(val))
             ptok = self.peek()
         else:
             if (self.debug): print("No-Assign // Expr =", str(val))
         self.dbg_msg("valuelist-expr: " + str(val))
         valueList.append(val)
         if (ptok.kind == EzhilToken.RPAREN):
             break
         elif (ptok.kind == EzhilToken.COMMA):
             self.match(EzhilToken.COMMA)
         else:
             raise ParseException(" function call argument list " +
                                  str(ptok))
     self.match(EzhilToken.RPAREN)
     [l, c] = lparen_tok.get_line_col()
     return ValueList(valueList, l, c, self.debug)
예제 #5
0
    def expr(self):
        self.dbg_msg(" EXPR ")
        val1 = self.term()
        res = val1
        ptok = self.peek()
        if ptok.kind in EzhilToken.ADDSUB:
            binop = self.dequeue()
            if (ptok.kind == EzhilToken.MINUS):
                val2 = self.term()
            else:
                val2 = self.expr()
            [l, c] = binop.get_line_col()
            res = Expr(val1, binop, val2, l, c, self.debug)
        elif ptok.kind == EzhilToken.LPAREN:
            ## function call
            if (res.__class__ != Identifier):
                raise ParseException("invalid function call" + str(ptok))
            [l, c] = ptok.get_line_col()
            vallist = self.valuelist()
            res = ExprCall(res, vallist, l, c, self.debug)

        ptok = self.peek()
        while ptok.kind in EzhilToken.BINOP:
            binop = self.dequeue()
            [l, c] = binop.get_line_col()
            res = Expr(res, binop, self.expr(), l, c, self.debug)
            ptok = self.peek()
        return res
예제 #6
0
파일: parser.py 프로젝트: moneytech/gypsum
def parse(fileName, tokens):
    parser = Parser(fileName, tokens)
    module = parser.module()
    if not parser.atEnd():
        raise ParseException(parser.location, "garbage at end of input")
    ast.addNodeIds(module)
    return module
예제 #7
0
파일: parser.py 프로젝트: moneytech/gypsum
 def stringLiteral(self):
     tok = self._nextTag(STRING)
     value = tryDecodeString(tok.text)
     if value is None:
         raise ParseException(tok.location,
                              "could not understand string: %s" % tok.text)
     return ast.StringLiteral(value, tok.location)
예제 #8
0
파일: parser.py 프로젝트: moneytech/gypsum
    def _parseBinop(self, simpleParser, astCtor, level):
        if level == 0:
            termParser = simpleParser
        else:
            termParser = lambda: self._parseBinop(simpleParser, astCtor, level
                                                  - 1)
        terms = [termParser()]
        ops = []
        tok = self._peek()
        while tok.tag is OPERATOR and self._precedence(tok.text) == level:
            self._next()
            ops.append(tok)
            terms.append(termParser())
            tok = self._peek()
        if len(terms) == 1:
            return terms[0]

        associativity = self._associativity(ops[0].text)
        if associativity is self.LEFT_ASSOC:
            e = terms[0]
            for i, op in enumerate(ops):
                term = terms[i + 1]
                if self._associativity(op.text) is not self.LEFT_ASSOC:
                    raise ParseException(
                        op.location,
                        "left and right associative operators are mixed together"
                    )
                loc = e.location.combine(term.location)
                b = astCtor(op.text, e, term, None, loc)
                self._liftComments(b, e, term)
                e = b
        else:
            e = terms[-1]
            for i in xrange(len(ops) - 1, -1, -1):
                op = ops[i]
                term = terms[i]
                if self._associativity(op.text) is not self.RIGHT_ASSOC:
                    raise ParseException(
                        op.location,
                        "left and right associative operators are mixed together"
                    )
                loc = term.location.combine(e.location)
                b = astCtor(op.text, term, e, None, loc)
                self._liftComments(b, term, e)
                e = b
        return e
예제 #9
0
 def match(self, kind):
     ## if match return token, else ParseException
     tok = self.dequeue()
     if (tok.kind != kind):
         raise ParseException(u"cannot find token "+ \
                             Token.get_name(kind) + u" got " \
                             + unicode(tok) + u" instead!")
     return tok
예제 #10
0
 def match(self, kind):
     ## if match return token, else ParseException
     tok = self.dequeue()
     if (tok.kind != kind):
         raise ParseException("cannot find token "+ \
                              EzhilToken.get_name(kind) + " got " \
                             + str(tok)  \
                             + " instead!")
     return tok
예제 #11
0
 def parseSwitchStmt(self, exp):
     ## @ <ID/EXPR> SWITCH @( expr ) CASE {stmtlist} @( expr ) CASE {stmtlist} OTHERWISE {stmtlist} END
     ## implement as an if-elseif-else statement
     self.dbg_msg("parsing SWITCH statement")
     sw_tok = self.dequeue()
     [l, c] = sw_tok.get_line_col()
     self.inside_if = True
     lhs = exp[0]
     # enter this if-statement always
     ifstmt = IfStmt(Number(1), None, None, l, c, self.debug)
     self.if_stack.append(ifstmt)
     self.dbg_msg("parsing SWITCH-body")  #self.dbg_msg
     ptok = self.peek()
     equality_token = EzhilLexeme("=", EzhilToken.EQUALITY)
     while (ptok.kind == EzhilToken.ATRATEOF
            or ptok.kind == EzhilToken.OTHERWISE):
         self.inside_if = True
         [l, c] = ptok.get_line_col()
         if (ptok.kind == EzhilToken.ATRATEOF):
             # parse elseif branch
             self.dbg_msg("parsing CASE")
             self.match(EzhilToken.ATRATEOF)
             exp = self.valuelist()
             self.dbg_msg("parsing CASE EXPR")
             self.match(EzhilToken.CASE)
             next_stmt = self.stmtlist()
             expr = Expr(lhs, equality_token, exp[0], l, c, self.debug)
             self.dbg_msg("building an Expr " + str(expr))
             if not ifstmt.body:
                 ifstmt.expr = expr
                 ifstmt.body = next_stmt
             else:
                 case_stmt = IfStmt(expr, next_stmt, None, l, c, self.debug)
                 ifstmt.append_stmt(case_stmt)
         elif (ptok.kind == EzhilToken.OTHERWISE):
             #parse else branch
             self.dbg_msg("parsing OTHERWISE: ")
             self.match(EzhilToken.OTHERWISE)
             self.dbg_msg("parsing OTHERWISE-Body")
             self.inside_if = False
             body = self.stmtlist()
             else_stmt = ElseStmt(body, l, c, self.debug)
             if not ifstmt.body:
                 ifstmt.body = else_stmt
             else:
                 ifstmt.append_stmt(else_stmt)
             break
         else:
             self.inside_if = False
             raise ParseException(
                 "SWITCH-CASE-OTHERWISE statement syntax is messed up")
         ptok = self.peek()
         self.dbg_msg("parsing SWITCH-CASE next bits " + str(ptok))
     self.match(EzhilToken.END)
     self.inside_if = False
     self.dbg_msg("parsing -SWITCH-CASE- complete")
     return ifstmt
예제 #12
0
 def parseIfStmt(self, exp):
     ## @ <expression> if { stmtlist } @<expr> ELSEIF {stmtlist} ELSE <stmtlist> END
     self.dbg_msg("parsing IF statement")
     if_tok = self.dequeue()
     [l, c] = if_tok.get_line_col()
     self.inside_if = True
     ifstmt = IfStmt(exp[0], None, None, l, c, self.debug)
     self.if_stack.append(ifstmt)
     self.dbg_msg("parsing IF-body")
     body = self.stmtlist()
     prev_body = body
     ifstmt.set_body(body)
     ptok = self.peek()
     while (ptok.kind == EzhilToken.ATRATEOF
            or ptok.kind == EzhilToken.ELSE):
         self.inside_if = True
         [l, c] = ptok.get_line_col()
         if (ptok.kind == EzhilToken.ATRATEOF):
             # parse elseif branch
             self.dbg_msg("parsing ELSE-IF")
             self.match(EzhilToken.ATRATEOF)
             exp = self.valuelist()
             self.dbg_msg("parsing ELSE-IF EXPR")
             tok = self.peek()
             if (tok.kind != EzhilToken.ELSEIF):
                 # maybe another IF statement, SWITCH-CASE or a WHILE loop, DO-WHILE loop etc.
                 next_stmt = self.stmtlist(exp)  #pass in the expression
                 prev_body.append(next_stmt)
                 # append to previously scanned body.
             else:
                 self.dbg_msg("parsing ELSE-IF-body")
                 self.match(EzhilToken.ELSEIF)
                 body = self.stmtlist()
                 prev_body = body
                 next_stmt = IfStmt(exp[0], body, None, l, c, self.debug)
                 ifstmt.append_stmt(next_stmt)
         elif (ptok.kind == EzhilToken.ELSE):
             #parse else branch
             self.dbg_msg("parsing stmt else: ")
             self.match(EzhilToken.ELSE)
             self.dbg_msg("parsing ELSE-Body")
             self.inside_if = False
             body = self.stmtlist()
             prev_body = body
             else_stmt = ElseStmt(body, l, c, self.debug)
             ifstmt.append_stmt(else_stmt)
             break
         else:
             self.inside_if = False
             raise ParseException(
                 "If-Else-If statement syntax is messed up")
         ptok = self.peek()
         self.dbg_msg("parsing -IF next bits " + str(ptok))
     self.match(EzhilToken.END)
     self.inside_if = False
     self.dbg_msg("parsing -IF-complete")
     return ifstmt
예제 #13
0
파일: parser.py 프로젝트: moneytech/gypsum
 def prefixedPattern(self):
     l = self._peek().location
     prefix = self.scopePrefix()
     tag = self._peekTag()
     if tag is LPAREN:
         args = self._parseList(self.simplePattern, "pattern arguments",
                                LPAREN, COMMA, RPAREN)
         ty = None
     elif tag is COLON:
         self._next()
         ty = self.ty()
         args = None
     else:
         args = None
         ty = None
     loc = self._location(l)
     if len(prefix) == 1 and args is None:
         mayHaveTypeArgs = False
         result = ast.VariablePattern(prefix[0].name, ty, None, loc)
         if ty is None:
             self._tailComment(result)
         else:
             self._liftComments(result, None, ty)
     elif args is None and ty is None:
         mayHaveTypeArgs = False
         result = ast.ValuePattern(prefix[:-1], prefix[-1].name, None, loc)
         self._tailComment(result)
     elif args is not None:
         mayHaveTypeArgs = True
         result = ast.DestructurePattern(prefix, args, None, loc)
         self._tailComment(result)
     else:
         raise ParseException(
             loc, "invalid variable, value, or destructure pattern")
     if not mayHaveTypeArgs and prefix[-1].typeArguments is not None:
         raise ParseException(
             loc,
             "can't have type arguments at end of variable or value pattern"
         )
     return result
예제 #14
0
    def factor(self):
        self.dbg_msg("factor")
        tok = self.peek()
        if tok.kind == Token.LPAREN:
            lparen_tok = self.dequeue()
            val = self.expr()
            if self.dequeue().kind != Token.RPAREN:
                raise SyntaxError("Missing Parens")
        elif tok.kind == Token.NUMBER:
            tok_num = self.dequeue()
            [l, c] = tok_num.get_line_col()
            val = Number(tok.val, l, c, self.debug)
        elif tok.kind == Token.ID:
            tok_id = self.dequeue()
            [l, c] = tok_id.get_line_col()
            val = Identifier(tok.val, l, c, self.debug)
            ptok = self.peek()
            self.dbg_msg("factor: " + str(ptok) + " / " + str(tok))
            if (ptok.kind == Token.LPAREN):
                ## function call
                [l, c] = ptok.get_line_col()
                vallist = self.valuelist()
                val = ExprCall(val, vallist, l, c, self.debug)
            elif (ptok.kind == Token.LSQRBRACE):
                ## array type
                val = None
                raise ParseException("arrays not implemented" + str(ptok))
        elif tok.kind == Token.STRING:
            str_tok = self.dequeue()
            [l, c] = str_tok.get_line_col()
            val = String(tok.val, l, c, self.debug)
        else:
            raise ParseException("Expected Number, found something " +
                                 str(tok))

        self.dbg_msg("factor-returning: " + str(val))
        return val
예제 #15
0
 def expr(self):
     self.dbg_msg(" EXPR ")
     val1 = self.term()
     res = val1
     ptok = self.peek()
     if ptok.kind in Token.ADDSUB:
         binop = self.dequeue()
         val2 = self.expr()
         [l, c] = binop.get_line_col()
         res = Expr(val1, binop, val2, l, c, self.debug)
     elif ptok.kind == Token.LPAREN:
         ## function call -OR- array type.
         if (res.__class__ != Identifier):
             raise ParseException("invalid function call" + unicode(ptok))
         [l, c] = ptok.get_line_col()
         vallist = self.valuelist()
         res = ExprCall(res, vallist, l, c, self.debug)
     return res
예제 #16
0
 def arglist(self):
     """parse: ( arg_1, arg_2, ... ) """
     self.dbg_msg(" ARGLIST ")
     args = list()
     lparen_tok = self.match(Token.LPAREN)
     while (self.peek().kind != Token.RPAREN):
         arg_name = self.dequeue()
         args.append(arg_name.val)
         ptok = self.peek()
         if (ptok.kind == Token.RPAREN):
             break
         elif (ptok.kind == Token.COMMA):
             self.match(Token.COMMA)
         else:
             raise ParseException(" function definition argument list " +
                                  str(ptok))
     self.match(Token.RPAREN)
     [l, c] = lparen_tok.get_line_col()
     return ArgList(args, l, c, self.debug)
예제 #17
0
파일: parser.py 프로젝트: moneytech/gypsum
    def maybeFunctionType(self):
        fnTypes = self._parseRepSep(self.simpleType, SMALL_ARROW)

        ty = fnTypes.pop()
        while len(fnTypes) > 0:
            pty = fnTypes.pop()
            if isinstance(pty, ast.TupleType):
                if len(pty.flags) > 0:
                    raise ParseException(
                        pty.location,
                        "function parameter list can't be nullable")
                ptys = pty.types
            else:
                ptys = [pty]
            loc = pty.location.combine(ty.location)
            fty = ast.FunctionType(ptys, ty, None, loc)
            self._liftComments(fty, pty, ty)
            ty = fty
        return ty
예제 #18
0
 def valuelist(self):
     """parse: ( expr_1 , expr_2, ... ) """
     valueList = list()
     self.dbg_msg("valuelist: ")
     lparen_tok = self.match(Token.LPAREN)
     while (self.peek().kind != Token.RPAREN):
         val = self.expr()
         self.dbg_msg("valuelist-expr: " + str(val))
         valueList.append(val)
         ptok = self.peek()
         if (ptok.kind == Token.RPAREN):
             break
         elif (ptok.kind == Token.COMMA):
             self.match(Token.COMMA)
         else:
             raise ParseException(" function call argument list " +
                                  str(ptok))
     self.match(Token.RPAREN)
     [l, c] = lparen_tok.get_line_col()
     return ValueList(valueList, l, c, self.debug)
예제 #19
0
파일: parser.py 프로젝트: moneytech/gypsum
 def _error(self, expected):
     tok = self._peek()
     raise ParseException(tok.location,
                          "expected %s but found %s" % (expected, tok.text))
예제 #20
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))
예제 #21
0
 def error(self, token, message):
     self.nebbdyr.error(token, message)
     return ParseException()
예제 #22
0
 def continue_statement(self):
     if self.loop_level <= 0:
         raise ParseException(
             self.previous(), "'continue' statement must be inside a loop.")
     self.consume(TT.NEWLINE, "Expect newline after 'continue' statement.")
     return stmt.Continue()
예제 #23
0
 def break_statement(self):
     if self.loop_level <= 0:
         raise ParseException(self.previous(),
                              "'break' statement must be inside a loop.")
     self.consume(TT.NEWLINE, "Expect newline after 'break' statement.")
     return stmt.Break()
예제 #24
0
    def factor(self):
        self.dbg_msg("factor")
        tok = self.peek()
        if tok.kind == EzhilToken.LPAREN:
            lparen_tok = self.dequeue()
            val = self.expr()
            if self.dequeue().kind != EzhilToken.RPAREN:
                raise SyntaxError("Missing Parens " + str(self.last_token()))
        elif tok.kind == EzhilToken.NUMBER:
            tok_num = self.dequeue()
            [l, c] = tok_num.get_line_col()
            val = Number(tok.val, l, c, self.debug)
        elif tok.kind == EzhilToken.LOGICAL_NOT:
            tok_not = self.dequeue()
            [l, c] = tok_not.get_line_col()
            val = UnaryExpr(self.expr(), tok_not, l, c, self.debug)
            self.dbg_msg("completed parsing unary expression" + str(val))
        elif tok.kind == EzhilToken.ID:
            tok_id = self.dequeue()
            [l, c] = tok_id.get_line_col()
            val = Identifier(tok.val, l, c, self.debug)
            ptok = self.peek()
            self.dbg_msg("factor: " + str(ptok) + " / " + str(tok))
            if (ptok.kind == EzhilToken.LPAREN):
                ## function call
                [l, c] = ptok.get_line_col()
                vallist = self.valuelist()
                val = ExprCall(val, vallist, l, c, self.debug)
            elif (ptok.kind == EzhilToken.LSQRBRACE):
                ## indexing a array type variable or ID
                val = None
                raise ParseException("arrays not implemented" + str(ptok))
        elif tok.kind == EzhilToken.STRING:
            str_tok = self.dequeue()
            [l, c] = str_tok.get_line_col()
            val = String(tok.val, l, c, self.debug)
        elif tok.kind in EzhilToken.ADDSUB:
            unop = self.dequeue()
            [l, c] = unop.get_line_col()
            val = Expr(Number(0), unop, self.term(), l, c, self.debug)
        elif tok.kind == EzhilToken.LSQRBRACE:
            # creating a list/array expression
            list_start = self.dequeue()
            val = Array()
            while (True):
                exprval = self.expr()
                val.append(exprval)
                if self.debug: print(self.peek().__class__, self.peek())
                if (self.peek().kind == EzhilToken.RSQRBRACE):
                    break
                else:
                    assert (self.peek().kind == EzhilToken.COMMA)
                    self.dequeue()
            assert (self.peek().kind == EzhilToken.RSQRBRACE)
            list_end = self.dequeue()
        else:
            raise ParseException("Expected Number, found something " +
                                 str(tok))

        self.dbg_msg("factor-returning: " + str(val))
        return val
예제 #25
0
파일: parser.py 프로젝트: moneytech/gypsum
 def ty(self):
     l = self._peek().location
     t = self.maybeFunctionType()
     if isinstance(t, ast.TupleType) and len(t.types) == 0:
         raise ParseException(l, "expected type but found ()")
     return t
예제 #26
0
 def check_loop_stack(self):
     if (len(self.loop_stack) == 0):
         raise ParseException(
             "break/continue statement outside any loop, near" +
             str(self.last_token()))
     return len(self.loop_stack)
예제 #27
0
    def factor(self):
        self.dbg_msg("factor")
        tok = self.peek()
        if tok.kind == EzhilToken.LPAREN:
            lparen_tok = self.dequeue()
            val = self.expr()
            if self.dequeue().kind != EzhilToken.RPAREN:
                raise SyntaxError("Missing Parens " + str(self.last_token()))
        elif tok.kind == EzhilToken.NUMBER:
            tok_num = self.dequeue()
            [l, c] = tok_num.get_line_col()
            val = Number(tok.val, l, c, self.debug)
        elif tok.kind == EzhilToken.LOGICAL_NOT:
            tok_not = self.dequeue()
            [l, c] = tok_not.get_line_col()
            val = UnaryExpr(self.expr(), tok_not, l, c, self.debug)
            self.dbg_msg("completed parsing unary expression" + str(val))
        elif tok.kind == EzhilToken.ID:
            tok_id = self.dequeue()
            [l, c] = tok_id.get_line_col()
            val = Identifier(tok.val, l, c, self.debug)
            ptok = self.peek()
            self.dbg_msg("factor: " + str(ptok) + " / " + str(tok))
            if (ptok.kind == EzhilToken.LPAREN):
                ## function call
                [l, c] = ptok.get_line_col()
                vallist = self.valuelist()
                val = ExprCall(val, vallist, l, c, self.debug)
            elif (ptok.kind == EzhilToken.LSQRBRACE):
                ## indexing a array type variable or ID
                [l, c] = ptok.get_line_col()
                ## replace with a call to __getitem__
                exp = self.factor()
                if (hasattr(exp, '__getitem__')):
                    VL2 = ValueList([val, exp[0]], l, c, self.debug)
                else:
                    # when exp is a expression
                    VL2 = ValueList([val, exp], l, c, self.debug)
                val = ExprCall(Identifier("__getitem__", l, c), VL2, l, c,
                               self.debug)
                for itr in range(1, len(exp)):
                    VL2 = ValueList([val, exp[itr]], l, c, self.debug)
                    val = ExprCall(Identifier("__getitem__", l, c), VL2, l, c,
                                   self.debug)
                #raise ParseException("array indexing implemented"+str(ptok));
            elif (ptok.kind == EzhilToken.LCURLBRACE):
                val = None
                raise ParseException("dictionary indexing implemented" +
                                     str(ptok))
        elif tok.kind == EzhilToken.STRING:
            str_tok = self.dequeue()
            [l, c] = str_tok.get_line_col()
            val = String(tok.val, l, c, self.debug)
        elif tok.kind in EzhilToken.ADDSUB:
            unop = self.dequeue()
            [l, c] = unop.get_line_col()
            val = Expr(Number(0), unop, self.term(), l, c, self.debug)
        elif tok.kind == EzhilToken.LCURLBRACE:
            # creating a list/dictionary expression
            dict_start = self.dequeue()
            val = Dict()
            while (True):
                if (self.peek().kind == EzhilToken.RCURLBRACE):
                    break
                exprkey = self.expr()
                tok_colon = self.match(EzhilToken.COLON)
                exprval = self.expr()
                val.update({exprkey: exprval})
                if self.debug: print(self.peek().__class__, self.peek())
                if (self.peek().kind == EzhilToken.RCURLBRACE):
                    break
                else:
                    assert (self.peek().kind == EzhilToken.COMMA)
                    self.dequeue()
            assert (self.peek().kind == EzhilToken.RCURLBRACE)
            list_end = self.dequeue()
        elif tok.kind == EzhilToken.LSQRBRACE:
            # creating a list/array expression
            list_start = self.dequeue()
            val = Array()
            while (True):
                if (self.peek().kind == EzhilToken.RSQRBRACE):
                    break
                exprval = self.expr()
                val.append(exprval)
                if self.debug: print(self.peek().__class__, self.peek())
                if (self.peek().kind == EzhilToken.RSQRBRACE):
                    break
                else:
                    assert (self.peek().kind == EzhilToken.COMMA)
                    self.dequeue()
            assert (self.peek().kind == EzhilToken.RSQRBRACE)
            list_end = self.dequeue()
        else:
            raise ParseException("Expected Number, found something " +
                                 str(tok))

        self.dbg_msg("factor-returning: " + str(val))
        return val
예제 #28
0
 def check_if_stack(self):
     if (len(self.if_stack) == 0):
         raise ParseException("unmatched else statement, near" +
                              str(self.last_token()))
     return len(self.if_stack)
예제 #29
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))