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 ParseError( "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
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
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))