void Parser::Statement(string functionName) { _message.print(DBUG, "PARSER: In Statement()\n"); // ExpressionStatement // | CompoundStatement // | SelectionStatement // | RepetitionStatement // | ReturnStatement static tokenType statementFirstSet[] = {SYM_PLUS, SYM_MINUS, SYM_NOT, SYM_CURLY_OPEN, KW_IF, KW_WHILE, KW_RETURN, SYM_OPEN, LIT_INT, LIT_FLOAT, LIT_STR, TOK_IDENT, SYM_SEMICOLON, (tokenType) - 1}; static tokenType followSet[] = {TOK_EOF, KW_ELSE, SYM_CURLY_CLOSE, KW_VOID, KW_INT, KW_FLOAT, SYM_PLUS, SYM_MINUS, SYM_NOT, SYM_CURLY_OPEN, KW_IF, KW_WHILE, KW_RETURN, SYM_OPEN, LIT_INT, LIT_FLOAT, LIT_STR, TOK_IDENT, (tokenType) - 1}; if ( synchronized(statementFirstSet, followSet, "Expected Statement") ) { if ( _lookAhead.getTokenType() == SYM_CURLY_OPEN ) { _symbolTable->openScope(); CompoundStatement(functionName); // _symbolTable->dump(); _symbolTable->closeScope(); } else if ( _lookAhead.getTokenType() == KW_IF ) { SelectionStatement(functionName); } else if ( _lookAhead.getTokenType() == KW_WHILE ) { RepetitionStatement(functionName); } else if ( _lookAhead.getTokenType() == KW_RETURN ) { ReturnStatement(functionName); } else { ExpressionStatement(); } } _message.print(DBUG, "PARSER: End of Statement()\n"); }
static void Statement(void) { switch(Token) { case tIF: IfStatement(); break; case tUNLESS: UnlessStatement(); break; case tCASE: CaseStatement(); break; case tFOR: ForStatement(); break; case tWHILE: WhileStatement(); break; case tUNTIL: UntilStatement(); break; case tBREAK: BreakStatement(); break; case tRETURN: ReturnStatement(); break; case tPUBLIC: PublicStatement(); break; case tPROTECTED: ProtectedStatement(); break; case tPRIVATE: PrivateStatement(); break; case tLIBRARY: LibraryStatement(); break; default: AssignmentStatement(); break; } if( Token==tSEMI ) NextToken(); }
int Statement (int* PendingToken) /* Statement parser. Returns 1 if the statement does a return/break, returns ** 0 otherwise. If the PendingToken pointer is not NULL, the function will ** not skip the terminating token of the statement (closing brace or ** semicolon), but store true if there is a pending token, and false if there ** is none. The token is always checked, so there is no need for the caller to ** check this token, it must be skipped, however. If the argument pointer is ** NULL, the function will skip the token. */ { ExprDesc Expr; int GotBreak; CodeMark Start, End; /* Assume no pending token */ if (PendingToken) { *PendingToken = 0; } /* Check for a label. A label is always part of a statement, it does not ** replace one. */ while (CurTok.Tok == TOK_IDENT && NextTok.Tok == TOK_COLON) { /* Handle the label */ DoLabel (); if (CheckLabelWithoutStatement ()) { return 0; } } switch (CurTok.Tok) { case TOK_LCURLY: NextToken (); GotBreak = CompoundStatement (); CheckTok (TOK_RCURLY, "`{' expected", PendingToken); return GotBreak; case TOK_IF: return IfStatement (); case TOK_WHILE: WhileStatement (); break; case TOK_DO: DoStatement (); break; case TOK_SWITCH: SwitchStatement (); break; case TOK_RETURN: ReturnStatement (); CheckSemi (PendingToken); return 1; case TOK_BREAK: BreakStatement (); CheckSemi (PendingToken); return 1; case TOK_CONTINUE: ContinueStatement (); CheckSemi (PendingToken); return 1; case TOK_FOR: ForStatement (); break; case TOK_GOTO: GotoStatement (); CheckSemi (PendingToken); return 1; case TOK_SEMI: /* Ignore it */ CheckSemi (PendingToken); break; case TOK_PRAGMA: DoPragma (); break; case TOK_CASE: CaseLabel (); CheckLabelWithoutStatement (); break; case TOK_DEFAULT: DefaultLabel (); CheckLabelWithoutStatement (); break; default: /* Remember the current code position */ GetCodePos (&Start); /* Actual statement */ ExprWithCheck (hie0, &Expr); /* Load the result only if it is an lvalue and the type is ** marked as volatile. Otherwise the load is useless. */ if (ED_IsLVal (&Expr) && IsQualVolatile (Expr.Type)) { LoadExpr (CF_NONE, &Expr); } /* If the statement didn't generate code, and is not of type ** void, emit a warning. */ GetCodePos (&End); if (CodeRangeIsEmpty (&Start, &End) && !IsTypeVoid (Expr.Type) && IS_Get (&WarnNoEffect)) { Warning ("Statement has no effect"); } CheckSemi (PendingToken); } return 0; }