PIPS
parser.c
Go to the documentation of this file.
1 /*
2 
3  $Id: parser.c 23259 2016-11-02 07:34:47Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* Pre-parser for Fortran syntax idiosyncrasy
28  */
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "genC.h"
35 #include "linear.h"
36 #include "ri.h"
37 #include "ri-util.h"
38 #include "parser_private.h"
39 
40 #include "syntax.h"
41 
42 #include "resources.h"
43 #include "database.h"
44 
45 #include "misc.h"
46 #include "pipsdbm.h"
47 ␌
48 /* name of the current file */
49 char *CurrentFN = NULL;
50 
51 /* the current function */
52 /* entity CurrentFunction; */
53 
54 /* list of formal parameters of the current function */
56 
57 /* the name of the current package, i.e. TOP-LEVEL or a module name? */
58 const char *CurrentPackage = NULL;
59 
60 
61 /* Indicates where the current instruction (in fact statement) starts and
62  ends in the input file and gives its label. Temporary versions of these
63  variables are used because of the pipeline existing between the reader
64  and the actual parser. The names of the temporary variables are
65  prefixed with "tmp_". The default and reset values of these variables
66  and their temporary versions (declared in reader.c) must be
67  consistent. */
69 char lab_I[6];
70 ␌
72 {
73  strcpy(lab_I, "");
74 }
75 
77 {
78  return lab_I;
79 }
80 
81 void set_current_label_string(string ln)
82 {
83  pips_assert("Label name is at most 5 characters long", strlen(ln)<=5);
84  strcpy(lab_I, ln);
85 }
86 
88 {
89  bool empty_p = same_string_p(lab_I, "");
90 
91  return empty_p;
92 }
93 /* a string that will contain the value of the format in case of format
94 statement */
96 
97 ␌
98 static bool parser_recursive_call = false;
99 
100 /* Safety for recursive calls of parser required to process entries */
102 {
103  parser_recursive_call = false;
104 }
105 
107 {
108  parser_recursive_call = false;
109 }
110 ␌
111 /* Parser error handling */
112 
113 bool InParserError = false;
114 
115 // does not always return
116 bool ParserError(const char * f, const char * m)
117 {
119 
120  /* Maybe a routine called by ParserError() may call ParserError()
121  * e.g. AbortOfProcedure() thru remove_ghost_variables()
122  */
123  if(InParserError)
124  return false;
125 
126  InParserError = true;
127 
128  uses_alternate_return(false);
131 
132  syn_reset_lex();
133 
134  ResetBlockStack();
135 
136  /* Get rid of partly declared variables... */
137  if(mod!=entity_undefined) {
138  /* Callers may already have pointers towards this function.
139  * The prettyprinter core dumps if entity_initial is
140  * destroyed. Maybe, I should clean the declarations field
141  * in code, as well as decls_text.
142  */
143  /*
144  entity_type(mod) = type_undefined;
145  entity_storage(mod) = storage_undefined;
146  entity_initial(mod) = value_undefined;
147  */
148  value v = entity_initial(mod);
149  code c = value_code(v);
150  code_declarations(c) = NIL;
152 
153  CleanLocalEntities(mod);
154  }
155 
156  /* The error may occur before the current module entity is defined */
159  free(CurrentFN);
160  CurrentFN = NULL;
161 
162  /* GetChar() will reinitialize its own buffer when called */
163 
164  /* Because of the strange behavior of BeginingOfParsing*/
165  /* CurrentPackage = NULL; */
167  /* Too bad for memory leak... */
176  ResetChains();
177  AbortEntries();
179 
180  InParserError = false;
181 
182  /* FI: let catch_error() take care of this in pipsmake since debug_on()
183  was not activated in ParserError */
184  /* debug_off(); */
185  user_error(f,"Parser error between lines %d and %d\n%s\n",
186  line_b_I,line_e_I,m);
187 
188  /* Should never be executed */
189  return true;
190 }
191 
192 
193 /* this function is called for each new file (FI: once?)
194  * FI: I do not understand how this works. It has an effect only once
195  * during a pips process lifetime. The error handling routine resets
196  * CurrentPackage to NULL, as it is when the pips process is started.
197  *
198  * Should I:
199  *
200  * A modify the error handling routine to reset CurrentPackage to
201  * TOP_LEVEL_MODULE_NAME?
202  *
203  * B reset CurrentPackage to TOP_LEVEL_MODULE_NAME each time the parser
204  * is entered?
205  *
206  * I choose A.
207  */
209 {
210  static bool called = false;
211 
212  if (called)
213  return;
214 
215  /* the current package is initialized */
217  called = true;
218 }
219 
220 /* parse "module.dbr_file"
221  */
222 
223 static bool the_actual_parser(string module,
224  string dbr_file)
225 {
226  string dir;
227  debug_on("SYNTAX_DEBUG_LEVEL");
228 
229  /* set up parser properties */
232 
233  /* parser is initialized */
235 
236  /* scanner is initialized */
237  ScanNewFile();
238 
239  pips_assert("CurrentFN is NULL", CurrentFN==NULL);
241  CurrentFN =
242  strdup(concatenate(dir, "/",
243  db_get_file_resource(dbr_file, module, true), 0));
244  free(dir);
245 
246  /* yacc parser is called */
247  syn_in = safe_fopen(CurrentFN, "r");
248  syn_parse();
250  free(CurrentFN);
251  CurrentFN = NULL;
252 
253  /* Handle the special case for entries without looping forever */
254  if(!parser_recursive_call) {
255  if(!EmptyEntryListsP()) {
256  /* The requested parsed code may have been an entry code. Then it
257  * is not yet computed because the parsed code for the module was
258  * produced and only a file resource was produced for the entry code.
259  */
260  ResetEntries();
261  if(!db_resource_p(DBR_PARSED_CODE, module)) {
263  the_actual_parser(module, dbr_file);
265  }
266  }
267  }
268  else {
269  if(!EmptyEntryListsP()) {
270  pips_internal_error("Unexpected entry handling in parser recursive call");
271  }
272  }
273 
274  /* This debug_off() occurs too late since pipsdbm has been called
275  * before. Initially, the parser was designed to parse more than
276  * one subroutine/function/program at a time. */
277  debug_off();
278 
279  return true;
280 }
281 
282 /* parser for HPFC.
283  * just a different input file not to touch the original source file.
284  * this parser should be selected/activated automatically.
285  */
286 bool hpfc_parser(const string module)
287 {
288  return the_actual_parser(module, DBR_HPFC_FILTERED_FILE);
289 }
290 
291 bool parser(const string module)
292 {
293  return the_actual_parser(module, DBR_SOURCE_FILE);
294 }
295 
297 {
299 }
bool db_resource_p(const char *rname, const char *oname)
true if exists and in loaded or stored state.
Definition: database.c:524
entity DynamicArea
These global variables are declared in ri-util/util.c.
Definition: area.c:57
entity HeapArea
Definition: area.c:59
entity StaticArea
Definition: area.c:58
void CleanLocalEntities(entity function)
Fortran version.
Definition: clean.c:140
void reset_common_size_map_on_error()
Definition: declaration.c:972
void ResetChains()
undefine chains between two successives calls to parser
Definition: equivalence.c:65
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
void free(void *)
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void parser_init_macros_support(void)
next available chunk
Definition: macros.c:57
#define debug_on(env)
Definition: misc-local.h:157
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
#define user_error(fn,...)
Definition: misc-local.h:265
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
#define string_undefined
Definition: newgen_types.h:40
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static char * module
Definition: pips.c:74
#define db_get_file_resource
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
void AbortEntries()
Definition: procedure.c:1473
void ResetEntries()
Definition: procedure.c:1458
bool EmptyEntryListsP()
Definition: procedure.c:1506
void AbortOfProcedure()
Definition: procedure.c:386
void parser_reset_all_reader_buffers(void)
Definition: reader.c:313
void ScanNewFile(void)
La fonction a appeler pour l'analyse d'un nouveau fichier.
Definition: reader.c:474
void init_parser_reader_properties()
Definition: reader.c:434
void error_reset_current_module_entity(void)
To be called by an error management routine only.
Definition: static.c:109
#define code_declarations(x)
Definition: ri.h:784
#define entity_undefined
Definition: ri.h:2761
#define value_code(x)
Definition: ri.h:3067
#define code_decls_text(x)
Definition: ri.h:786
#define entity_initial(x)
Definition: ri.h:2796
char * strdup()
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
int syn_parse(void)
#define FORMATLENGTH
Definition: syntax-local.h:44
FILE * syn_in
lex yacc interface
Definition: syntax.h:325
void syn_reset_lex()
int line_e_C
Definition: parser.c:68
void set_current_label_string(string ln)
Definition: parser.c:81
char * CurrentFN
Pre-parser for Fortran syntax idiosyncrasy.
Definition: parser.c:49
static void reset_parser_recursive_call()
Safety for recursive calls of parser required to process entries.
Definition: parser.c:101
cons * FormalParameters
the current function
Definition: parser.c:55
bool InParserError
Parser error handling.
Definition: parser.c:113
static bool the_actual_parser(string module, string dbr_file)
parse "module.dbr_file"
Definition: parser.c:223
static void set_parser_recursive_call()
Definition: parser.c:106
int line_e_I
Definition: parser.c:68
int line_b_C
Definition: parser.c:68
int line_b_I
Indicates where the current instruction (in fact statement) starts and ends in the input file and giv...
Definition: parser.c:68
void BeginingOfParsing()
this function is called for each new file (FI: once?) FI: I do not understand how this works.
Definition: parser.c:208
string get_current_label_string()
Definition: parser.c:76
bool empty_current_label_string_p()
Definition: parser.c:87
char FormatValue[FORMATLENGTH]
a string that will contain the value of the format in case of format statement
Definition: parser.c:95
char lab_I[6]
Definition: parser.c:69
bool ParserError(const char *f, const char *m)
Definition: parser.c:116
void init_parser_properties(void)
Definition: parser.c:296
bool hpfc_parser(const string module)
parser for HPFC.
Definition: parser.c:286
void reset_current_label_string()
Definition: parser.c:71
static bool parser_recursive_call
Definition: parser.c:98
const char * CurrentPackage
the name of the current package, i.e.
Definition: parser.c:58
bool parser(const string module)
Definition: parser.c:291
void soft_reset_alternate_returns()
ParserError() cannot guess if it has been performed or not, because it is reinitialized before and af...
Definition: return.c:284
void SubstituteAlternateReturns(const char *option)
return.c
Definition: return.c:59
void uses_alternate_return(bool use)
Definition: return.c:171
void ResetReturnCodeVariable()
Definition: return.c:151
void ResetBlockStack()
Definition: statement.c:203
void parser_reset_StmtHeap_buffer(void)
statement.c
Definition: statement.c:85