📄 stb.c
字号:
/* stb.c -- Implementation File (module.c template V1.0) Copyright (C) 1995, 1996 Free Software Foundation, Inc. Contributed by James Craig Burley.This file is part of GNU Fortran.GNU Fortran is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Fortran is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Fortran; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA02111-1307, USA. Related Modules: st.c Description: Parses the proper form for statements, builds up expression trees for them, but does not actually implement them. Uses ffebad (primarily via ffesta_ffebad_start) to indicate errors in form. In many cases, an invalid statement form indicates another possible statement needs to be looked at by ffest. In a few cases, a valid statement form might not completely determine the nature of the statement, as in REALFUNCTIONA(B), which is a valid form for either the first statement of a function named A taking an argument named B or for the declaration of a real array named FUNCTIONA with an adjustable size of B. A similar (though somewhat easier) choice must be made for the statement-function-def vs. assignment forms, as in the case of FOO(A) = A+2.0. A given parser consists of one or more state handlers, the first of which is the initial state, and the last of which (for any given input) returns control to a final state handler (ffesta_zero or ffesta_two, explained below). The functions handling the states for a given parser usually have the same names, differing only in the final number, as in ffestb_foo_ (handles the initial state), ffestb_foo_1_, ffestb_foo_2_ (handle subsequent states), although liberties sometimes are taken with the "foo" part either when keywords are clarified into given statements or are transferred into other possible areas. (For example, the type-name states can hop over to _dummy_ functions when the FUNCTION or RECURSIVE keywords are seen, though this kind of thing is kept to a minimum.) Only the names without numbers are exported to the rest of ffest; the others are local (static). Each initial state is provided with the first token in ffesta_tokens[0], which will be killed upon return to the final state (ffesta_zero or ffelex_swallow_tokens passed through to ffesta_zero), so while it may be changed to another token, a valid token must be left there to be killed. Also, a "convenient" array of tokens are left in ffesta_tokens[1..FFESTA_tokensMAX]. The initial state of this set of elements is undefined, thus, if tokens are stored here, they must be killed before returning to the final state. Any parser may also use cross-state local variables by sticking a structure containing storage for those variables in the local union ffestb_local_ (unless the union goes on strike). Furthermore, parsers that handle more than one first or second tokens (like _varlist_, which handles EXTERNAL, INTENT, INTRINSIC, OPTIONAL, PUBLIC, or PRIVATE, and _endxyz_, which handles ENDBLOCK, ENDBLOCKDATA, ENDDO, ENDIF, and so on) may expect arguments from ffest in the ffest-wide union ffest_args_, the substructure specific to the parser. A parser's responsibility is: to call either ffesta_confirmed or ffest_ffebad_start before returning to the final state; to be the only parser that can possibly call ffesta_confirmed for a given statement; to call ffest_ffebad_start immediately upon recognizing a bad token (specifically one that another statement parser might confirm upon); to call ffestc functions only after calling ffesta_confirmed and only when ffesta_is_inhibited returns FALSE; and to call ffesta_is_inhibited only after calling ffesta_confirmed. Confirm as early as reasonably possible, even when only one ffestc function is called for the statement later on, because early confirmation can enhance the error-reporting capabilities if a subsequent error is detected and this parser isn't the first possibility for the statement. To assist the parser, functions like ffesta_ffebad_1t and _1p_ have been provided to make use of ffest_ffebad_start fairly easy. Modifications:*//* Include files. */#include "proj.h"#include "stb.h"#include "bad.h"#include "expr.h"#include "lex.h"#include "malloc.h"#include "src.h"#include "sta.h"#include "stc.h"#include "stp.h"#include "str.h"/* Externals defined here. */struct _ffestb_args_ ffestb_args;/* Simple definitions and enumerations. */#define FFESTB_KILL_EASY_ 1 /* 1 for only one _subr_kill_xyz_ fn. *//* Internal typedefs. */union ffestb_subrargs_u_ { struct { ffesttTokenList labels; /* Input arg, must not be NULL. */ ffelexHandler handler; /* Input arg, call me when done. */ bool ok; /* Output arg, TRUE if list ended in CLOSE_PAREN. */ } label_list; struct { ffesttDimList dims; /* Input arg, must not be NULL. */ ffelexHandler handler; /* Input arg, call me when done. */ mallocPool pool; /* Pool to allocate into. */ bool ok; /* Output arg, TRUE if list ended in CLOSE_PAREN. */ ffeexprContext ctx; /* DIMLIST or DIMLISTCOMMON. */#ifdef FFECOM_dimensionsMAX int ndims; /* For backends that really can't have infinite dims. */#endif } dim_list; struct { ffesttTokenList args; /* Input arg, must not be NULL. */ ffelexHandler handler; /* Input arg, call me when done. */ ffelexToken close_paren;/* Output arg if ok, CLOSE_PAREN token. */ bool is_subr; /* Input arg, TRUE if list in subr-def context. */ bool ok; /* Output arg, TRUE if list ended in CLOSE_PAREN. */ bool names; /* Do ffelex_set_names(TRUE) before return. */ } name_list; };union ffestb_local_u_ { struct { ffebld expr; } call_stmt; struct { ffebld expr; } go_to; struct { ffebld dest; bool vxtparam; /* If assignment might really be VXT PARAMETER stmt. */ } let; struct { ffebld expr; } if_stmt; struct { ffebld expr; } else_stmt; struct { ffebld expr; } dowhile; struct { ffebld var; ffebld start; ffebld end; } do_stmt; struct { bool is_cblock; } R522; struct { ffebld expr; bool started; } parameter; struct { ffesttExprList exprs; bool started; } equivalence; struct { ffebld expr; bool started; } data; struct { ffestrOther kw; } varlist;#if FFESTR_F90 struct { ffestrOther kw; } type;#endif struct { ffelexHandler next; } construct; struct { ffesttFormatList f; ffestpFormatType current; /* What we're currently working on. */ ffelexToken t; /* Token of what we're currently working on. */ ffesttFormatValue pre; ffesttFormatValue post; ffesttFormatValue dot; ffesttFormatValue exp; bool sign; /* _3_, pos/neg; elsewhere, signed/unsigned. */ bool complained; /* If run-time expr seen in nonexec context. */ } format;#if FFESTR_F90 struct { bool started; } moduleprocedure;#endif struct { ffebld expr; } selectcase; struct { ffesttCaseList cases; } case_stmt;#if FFESTR_F90 struct { ffesttExprList exprs; ffebld expr; } heap;#endif#if FFESTR_F90 struct { ffesttExprList exprs; } R624;#endif#if FFESTR_F90 struct { ffestpDefinedOperator operator; bool assignment; /* TRUE for INTERFACE ASSIGNMENT, FALSE for ...OPERATOR. */ bool slash; /* TRUE if OPEN_ARRAY, FALSE if OPEN_PAREN. */ } interface;#endif struct { bool is_cblock; } V014;#if FFESTR_VXT struct { bool started; ffebld u; ffebld m; ffebld n; ffebld asv; } V025;#endif struct { ffestpBeruIx ix; bool label; bool left; ffeexprContext context; } beru; struct { ffestpCloseIx ix; bool label; bool left; ffeexprContext context; } close; struct { ffestpDeleteIx ix; bool label; bool left; ffeexprContext context; } delete; struct { ffestpDeleteIx ix; bool label; bool left; ffeexprContext context; } find; struct { ffestpInquireIx ix; bool label; bool left; ffeexprContext context; bool may_be_iolength; } inquire; struct { ffestpOpenIx ix; bool label; bool left; ffeexprContext context; } open; struct { ffestpReadIx ix; bool label; bool left; ffeexprContext context; } read; struct { ffestpRewriteIx ix; bool label; bool left; ffeexprContext context; } rewrite; struct { ffestpWriteIx ix; bool label; bool left; ffeexprContext context; } vxtcode; struct { ffestpWriteIx ix; bool label; bool left; ffeexprContext context; } write;#if FFESTR_F90 struct { bool started; } structure;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -