private Stmt parseHeadlessStatement ( EnclosingScope scope ) { int start = index ; // See if it is a named block Identifier blockName = parseOptionalIdentifier ( scope ) ; if ( blockName != null ) { if ( tryAndMatch ( true , Colon ) != null && isAtEOL ( ) ) { int end = index ; matchEndLine ( ) ; scope = scope . newEnclosingScope ( ) ; scope . declareLifetime ( blockName ) ; Stmt . Block body = parseBlock ( scope , false ) ; return annotateSourceLocation ( new Stmt . NamedBlock ( blockName , body ) , start ) ; } else { index = start ; // backtrack } } // assignment : Identifier | LeftBrace | Star // variable decl: Identifier | LeftBrace | LeftCurly | Ampersand // invoke : Identifier | LeftBrace | Star if ( tryAndMatch ( false , Final ) != null || ( skipType ( scope ) && tryAndMatch ( false , Identifier ) != null ) ) { // Must be a variable declaration as this is the only situation in which a type // can be followed by an identifier. index = start ; // backtrack // return parseVariableDeclaration ( scope ) ; } // Must be an assignment or invocation index = start ; // backtrack // Expr e = parseExpression ( scope , false ) ; // if ( e instanceof Expr . Invoke || e instanceof Expr . IndirectInvoke ) { // Must be an invocation since these are neither valid // lvals (i.e. they cannot be assigned) nor types. matchEndLine ( ) ; return e ; } else { // At this point, the only remaining option is an assignment statement. // Therefore, it must be that. index = start ; // backtrack // return parseAssignmentStatement ( scope ) ; } }
A headless statement is one which has no identifying keyword . The set of headless statements include assignments invocations variable declarations and named blocks .