📄 sta.c
字号:
ffesta_current_possible_ = first_named; else if (ffesta_seen_first_exec && (first_exec != NULL)) ffesta_current_possible_ = first_exec; else ffesta_current_possible_ = first; ffesta_current_handler_ = ffesta_current_possible_->handler; assert (ffesta_current_handler_ != NULL); } else { /* Confirmed success, use it. */ ffesta_current_possible_ = ffesta_confirmed_possible_; ffesta_current_handler_ = ffesta_confirmed_possible_->handler; } ffesta_reset_possibles_ (); } else { /* Switching from [empty?] list of nonexecs to nonempty list of execs at this point. */ ffesta_tokens[0] = ffelex_token_use (ffesta_token_0_); ffesymbol_set_retractable (ffesta_scratch_pool); } } else { ffesta_tokens[0] = ffelex_token_use (ffesta_token_0_); ffesymbol_set_retractable (ffesta_scratch_pool); } /* Send saved tokens to current handler until either shut down or all tokens sent. */ for (toknum = 0; toknum < num_saved_tokens; ++toknum) { t = *(saved_tokens + toknum); switch (ffelex_token_type (t)) { case FFELEX_typeCHARACTER: ffelex_set_expecting_hollerith (0, '\0', ffewhere_line_unknown (), ffewhere_column_unknown ()); ffesta_current_handler_ = (ffelexHandler) (*ffesta_current_handler_) (t); break; case FFELEX_typeNAMES: if (ffelex_is_names_expected ()) ffesta_current_handler_ = (ffelexHandler) (*ffesta_current_handler_) (t); else { t2 = ffelex_token_name_from_names (t, 0, 0); ffesta_current_handler_ = (ffelexHandler) (*ffesta_current_handler_) (t2); ffelex_token_kill (t2); } break; default: ffesta_current_handler_ = (ffelexHandler) (*ffesta_current_handler_) (t); break; } if (!ffesta_is_inhibited_) ffelex_token_kill (t); /* Won't need this any more. */ /* See if this possible has been shut down. */ else if ((ffesta_current_shutdown_ || (FFESTA_ABORT_ON_CONFIRM_ && ffesta_confirmed_current_)) && !ffelex_expecting_character ()) { switch (ffelex_token_type (t)) { case FFELEX_typeEOS: case FFELEX_typeSEMICOLON: break; default: eos = ffelex_token_new_eos (ffelex_token_where_line (t), ffelex_token_where_column (t)); ffesta_inhibit_confirmation_ = ffesta_current_shutdown_; (*ffesta_current_handler_) (eos); ffesta_inhibit_confirmation_ = FALSE; ffelex_token_kill (eos); break; } goto next_handler; /* :::::::::::::::::::: */ } } /* Finished sending all the tokens so far. If still trying possibilities, then if we've just sent an EOS or SEMICOLON token through, go to the next handler. Otherwise, return self so we can gather and process more tokens. */ if (ffesta_is_inhibited_) { switch (ffelex_token_type (t)) { case FFELEX_typeEOS: case FFELEX_typeSEMICOLON: goto next_handler; /* :::::::::::::::::::: */ default:#if FFESTA_ABORT_ON_CONFIRM_ assert (!ffesta_confirmed_other_); /* Catch ambiguities. */#endif return (ffelexHandler) ffesta_save_; } } /* This was the one final possibility, uninhibited, so send the final handler it sent. */ num_saved_tokens = 0;#if !FFESTA_ABORT_ON_CONFIRM_ if (ffesta_is_two_into_statement_) { /* End of the line for the previous two tokens, resurrect them. */ ffelexHandler next; ffesta_is_two_into_statement_ = FALSE; next = (ffelexHandler) ffesta_first (ffesta_twotokens_1_); ffelex_token_kill (ffesta_twotokens_1_); next = (ffelexHandler) (*next) (ffesta_twotokens_2_); ffelex_token_kill (ffesta_twotokens_2_); return (ffelexHandler) next; }#endif assert (ffesta_current_handler_ != NULL); return (ffelexHandler) ffesta_current_handler_;}/* ffesta_second_ -- Parse the token after a NAME/NAMES in a statement return ffesta_second_; // to lexer. The second token cannot be a NAMES, since the first token is a NAME or NAMES. If the second token is a NAME, look up its name in the list of second names for use by whoever needs it. Then make a list of all the possible statements this could be, based on looking at the first two tokens. Two lists of possible statements are created, one consisting of nonexecutable statements, the other consisting of executable statements. If the total number of possibilities is one, just fire up that possibility by calling its handler function, passing the first two tokens through it and so on. Otherwise, start up a process whereby tokens are passed to the first possibility on the list until EOS or SEMICOLON is reached or an error is detected. But inhibit any actual reporting of errors; just record their existence in the list. If EOS or SEMICOLON is reached with no errors (other than non-form errors happening downstream, such as an overflowing value for an integer or a GOTO statement identifying a label on a FORMAT statement), then that is the only possible statement. Rerun the statement with error-reporting turned on if any non-form errors were generated, otherwise just use its results, then erase the list of tokens memorized during the search process. If a form error occurs, immediately cancel that possibility by sending EOS as the next token, remember the error code for that possibility, and try the next possibility on the list, first sending it the list of tokens memorized while handling the first possibility, then continuing on as before. Ultimately, either the end of the list of possibilities will be reached without any successful forms being detected, in which case we pick one based on hueristics (usually the first possibility) and rerun it with error reporting turned on using the list of memorized tokens so the user sees the error, or one of the possibilities will effectively succeed. */static ffelexHandlerffesta_second_ (ffelexToken t){ ffelexHandler next; ffesymbol s; assert (ffelex_token_type (t) != FFELEX_typeNAMES); if (ffelex_token_type (t) == FFELEX_typeNAME) ffesta_second_kw = ffestr_second (t); /* Here we use switch on the first keyword name and handle each possible recognizable name by looking at the second token, and building the list of possible names accordingly. For now, just put every possible statement on the list for ambiguity checking. */ switch (ffesta_first_kw) {#if FFESTR_VXT case FFESTR_firstACCEPT: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V019); break;#endif#if FFESTR_F90 case FFESTR_firstALLOCATABLE: ffestb_args.dimlist.len = FFESTR_firstlALLOCATABLE; ffestb_args.dimlist.badname = "ALLOCATABLE"; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dimlist); break;#endif#if FFESTR_F90 case FFESTR_firstALLOCATE: ffestb_args.heap.len = FFESTR_firstlALLOCATE; ffestb_args.heap.badname = "ALLOCATE"; ffestb_args.heap.ctx = FFEEXPR_contextALLOCATE; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_heap); break;#endif case FFESTR_firstASSIGN: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R838); break; case FFESTR_firstBACKSPACE: ffestb_args.beru.len = FFESTR_firstlBACKSPACE; ffestb_args.beru.badname = "BACKSPACE"; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru); break; case FFESTR_firstBLOCK: ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_block); break; case FFESTR_firstBLOCKDATA: ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_blockdata); break; case FFESTR_firstBYTE: ffestb_args.decl.len = FFESTR_firstlBYTE; ffestb_args.decl.type = FFESTP_typeBYTE; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); break; case FFESTR_firstCALL: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1212); break; case FFESTR_firstCASE: case FFESTR_firstCASEDEFAULT: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R810); break; case FFESTR_firstCHRCTR: ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_chartype); break; case FFESTR_firstCLOSE: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R907); break; case FFESTR_firstCOMMON: ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R547); break; case FFESTR_firstCMPLX: ffestb_args.decl.len = FFESTR_firstlCMPLX; ffestb_args.decl.type = FFESTP_typeCOMPLEX; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); break;#if FFESTR_F90 case FFESTR_firstCONTAINS: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1228); break;#endif case FFESTR_firstCONTINUE: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R841); break; case FFESTR_firstCYCLE: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R834); break; case FFESTR_firstDATA: if (ffe_is_pedantic_not_90 ()) ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R528); else ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R528); break;#if FFESTR_F90 case FFESTR_firstDEALLOCATE: ffestb_args.heap.len = FFESTR_firstlDEALLOCATE; ffestb_args.heap.badname = "DEALLOCATE"; ffestb_args.heap.ctx = FFEEXPR_contextDEALLOCATE; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_heap); break;#endif#if FFESTR_VXT case FFESTR_firstDECODE: ffestb_args.vxtcode.len = FFESTR_firstlDECODE; ffestb_args.vxtcode.badname = "DECODE"; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_vxtcode); break;#endif#if FFESTR_VXT case FFESTR_firstDEFINEFILE: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V025); break; case FFESTR_firstDELETE: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V021); break;#endif case FFESTR_firstDIMENSION: ffestb_args.R524.len = FFESTR_firstlDIMENSION; ffestb_args.R524.badname = "DIMENSION"; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R524); break; case FFESTR_firstDO: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_do); break; case FFESTR_firstDBL: ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_double); break; case FFESTR_firstDBLCMPLX: ffestb_args.decl.len = FFESTR_firstlDBLCMPLX; ffestb_args.decl.type = FFESTP_typeDBLCMPLX; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_dbltype); break; case FFESTR_firstDBLPRCSN: ffestb_args.decl.len = FFESTR_firstlDBLPRCSN; ffestb_args.decl.type = FFESTP_typeDBLPRCSN; ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_dbltype); break; case FFESTR_firstDOWHILE: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_dowhile); break; case FFESTR_firstELSE: ffesta_add_possible_exec_ ((ffelexHandler) ffestb_else); break; case FFESTR_firstELSEIF: ffestb_args.elsexyz.second = FFESTR_secondIF; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_elsexyz); break;#if FFESTR_F90 case FFESTR_firstELSEWHERE: ffestb_args.elsexyz.second = FFESTR_secondWHERE; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_elsexyz); break;#endif#if FFESTR_VXT case FFESTR_firstENCODE: ffestb_args.vxtcode.len = FFESTR_firstlENCODE; ffestb_args.vxtcode.badname = "ENCODE"; ffesta_add_possible_exec_ ((ffelexHandler) ffestb_vxtcode); break;#endif case FFESTR_firstEND: if ((ffelex_token_type (ffesta_token_0_) == FFELEX_typeNAMES) || (ffelex_token_type (t) != FFELEX_typeNAME)) ffesta_add_possible_exec_ ((ffelexHandler) ffestb_end); else { switch (ffesta_second_kw) { case FFESTR_secondBLOCK: case FFESTR_secondBLOCKDATA: case FFESTR_secondDO: case FFESTR_secondFILE: case FFESTR_secondFUNCTION: case FFESTR_secondIF:#if FFESTR_F90 case FFESTR_secondMODULE:#endif case FFESTR_secondPROGRAM: case FFESTR_secondSELECT: case FFESTR_secondSUBROUTINE:#if FFESTR_F90 case FFESTR_secondWHERE:#endif ffesta_add_possible_exec_ ((ffelexHandler) ffestb_end); break; default: ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_end); break; } } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -