def Statement(tokenizer, staticContext):

    tokenType = tokenizer.get(True)
    builder = staticContext.builder

    # Cases for statements ending in a right curly return early, avoiding the
    # common semicolon insertion magic after this switch.
    
    if tokenType == "function":
        # "declared_form" extends functions of staticContext, "statement_form" doesn'tokenizer.
        if len(staticContext.statementStack) > 1:
            kind = "statement_form"
        else:
            kind = "declared_form"
        
        return FunctionDefinition(tokenizer, staticContext, True, kind)
        
        
    elif tokenType == "left_curly":
        node = Statements(tokenizer, staticContext)
        tokenizer.mustMatch("right_curly")
        
        return node
        
        
    elif tokenType == "if":
        node = builder.IF_build(tokenizer)
        builder.IF_setCondition(node, ParenExpression(tokenizer, staticContext))
        staticContext.statementStack.append(node)
        builder.IF_setThenPart(node, Statement(tokenizer, staticContext))

        if tokenizer.match("else"):
            comments = tokenizer.getComments()
            elsePart = Statement(tokenizer, staticContext)
            builder.COMMENTS_add(elsePart, node, comments)
            builder.IF_setElsePart(node, elsePart)

        staticContext.statementStack.pop()
        builder.IF_finish(node)
        
        return node
        
        
    elif tokenType == "switch":
        # This allows CASEs after a "default", which is in the standard.
        node = builder.SWITCH_build(tokenizer)
        builder.SWITCH_setDiscriminant(node, ParenExpression(tokenizer, staticContext))
        staticContext.statementStack.append(node)

        tokenizer.mustMatch("left_curly")
        tokenType = tokenizer.get()
        
        while tokenType != "right_curly":
            if tokenType == "default":
                if node.defaultIndex >= 0:
                    raise SyntaxError("More than one switch default", tokenizer)
                    
                childNode = builder.DEFAULT_build(tokenizer)
                builder.SWITCH_setDefaultIndex(node, len(node)-1)
                tokenizer.mustMatch("colon")
                builder.DEFAULT_initializeStatements(childNode, tokenizer)
                
                while True:
                    tokenType=tokenizer.peek(True)
                    if tokenType == "case" or tokenType == "default" or tokenType == "right_curly":
                        break
                    builder.DEFAULT_addStatement(childNode, Statement(tokenizer, staticContext))
                
                builder.DEFAULT_finish(childNode)

            elif tokenType == "case":
                childNode = builder.CASE_build(tokenizer)
                builder.CASE_setLabel(childNode, Expression(tokenizer, staticContext))
                tokenizer.mustMatch("colon")
                builder.CASE_initializeStatements(childNode, tokenizer)

                while True:
                    tokenType=tokenizer.peek(True)
                    if tokenType == "case" or tokenType == "default" or tokenType == "right_curly":
                        break
                    builder.CASE_addStatement(childNode, Statement(tokenizer, staticContext))
                
                builder.CASE_finish(childNode)

            else:
                raise SyntaxError("Invalid switch case", tokenizer)

            builder.SWITCH_addCase(node, childNode)
            tokenType = tokenizer.get()

        staticContext.statementStack.pop()
        builder.SWITCH_finish(node)

        return node
        

    elif tokenType == "for":
        node = builder.FOR_build(tokenizer)
        forBlock = None
        
        if tokenizer.match("identifier") and tokenizer.token.value == "each":
            builder.FOR_rebuildForEach(node)
            
        tokenizer.mustMatch("left_paren")
        tokenType = tokenizer.peek()
        childNode = None
        
        if tokenType != "semicolon":
            staticContext.inForLoopInit = True
            
            if tokenType == "var" or tokenType == "const":
                tokenizer.get()
                childNode = Variables(tokenizer, staticContext)
            
            elif tokenType == "let":
                tokenizer.get()

                if tokenizer.peek() == "left_paren":
                    childNode = LetBlock(tokenizer, staticContext, False)
                    
                else:
                    # Let in for head, we need to add an implicit block
                    # around the rest of the for.
                    forBlock = builder.BLOCK_build(tokenizer, staticContext.blockId)
                    staticContext.blockId += 1
                    staticContext.statementStack.append(forBlock)
                    childNode = Variables(tokenizer, staticContext, forBlock)
                
            else:
                childNode = Expression(tokenizer, staticContext)
            
            staticContext.inForLoopInit = False

        if childNode and tokenizer.match("in"):
            builder.FOR_rebuildForIn(node)
            builder.FOR_setObject(node, Expression(tokenizer, staticContext), forBlock)
            
            if childNode.type == "var" or childNode.type == "let":
                if len(childNode) != 1:
                    raise SyntaxError("Invalid for..in left-hand side", tokenizer)

                builder.FOR_setIterator(node, childNode, forBlock)
                
            else:
                builder.FOR_setIterator(node, childNode, forBlock)

        else:
            builder.FOR_setSetup(node, childNode)
            tokenizer.mustMatch("semicolon")
            
            if node.isEach:
                raise SyntaxError("Invalid for each..in loop", tokenizer)
                
            if tokenizer.peek() == "semicolon":
                builder.FOR_setCondition(node, None)
            else:
                builder.FOR_setCondition(node, Expression(tokenizer, staticContext))
            
            tokenizer.mustMatch("semicolon")
            
            if tokenizer.peek() == "right_paren":
                builder.FOR_setUpdate(node, None)
            else:    
                builder.FOR_setUpdate(node, Expression(tokenizer, staticContext))
        
        tokenizer.mustMatch("right_paren")
        builder.FOR_setBody(node, nest(tokenizer, staticContext, node, Statement))
        
        if forBlock:
            builder.BLOCK_finish(forBlock)
            staticContext.statementStack.pop()
    
        builder.FOR_finish(node)
        return node
        
        
    elif tokenType == "while":
        node = builder.WHILE_build(tokenizer)
        
        builder.WHILE_setCondition(node, ParenExpression(tokenizer, staticContext))
        builder.WHILE_setBody(node, nest(tokenizer, staticContext, node, Statement))
        builder.WHILE_finish(node)
        
        return node                                    
        
        
    elif tokenType == "do":
        node = builder.DO_build(tokenizer)
        
        builder.DO_setBody(node, nest(tokenizer, staticContext, node, Statement, "while"))
        builder.DO_setCondition(node, ParenExpression(tokenizer, staticContext))
        builder.DO_finish(node)
        
        if not staticContext.ecma3OnlyMode:
            # <script language="JavaScript"> (without version hints) may need
            # automatic semicolon insertion without a newline after do-while.
            # See http://bugzilla.mozilla.org/show_bug.cgi?id=238945.
            tokenizer.match("semicolon")
            return node

        # NO RETURN
      
      
    elif tokenType == "break" or tokenType == "continue":
        if tokenType == "break":
            node = builder.BREAK_build(tokenizer) 
        else:
            node = builder.CONTINUE_build(tokenizer)

        if tokenizer.peekOnSameLine() == "identifier":
            tokenizer.get()
            
            if tokenType == "break":
                builder.BREAK_setLabel(node, tokenizer.token.value)
            else:
                builder.CONTINUE_setLabel(node, tokenizer.token.value)

        statementStack = staticContext.statementStack
        i = len(statementStack)
        label = node.label if hasattr(node, "label") else None

        if label:
            while True:
                i -= 1
                if i < 0:
                    raise SyntaxError("Label not found", tokenizer)
                if getattr(statementStack[i], "label", None) == label:
                    break

            # 
            # Both break and continue to label need to be handled specially
            # within a labeled loop, so that they target that loop. If not in
            # a loop, then break targets its labeled statement. Labels can be
            # nested so we skip all labels immediately enclosing the nearest
            # non-label statement.
            # 
            while i < len(statementStack) - 1 and statementStack[i+1].type == "label":
                i += 1
                
            if i < len(statementStack) - 1 and getattr(statementStack[i+1], "isLoop", False):
                i += 1
            elif tokenType == "continue":
                raise SyntaxError("Invalid continue", tokenizer)
                
        else:
            while True:
                i -= 1
                if i < 0:
                    if tokenType == "break":
                        raise SyntaxError("Invalid break", tokenizer)
                    else:
                        raise SyntaxError("Invalid continue", tokenizer)

                if getattr(statementStack[i], "isLoop", False) or (tokenType == "break" and statementStack[i].type == "switch"):
                    break
        
        if tokenType == "break":
            builder.BREAK_finish(node)
        else:
            builder.CONTINUE_finish(node)
        
        # NO RETURN


    elif tokenType == "try":
        node = builder.TRY_build(tokenizer)
        builder.TRY_setTryBlock(node, Block(tokenizer, staticContext))
        
        while tokenizer.match("catch"):
            childNode = builder.CATCH_build(tokenizer)
            tokenizer.mustMatch("left_paren")
            nextTokenType = tokenizer.get()
            
            if nextTokenType == "left_bracket" or nextTokenType == "left_curly":
                # Destructured catch identifiers.
                tokenizer.unget()
                exception = DestructuringExpression(tokenizer, staticContext, True)
            
            elif nextTokenType == "identifier":
                exception = builder.CATCH_wrapException(tokenizer)
            
            else:
                raise SyntaxError("Missing identifier in catch", tokenizer)
                
            builder.CATCH_setException(childNode, exception)
            
            if tokenizer.match("if"):
                if staticContext.ecma3OnlyMode:
                    raise SyntaxError("Illegal catch guard", tokenizer)
                    
                if node.getChildrenLength() > 0 and not node.getUnrelatedChildren()[0].guard:
                    raise SyntaxError("Guarded catch after unguarded", tokenizer)
                    
                builder.CATCH_setGuard(childNode, Expression(tokenizer, staticContext))
                
            else:
                builder.CATCH_setGuard(childNode, None)
            
            tokenizer.mustMatch("right_paren")
            
            builder.CATCH_setBlock(childNode, Block(tokenizer, staticContext))
            builder.CATCH_finish(childNode)
            
            builder.TRY_addCatch(node, childNode)
        
        builder.TRY_finishCatches(node)
        
        if tokenizer.match("finally"):
            builder.TRY_setFinallyBlock(node, Block(tokenizer, staticContext))
            
        if node.getChildrenLength() == 0 and not hasattr(node, "finallyBlock"):
            raise SyntaxError("Invalid try statement", tokenizer)
            
        builder.TRY_finish(node)
        return node
        

    elif tokenType == "catch" or tokenType == "finally":
        raise SyntaxError(tokens[tokenType] + " without preceding try", tokenizer)


    elif tokenType == "throw":
        node = builder.THROW_build(tokenizer)
        
        builder.THROW_setException(node, Expression(tokenizer, staticContext))
        builder.THROW_finish(node)
        
        # NO RETURN


    elif tokenType == "return":
        node = returnOrYield(tokenizer, staticContext)
        
        # NO RETURN


    elif tokenType == "with":
        node = builder.WITH_build(tokenizer)

        builder.WITH_setObject(node, ParenExpression(tokenizer, staticContext))
        builder.WITH_setBody(node, nest(tokenizer, staticContext, node, Statement))
        builder.WITH_finish(node)

        return node


    elif tokenType == "var" or tokenType == "const":
        node = Variables(tokenizer, staticContext)
        
        # NO RETURN
        

    elif tokenType == "let":
        if tokenizer.peek() == "left_paren":
            node = LetBlock(tokenizer, staticContext, True)
        else:
            node = Variables(tokenizer, staticContext)
        
        # NO RETURN
        

    elif tokenType == "debugger":
        node = builder.DEBUGGER_build(tokenizer)
        
        # NO RETURN
        

    elif tokenType == "newline" or tokenType == "semicolon":
        node = builder.SEMICOLON_build(tokenizer)

        builder.SEMICOLON_setExpression(node, None)
        builder.SEMICOLON_finish(tokenizer)
        
        return node


    else:
        if tokenType == "identifier":
            tokenType = tokenizer.peek()

            # Labeled statement.
            if tokenType == "colon":
                label = tokenizer.token.value
                statementStack = staticContext.statementStack
               
                i = len(statementStack)-1
                while i >= 0:
                    if getattr(statementStack[i], "label", None) == label:
                        raise SyntaxError("Duplicate label", tokenizer)
                    
                    i -= 1
               
                tokenizer.get()
                node = builder.LABEL_build(tokenizer)
                
                builder.LABEL_setLabel(node, label)
                builder.LABEL_setStatement(node, nest(tokenizer, staticContext, node, Statement))
                builder.LABEL_finish(node)
                
                return node

        # Expression statement.
        # We unget the current token to parse the expression as a whole.
        node = builder.SEMICOLON_build(tokenizer)
        tokenizer.unget()
        builder.SEMICOLON_setExpression(node, Expression(tokenizer, staticContext))
        node.end = node.expression.end
        builder.SEMICOLON_finish(node)
        
        # NO RETURN
        

    MagicalSemicolon(tokenizer)
    return node
Parses a Statement.
dataset/ETHPy150Open zynga/jasy/jasy/js/parse/Parser.py/Statement