PIPS
reader.c
Go to the documentation of this file.
1 /*
2 
3  $Id: reader.c 23065 2016-03-02 09:05:50Z 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 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32 
33 #include "genC.h"
34 #include "parser_private.h"
35 #include "linear.h"
36 #include "ri.h"
37 
38 #include "misc.h"
39 #include "ri-util.h"
40 
41 #include "syntax.h"
42 
43 /*
44  * Fortran est un langage un peu ancien (je ne dirais pas "tres ancien" car
45  * nous avons, lui et moi, le meme age) dans lequel les blancs ne sont pas
46  * significatifs, et dans lequel il n'y a pas de mot clefs reserves. Cela a
47  * pour consequence que l'analyse lexicale de Fortran est delicate, et ne peut
48  * etre effectuee avec lex. Plus exactement, il semble que les nouvelles
49  * versions de lex, avec 'look-ahead', permette d'analyser Fortran, mais je
50  * n'ai pas explore cette voie.
51  *
52  * J'ai prefere utiliser lex en lui fournissant une fonction 'getc' qui
53  * permette de lever les difficultes liees a Fortran.
54  *
55  * La nouvelle fonction getc fonctionne de la facon suivante. Getc lit d'un
56  * seul coup toutes les lignes d'une instruction Fortran, c'est a dire la
57  * ligne initiale et les 19 eventuelles lignes de continuation, et les stocke
58  * dans le buffer 'Stmt'. Au vol, getc repere le label, enleve tous les
59  * blancs, detecte les caracteres entre simples quotes, et met a jour 4
60  * variables externes, qui representent pour l'instruction courante la
61  * premiere et la derniere ligne commentaire, et la premiere et la derniere
62  * ligne source. Ensuite, le contenu du buffer Stmt est analyse pour y
63  * detecter les mot clefs, c'est a dire traiter les cas des instructions IF,
64  * ELSEIF, ASSIGN, DO, des declaratives IMPLICIT et FUNCTION, et des
65  * operateurs '.XX.' (.EQ., .NEQV., ...).
66  *
67  * Lorsqu'un mot clef est detecte, il est mis en minuscules dans le texte
68  * source, sauf la premiere lettre qui reste en majuscule. Ainsi, lex peut
69  * faire la difference entre le mot clef 'Assign' et l'identificateur
70  * 'ASSIGN'. Grace a la premiere lettre, lex peut detecter deux mots clef
71  * successifs, meme sans blanc pour les separer, comme dans
72  * 'IntegerFunctionASSIGN(X)'.
73  *
74  * Lorsqu'un operateur .XX. est detecte, il est remplace dans le source
75  * par '%XX%'. Ainsi, lex peut faire la difference entre une constante
76  * reelle et un operateur, comme dans '(X+1.%EQ%5)'. It used to be '_' but
77  * the underscore is replaced by percent to allow safely underscore in
78  * identifiers.
79  *
80  * Nullary operators .TRUE. and .FALSE. are also converted but are later
81  * seen as constants instead.
82  *
83  * Remi Triolet
84  *
85  * Modifications:
86  *
87  * - the double quote character is not part of Fortran character set; it
88  * should not appear, even in comments or formats (Francois Irigoin)
89  *
90  * - comments were associated with the wrong statement; iPrevComm and
91  * PrevComm were added to keep the right comment; syntax-local.h
92  * and statement.c were modified (Francois Irigoin)
93  *
94  * - ReadLine: there was no check for comment buffer overflow
95  * (Francois Irigoin, 12 February 1992)
96  *
97  * - replaced calls to Warning() by calls to pips_error() in CheckParenthesis
98  * to track a bug (Francois Irigoin, 21 February 1992)
99  * (Francois Irigoin, 7 June 1995)
100  *
101  * - toupper moved from GetChar into ReadLine to keep lower case letters
102  * in character strings and comments; tex_util/print.c had to be changed
103  * too to avoid putting everything in upper case at prettyprint type;
104  * statement.c was also modified to put the declaration part in upper
105  * case as before while keeping comments in their original case
106  * (Function check_first_statement). See minuscule.f in Validation
107  * (Francois Irigoin, 7 June 1995)
108  *
109  * - double quotes can be used instead of simple quotes for character
110  * string constants (Francois Irigoin, 11 novembre 1996)
111  *
112  * - empty and invisible lines made of TAB and SPACE characters are preserved
113  * as comments in the executable part as they are in the declaration part
114  * (Francois Irigoin, 25 juillet 1997).
115 
116  */
117 
118 /*-------------------------------------------------------------------------*/
119 /*
120  * macros
121  */
122 #define IS_QUOTED(c) (c>=256)
123 #define QUOTE(c) (c+256)
124 #define UNQUOTE(c) (IS_QUOTED(c) ? (c)-256 : (c))
125 
126 /*-------------------------------------------------------------------------*/
127 /*
128  * definitions
129  */
130 #define LOCAL static
131 
132 #define UNDEF -2
133 
134 #define FIRST_LINE 100
135 #define CONTINUATION_LINE 101
136 #define EOF_LINE 102
137 
138 /*-------------------------------------------------------------------------*/
139 /*
140  * declarations de variables externes locales
141  */
142 
143 /*********************************************************** COMMENT BUFFERS */
144 
145 /* Comm contains the comments for the current statement in ReadStmt().
146  * PrevComm contains the comments for the previous statement in ReadStmt(),
147  * which is currently being parsed.
148  * CurrComm contains the comments attached to the current line in ReadLine()
149  */
150 
151 #define INITIAL_BUFFER_SIZE (128)
152 char * Comm = NULL, * PrevComm = NULL, * CurrComm;
153 int iComm = 0, iPrevComm = 0, iCurrComm = 0;
154 static int CommSize = 0;
155 static int EofSeen = false;
156 
157 /* lazy initialization of the comment buffer
158  */
159 static void
161 {
162  if (CommSize!=0) return; /* if needed */
163  pips_debug(9, "allocating comment buffers\n");
165  Comm = (char*) malloc(CommSize);
166  PrevComm = (char*) malloc(CommSize);
167  CurrComm = (char*) malloc(CommSize);
168  pips_assert("malloc ok", Comm && PrevComm && CurrComm);
169 }
170 
171 static void
173 {
174  pips_debug(9, "resizing comment buffers\n");
175  pips_assert("comment buffer is initialized", CommSize>0);
176  CommSize*=2;
177  Comm = (char*) realloc(Comm, CommSize);
178  PrevComm = (char*) realloc(PrevComm, CommSize);
179  CurrComm = (char*) realloc(CurrComm, CommSize);
180  pips_assert("realloc ok", Comm && PrevComm && CurrComm);
181 }
182 
183 
184 /*********************************************************** GETCHAR BUFFER */
185 
186 static int * getchar_buffer = NULL;
187 static int getchar_buffer_size = 0; /* number of elements in the array */
188 
189 static void
191 {
192  if (getchar_buffer_size!=0) return; /* if needed */
193  pips_debug(9, "allocating getchar buffer\n");
195  getchar_buffer = (int*) malloc(sizeof(int)*getchar_buffer_size);
196  pips_assert("malloc ok", getchar_buffer);
197 }
198 
199 static void
201 {
202  pips_debug(9, "resizing getchar buffer\n");
203  pips_assert("buffer initialized", getchar_buffer_size>0);
205  getchar_buffer = (int*) realloc(getchar_buffer,
206  sizeof(int)*getchar_buffer_size);
207  pips_assert("realloc ok", getchar_buffer);
208 }
209 
210 
211 static int i_getchar = UNDEF, l_getchar = UNDEF;
212 
213 
214 /*************************************************************** STMT BUFFER */
215 
216 /* le buffer contenant le statement courant, l'indice courant et la longueur.
217  */
218 static int * stmt_buffer = NULL;
219 static size_t stmt_buffer_size = 0;
220 
221 static void
223 {
224  if (stmt_buffer_size!=0) return; /* if needed */
225  pips_debug(9, "allocating stmt buffer\n");
227  stmt_buffer = (int*) malloc(sizeof(int)*stmt_buffer_size);
228  pips_assert("malloc ok", stmt_buffer);
229 }
230 
231 static void
233 {
234  pips_debug(9, "resizing stmt buffer\n");
235  pips_assert("buffer initialized", stmt_buffer_size>0);
236  stmt_buffer_size*=2;
237  stmt_buffer = (int*) realloc(stmt_buffer, sizeof(int)*stmt_buffer_size);
238  pips_assert("realloc ok", stmt_buffer);
239 }
240 
241 /* indexes in the buffer...
242  */
243 static size_t iStmt = 0, lStmt = 0;
244 #define SIZE_UNDEF ((size_t) UNDEF)
245 
246 /*************************************************************** LINE BUFFER */
247 
248 /* le buffer contenant la ligne que l'on doit lire en avance pour se rendre
249  * compte qu'on a finit de lire un statement, l'indice courant et la longueur.
250  */
251 static int * line_buffer = NULL;
252 static int line_buffer_size = 0;
253 
254 static void
256 {
257  if (line_buffer_size!=0) return; /* if needed */
258  pips_debug(9, "allocating line buffer\n");
260  line_buffer = (int*) malloc(sizeof(int)*line_buffer_size);
261  pips_assert("malloc ok", line_buffer);
262 }
263 
264 static void
266 {
267  pips_debug(9, "resizing line buffer\n");
268  pips_assert("buffer initialized", line_buffer_size>0);
269  line_buffer_size*=2;
270  line_buffer = (int*) realloc(line_buffer, sizeof(int)*line_buffer_size);
271  pips_assert("realloc ok", line_buffer);
272 }
273 
274 static int iLine = 0, lLine = 0;
275 
277 {
278  size_t i=0, j=0, column=6;
279  char * tmp = (char*) malloc(lStmt+200), * ndecls, * odecls;
281 
282  for (; i<lStmt; i++, j++, column++)
283  {
284  if (column==71)
285  {
286  tmp[j++] = '\n';
287  tmp[j++] = ' ';
288  tmp[j++] = ' ';
289  tmp[j++] = ' ';
290  tmp[j++] = ' ';
291  tmp[j++] = ' ';
292  tmp[j++] = 'x';
293  tmp[j++] = ' ';
294  tmp[j++] = ' ';
295  tmp[j++] = ' ';
296  tmp[j++] = ' ';
297  tmp[j++] = ' ';
298  column = 10;
299  }
300  tmp[j] = (char) stmt_buffer[i]; /* int[] */
301  }
302  stmt_buffer[i]='\0';
303  tmp[j] = '\0';
304 
305  odecls = code_decls_text(c);
306  ndecls = strdup(concatenate(odecls, "! moved up...\n DATA ",
307  tmp+4, 0));
308  free(odecls);
309  free(tmp);
310  code_decls_text(c) = ndecls;
311 }
312 
314 {
315  iLine = 0, lLine = 0;
316  iStmt = 0, lStmt = 0;
317  iCurrComm = 0;
318  iComm = 0;
319  iPrevComm = 0;
321  EofSeen = false;
322 }
323 
324 /*
325  * Une variable pour traiter les quotes. Petit automate a 3 etats:
326  * NONINQUOTES on est a l'exterieur de quotes
327  * INQUOTES on etait dans l'etat NONINQUOTES et on a vu une quote
328  * INQUOTEQUOTE on etait dans l'etat INQUOTES et on a vu un quote
329  *
330  * INQUOTEBACKSLASH
331  * ^ x
332  * | |
333  * \ v
334  * NONINQUOTES -----'----> INQUOTES -------'-----> INQUOTEQUOTE
335  * | ^ ^ | ^ ^ | |
336  * | | | | | | | |
337  * +-x-+ | +-x-+ +--------'-------+ |
338  * | |
339  * +----------------------x-------------------------+
340  *
341  * x est un caractere quelconque different de '
342  *
343  * Modifications:
344  * - la quote peut-etre simple-quote ou double-quote pour faire plaisir a
345  * Fabien Coelho.
346  * L'information est stockee lors de la rentree dans une constante chaine
347  * de caracteres (variable QuoteChar).
348  * - ajout de l'etat INQUOTEBACKSLASH pour traiter les extensions
349  * non normalisees similaires aux chaines C
350  *
351  * Notes:
352  * - il faut rester compatible avec l'analyseur lexical scanner.l
353  * - les declarations sont relues par un autre analyseur pour en garder
354  * le texte et rester fidele au source
355  */
356 static int EtatQuotes;
357 #define NONINQUOTES 1
358 #define INQUOTES 2
359 #define INQUOTEQUOTE 3
360 #define INQUOTEBACKSLASH 4
361 
362 /*
363  * Numero de ligne et de colonne du fichier d'entree courant.
364  */
366 
367 /*
368  * Line number of the statement in ReadStmt(),
369  * which is currently being parsed.
370  */
372 
373 
374 /*
375  * Y a t il un '=' ou un ',' non parenthese ?
376  */
378 
379 /* La table des operateurs du type '.XX.'.
380  */
381 static char * OperateurPoints[] = {
382  ".NOT.",
383  ".AND.",
384  ".OR.",
385  ".EQV.",
386  ".NEQV.",
387  ".LT.",
388  ".LE.",
389  ".EQ.",
390  ".NE.",
391  ".GT.",
392  ".GE.",
393  ".TRUE.",
394  ".FALSE.",
395  ".INOUT.",
396  ".IN.",
397  ".OUT.",
398  NULL
399 };
400 
401 /*
402  * La table keywtbl contient tous les keywords de la grammaire Fortran. Elle
403  * est fabriquee automatiquement a partir du fichier f77keywords et mise dans
404  * le fichier keywtbl.h. Le champ 'keywstr' est le nom du mot clef, et le
405  * champ 'keywval est sa valeur numerique pour echange entre le scanner et le
406  * parser.
407  */
408 struct Skeyword {
409  char * keywstr;
410  int keywval;
411 };
412 
413 #include "keywtbl.h"
414 
415 /* Une table pour accelerer les recherche des keywords. keywidx[X] indique le
416  * rang dans keywtbl du premier mot clef commencant par X.
417  */
418 static int keywidx[26];
419 
420 /* Variables qui serviront a mettre a jour les numeros de la premiere et de la
421  * derniere ligne de commentaire, et les numeros de la premiere et de la
422  * derniere ligne du statement.
423  */
425 static char tmp_lab_I[6];
426 
427 /* memoization des properties */
428 
429 #include "properties.h"
430 
431 static bool parser_warn_for_columns_73_80 = true;
432 
433 void
435 {
437  get_bool_property("PARSER_WARN_FOR_COLUMNS_73_80");
439 }
440 
441 
442 /*-------------------------------------------------------------------------*/
443 /*
444  * declarations de vraies variables externes
445  */
446 
447 /*
448  * les numeros de la premiere et de la derniere ligne de commentaire, les
449  * numeros de la premiere et de la derniere ligne du statement, et le label du
450  * statement.
451  */
453 extern char lab_I[];
454 
455 /*-------------------------------------------------------------------------*/
456 /*
457  * declarations de fonctions externes
458  */
459 
460 void CheckParenthesis();
461 void FindIf();
462 void FindAutre();
463 void FindPoints();
464 
465 int
466 syn_wrap(void)
467 {
468  return(1);
469 }
470 
471 /* La fonction a appeler pour l'analyse d'un nouveau fichier.
472  */
473 void
475 {
476  register int i;
477  static int FirstCall = true;
478  char letcour, *keywcour;
479 
480 
481  if (FirstCall) {
482  FirstCall = false;
483 
484  /* on initialise la table keywidx */
485  for (i = 0; i < 26; i += 1)
486  keywidx[i] = UNDEF;
487 
488  /* on met a jour la table keywidx en fonction des keywords */
489  letcour = ' ';
490  i = 0;
491  while ((keywcour = keywtbl[i].keywstr) != NULL) {
492  if (keywcour[0] != letcour) {
493  /* premier keyword commencant par keywcour[0] */
494  keywidx[(int) keywcour[0]-'A'] = i;
495  letcour = keywcour[0];
496  }
497  i += 1;
498  }
499  }
500 
501  /* on initialise les variables externes locales et non locales */
502  LineNumber = 1;
503  Column = 1;
504  StmtLineNumber = 1;
506  iStmt = lStmt = SIZE_UNDEF;
507  iLine = lLine = UNDEF;
508 }
509 
510 /* Fonction appelee par sslex sur la reduction de la regle de reconnaissance
511  * des mot clefs. Elle recherche si le mot 's' est un mot clef, retourne sa
512  * valeur si oui, et indique une erreur si non.
513  */
514 int
515 IsCapKeyword(char * s)
516 {
517  register int i, c;
518  char *kwcour, *t;
519  char buffer[32];
520 
521  debug(9, "IsCapKeyword", "%s\n", s);
522 
523  pips_assert("not too long keyword", strlen(s)<32);
524 
525  /* la chaine s est mise en majuscules */
526  t = buffer;
527  while ( (c = *s++) ) {
528  if (islower(c))
529  c = toupper(c);
530  *t++ = c;
531  }
532  *t = '\0';
533 
534  i = keywidx[(int) buffer[0]-'A'];
535 
536  if (i != UNDEF) {
537  while ((kwcour = keywtbl[i].keywstr)!=0 && kwcour[0]==buffer[0]) {
538  if (strcmp(buffer, kwcour) == 0) {
539  debug(9, "IsCapKeyword", "%s %d\n", kwcour, i);
540  return(keywtbl[i].keywval);
541  }
542 
543  i += 1;
544  }
545  }
546 
547  user_warning("IsCapKeyword", "[scanner] keyword expected near %s\n",
548  buffer);
549  ParserError("IsCapKeyword", "Missing keyword.\n");
550 
551  return(-1); /* just to avoid a gcc warning */
552  /*NOTREACHED*/
553 }
554 
555 /* Routine de lecture pour l'analyseur lexical, lex ou flex */
556 int
557 PipsGetc(FILE * fp)
558 {
559  int eof = false;
560  int c;
561 
562  if (iStmt == SIZE_UNDEF || iStmt >= lStmt) {
563  /*
564  * le statement est vide. On lit et traite le suivant.
565  */
566  if (ReadStmt(fp) == EOF) {
567  eof = true;
568  }
569  else {
570  /*
571  * verifie les parentheses et on recherche les '=' et
572  * les ',' de profondeur zero.
573  */
575 
576  /*
577  * on recherche les operateurs du genre .eq.
578  */
579  FindPoints();
580 
581  if (!FindDo()) {
582  if (!FindImplicit()) {
583  if (!FindIfArith()) {
584  FindIf();
585 
586  if (!FindAssign()) {
587  FindAutre();
588  }
589  }
590  }
591  }
592 
593  iStmt = 0;
594  }
595  }
596 
597  c = stmt_buffer[iStmt++];
598  return((eof) ? EOF : UNQUOTE(c));
599 }
600 
601 /* Routine de lecture physique
602  *
603  * In case an error occurs, buffer must be emptied.
604  * Since i_getchar and l_getchar
605  * cannot be touched by the error handling routine, changes of fp are tracked
606  * in GetChar() and dynamically tested. Kludge suggested by Fabien Coelho to
607  * avoid adding more global variables. (FI)
608  *
609  * Empty (or rather invisible) lines made of TAB and SPACE characters are
610  * replaced by the string "\n".
611  */
612 
613 int
614 GetChar(FILE * fp)
615 {
616  int c = UNDEF;
617  static int col = 0;
618  static FILE * previous_fp = NULL;
619 
621 
622  /* This section (probably) is made obsolete by the new function
623  * parser_reset_all_reader_buffers(). The user_warning() is replaced
624  * by a pips_error(). Test: Cachan/bug10
625  */
626  if( previous_fp != fp ) {
627  /* If a file has just been opened */
628  if( i_getchar < l_getchar ) {
629  /* if the buffer is not empty, which may never occur if
630  * previous_fp == NULL, perform a buffer reset
631  */
633  pips_internal_error("Unexpected buffer reset."
634  "A parser error must have occured previously.\n");
635  }
636  previous_fp = fp;
637  }
638 
639  /* A whole input line is read to process TABs and empty lines */
640  while (i_getchar >= l_getchar && c != EOF) {
641  int EmptyBuffer = true;
642  int LineTooLong = false;
643  bool first_column = true;
644  bool in_comment = false;
645 
646  i_getchar = l_getchar = 0;
647 
648  while ((c = getc(fp)) != '\n' && c != EOF) {
649 
650  if (l_getchar>getchar_buffer_size-20) /* large for expansion */
652 
653  if(first_column) {
654  in_comment = (strchr(START_COMMENT_LINE, (char) c)!= NULL);
655  first_column = false;
656  }
657 
658  /* Fortran has a limited character set. See standard section 3.1.
659  This cannot be handled here as you do not know if you are
660  in a string constant or not. You cannot convert the double
661  quote into a simple quote because you may generate an illegal
662  string constant. Maybe the best would be to uncomment the
663  next test. FI, 21 February 1992
664  if( c == '\"')
665  FatalError("GetChar","Illegal double quote character");
666  " */
667  /* FI: let's delay and do it in ReadLine:
668  * if (islower(c)) c = toupper(c);
669  */
670 
671  if (c == '\t') {
672  int i;
673  int nspace = 8-col%8;
674  /* for (i = 0; i < (8-Column%8); i++) { */
675  for (i = 0; i < nspace; i++) {
676  col += 1;
677  getchar_buffer[l_getchar++] = ' ';
678  }
679  } else if (c == '\r') {
680  /* Ignore carriage returns introduced by VMS, MSDOS or MACOS...*/
681  ;
682  }
683  else {
684  col += 1;
685  if(col > 72 && !LineTooLong && !in_comment &&
686  parser_warn_for_columns_73_80 && !(c==' ' || c=='\t')) {
687  user_warning("GetChar",
688  "Line %d truncated, col=%d and l_getchar=%d\n",
690  LineTooLong = true;
691  }
692  /* buffer[l_getchar++] = (col > 72) ? ' ' : c; */
693  /* buffer[l_getchar++] = (col > 72) ? '\n' : c; */
694  if(col <= 72 || in_comment) {
695  /* last columns cannot be copied because we might be
696  * inside a character string
697  */
698  getchar_buffer[l_getchar++] = c;
699  }
700  if (c != ' ')
701  EmptyBuffer = false;
702  }
703  }
704 
705  if (c == EOF) {
706  if (!EmptyBuffer) {
707  user_warning("GetChar",
708  "incomplete last line !!!\n");
709  c = '\n';
710  }
711  }
712  else {
713  if (EmptyBuffer) {
714  /* i_getchar = l_getchar = UNDEF; */
715  debug(8, "GetChar", "An empty line has been detected\n");
716  i_getchar = l_getchar = 0;
717  getchar_buffer[l_getchar++] = '\n';
718  col = 0;
719  /* LineNumber += 1; */
720  }
721  else {
722  col = 0;
723  getchar_buffer[l_getchar++] = '\n';
724  }
725  }
726  ifdebug(8) {
727  int i;
728 
729  if(l_getchar==UNDEF) {
730  debug(8, "GetChar",
731  "Input line after tab expansion is empty:\n");
732  }
733  else {
734  debug(8, "GetChar",
735  "Input line after tab expansion l_getchar=%d, col=%d:\n",
736  l_getchar, col);
737  }
738  for (i=0; i < l_getchar; i++) {
739  (void) putc((char) getchar_buffer[i], stderr);
740  }
741  if(l_getchar<=0) {
742  (void) putc('\n', stderr);
743  }
744  }
745  }
746 
747  if (c != EOF) {
748  if ((c = getchar_buffer[i_getchar++]) == '\n') {
749  Column = 1;
750  LineNumber += 1;
751  }
752  else {
753  Column += 1;
754  }
755  }
756 
757  return(c);
758 }
759 
760 /* All physical lines of a statement are put together in a unique buffer
761  * called "line_buffer". Each character in each physical line is retrieved with
762  * GetChar().
763  */
764 int
765 ReadLine(FILE * fp)
766 {
767  static char QuoteChar = '\000';
768  int TypeOfLine;
769  int i, c;
770  char label[6];
771  int ilabel = 0;
772 
773  /* on entre dans ReadLine avec Column = 1 */
774  pips_assert("ReadLine", Column == 1);
775 
777 
778  /* Read all comment lines you can */
779  while (strchr(START_COMMENT_LINE,(c = GetChar(fp))) != NULL) {
780  if (tmp_b_C == UNDEF)
781  tmp_b_C = (c=='\n')?LineNumber-1:LineNumber;
782 
783  ifdebug(8) {
784  if(c=='\n')
785  debug(8, "ReadLine",
786  "Empty comment line detected at line %d "
787  "for comment starting at line %d\n",
788  LineNumber-1, tmp_b_C);
789  }
790 
791  while(c!=EOF) {
792  if (iCurrComm >= CommSize-2)
794  CurrComm[iCurrComm++] = c;
795  if(c=='\n') break;
796  c = GetChar(fp);
797  }
798  }
799 
800  CurrComm[iCurrComm] = '\0';
801 
802  pips_debug(7, "comment CurrComm: (%d) --%s--\n", iCurrComm, CurrComm);
803 
804  if (c != EOF) {
805  /* Read label */
806  for (i = 0; i < 5; i++) {
807  if (c != ' ') {
808  if (isdigit(c)) {
809  label[ilabel++] = c;
810  }
811  else {
812  pips_user_warning("Unexpected character '%c' (0x%x)\n",
813  c, (int) c);
814  ParserError("ReadLine",
815  "non numeric character in label!\n");
816  }
817  }
818  c = GetChar(fp);
819  }
820 
821  if (ilabel > 0) {
822  label[ilabel] = '\0';
823  strcpy(tmp_lab_I, label);
824  }
825  else
826  strcpy(tmp_lab_I, "");
827 
828  /* Check continuation character */
829  TypeOfLine = (c != ' ' && c!= '0') ? CONTINUATION_LINE : FIRST_LINE;
830 
831  /* Keep track of the first and last comment lines and of the first and
832  * last statement lines. These two intervals may intersect.
833  *
834  * Append current comment CurrComm to Comm if it is a continuation. Save Comm
835  * in PrevComm and CurrComm in Comm if it is a first statement line.
836  */
837  if (TypeOfLine == FIRST_LINE) {
838  if(iComm!=0) {
839  Comm[iComm] = '\0';
840  (void) strcpy(PrevComm, Comm);
841  Comm[0] = '\0';
842  }
843  else {
844  PrevComm[0] = '\0';
845  }
846  iPrevComm = iComm;
847 
848  (void) strcpy(Comm, CurrComm);
849  iComm = iCurrComm;
850  iCurrComm = 0;
851  CurrComm[0] = '\0';
852 
853  if (tmp_b_C != UNDEF)
854  tmp_e_C = LineNumber - 1;
856  }
857  else if (TypeOfLine == CONTINUATION_LINE){
858  if (iCurrComm+iComm >= CommSize-2)
860  (void) strcat(Comm, CurrComm);
861  iComm += iCurrComm;
862  iCurrComm = 0;
863  CurrComm[0] = '\0';
864 
865  /* FI: this is all wrong */
866  /* Why destroy comments because there are continuation lines? */
867  /* tmp_b_C = tmp_e_C = UNDEF; */
868  }
869 
870  pips_debug(7, "comment Comm: (%d) --%s--\n", iComm, Comm);
871  pips_debug(7, "comment PrevComm: (%d) --%s--\n", iPrevComm, PrevComm);
872 
873  /* Read the rest of the line, skipping SPACEs but handling string constants */
874 
875  while ((c = GetChar(fp)) != '\n') {
876  if (c == '\'' || c == '"') {
877  if (EtatQuotes == INQUOTES) {
878  if(c == QuoteChar)
880  else {
881  if (EtatQuotes == INQUOTEQUOTE)
883  }
884  }
885  else if(EtatQuotes == INQUOTEBACKSLASH)
887  else {
889  QuoteChar = c;
890  }
891  }
892  else {
893  if (EtatQuotes == INQUOTEQUOTE)
895  else if(EtatQuotes == INQUOTES && c == '\\')
897  else if(EtatQuotes == INQUOTEBACKSLASH)
899  }
900 
901  if (lLine>line_buffer_size-5)
903 
904  if (EtatQuotes == NONINQUOTES) {
905  if (c != ' ') {
906  line_buffer[lLine++] = islower(c)? toupper(c) : c;
907  }
908  }
909  else {
910  line_buffer[lLine++] = QUOTE(c);
911  }
912 
913  }
914 
915  if (EtatQuotes == INQUOTEQUOTE)
917  }
918  else {
919  TypeOfLine = EOF_LINE;
920  if (tmp_b_C != UNDEF)
921  tmp_e_C = LineNumber - 1;
923 
924  if(iComm!=0) {
925  Comm[iComm] = '\0';
926  (void) strcpy(PrevComm, Comm);
927  Comm[0] = '\0';
928  }
929  else {
930  PrevComm[0] = '\0';
931  }
932  iPrevComm = iComm;
933  }
934 
935  pips_debug(9, "Aggregation of continuation lines: '%s'\n", (char*)line_buffer);
936 
937  return(TypeOfLine);
938 }
939 
940 /* regroupement des lignes du statement en une unique ligne sans continuation */
941 int
942 ReadStmt(FILE * fp)
943 {
944  int TypeOfLine;
945  int result;
946 
948 
949  if (EofSeen == true) {
950  /*
951  * on a rencontre EOF, et on a deja purge le dernier
952  * statement. On arrete.
953  */
954  EofSeen = false;
955  result = EOF;
956  }
957  else {
958  /*
959  * on a deja lu la 1ere ligne sauf au moment de l'initialisation
960  */
961  if (lLine == UNDEF) {
962  lLine = 0;
963 
964  tmp_b_I = tmp_e_I = UNDEF;
965  tmp_b_C = tmp_e_C = UNDEF;
966 
967  if ((TypeOfLine = ReadLine(fp)) == CONTINUATION_LINE) {
968  ParserError("ReadStmt",
969  "[scanner] incorrect continuation line as first line\n");
970  }
971  else if (TypeOfLine == FIRST_LINE) {
972  /* It would be nice to move the current comments from
973  * Comm to PrevComm, but it is just too late because of
974  * the repeat until control structure down: ReadLine()
975  * has already been called and read the first line of
976  * the next statement. Hence, CurrComm is needed.
977  */
978  }
979  else if (TypeOfLine == EOF_LINE) {
980  result = EOF;
981  }
982  }
983 
984  line_b_I = tmp_b_I;
985  line_b_C = tmp_b_C;
986  strcpy(lab_I, tmp_lab_I);
987 
988  lStmt = 0;
989  /* Memorize the line number before to find next Statement*/
991  do {
992  iLine = 0;
993  while (iLine < lLine) {
994  if (lStmt>stmt_buffer_size-20)
997  }
998  lLine = 0;
999 
1000  /* Update the current final lines for instruction and comments */
1001  line_e_I = tmp_e_I;
1002  line_e_C = tmp_e_C;
1003 
1004  /* Initialize temporary beginning and end line numbers */
1005  tmp_b_I = tmp_e_I = UNDEF;
1006  tmp_b_C = tmp_e_C = UNDEF;
1007 
1008  } while ((TypeOfLine = ReadLine(fp)) == CONTINUATION_LINE) ;
1009 
1010  stmt_buffer[lStmt++] = '\n';
1011  iStmt = 0;
1012 
1013  line_e_I = (tmp_b_C == UNDEF) ? tmp_b_I-1 : tmp_b_C-1;
1014 
1015  if (TypeOfLine == EOF_LINE)
1016  EofSeen = true;
1017 
1018  result = 1;
1019 
1020  ifdebug(7) {
1021  size_t i;
1022  pips_debug(7, "stmt: (%td)\n", lStmt);
1023  for(i=0; i<lStmt; i++)
1024  putc((int) stmt_buffer[i], stderr);
1025  }
1026  }
1027 
1028  return(result);
1029 }
1030 
1031 void
1033 {
1034  register size_t i;
1035  int parenthese = 0;
1036 
1037  ProfZeroVirg = ProfZeroEgal = false;
1038 
1039  for (i = 0; i < lStmt; i++) {
1040  if (!IS_QUOTED(stmt_buffer[i])) {
1041  if (parenthese == 0) {
1042  if (stmt_buffer[i] == ',')
1043  ProfZeroVirg = true;
1044  else if (stmt_buffer[i] == '=')
1045  ProfZeroEgal = true;
1046  }
1047  if(stmt_buffer[i] == '(') parenthese ++;
1048  if(stmt_buffer[i] == ')') parenthese --;
1049  }
1050  }
1051  if(parenthese < 0) {
1052  for (i=0; i < lStmt; i++)
1053  (void) putc((char) stmt_buffer[i], stderr);
1054  /* Warning("CheckParenthesis", */
1055  ParserError("CheckParenthesis",
1056  "unbalanced paranthesis (too many ')')\n"
1057  "Due to line truncation at column 72?\n");
1058  }
1059  if(parenthese > 0) {
1060  for (i=0; i < lStmt; i++)
1061  (void) putc((char) stmt_buffer[i], stderr);
1062  ParserError("CheckParenthesis",
1063  "unbalanced paranthesis (too many '(')\n"
1064  "Due to line truncation at column 72?\n");
1065  }
1066 }
1067 
1068 /* This function is redundant with FindDo() but much easier to
1069  * understand. I leave it as documentation. FI.
1070  */
1071 
1072 int
1074 {
1075  int result = false;
1076 
1077  if (!ProfZeroEgal && StmtEqualString("DOWHILE", iStmt)) {
1078  (void) CapitalizeStmt("DO", iStmt);
1079  (void) CapitalizeStmt("WHILE", iStmt+2);
1080  result = true;
1081  }
1082 
1083  return(result);
1084 }
1085 
1086 int
1087 FindDo(void)
1088 {
1089  int result = false;
1090 
1091  if(StmtEqualString("DO", iStmt)) {
1092  if (ProfZeroVirg && ProfZeroEgal) {
1093  (void) CapitalizeStmt("DO", iStmt);
1094  result = true;
1095  }
1096  else if (!ProfZeroVirg && !ProfZeroEgal) {
1097  /* Let's skip a loop label to look for a while construct */
1098  int i = iStmt+2;
1099  while (isdigit(stmt_buffer[i]))
1100  i++;
1101 
1102  if (StmtEqualString("WHILE", i)) {
1103  (void) CapitalizeStmt("DO", iStmt);
1104  (void) CapitalizeStmt("WHILE", i);
1105  result = true;
1106  }
1107  }
1108  }
1109 
1110  return(result);
1111 }
1112 
1113 int
1115 {
1116  int result = false;
1117 
1118  if (!ProfZeroEgal && StmtEqualString("IMPLICIT", iStmt)) {
1119  iStmt = CapitalizeStmt("IMPLICIT", iStmt);
1120  while (iStmt < lStmt) {
1121  iStmt = NeedKeyword();
1122  if ((iStmt = FindProfZero((int) ',')) == SIZE_UNDEF)
1123  iStmt = lStmt;
1124  else
1125  iStmt += 1;
1126  }
1127  result = true;
1128  }
1129 
1130  return(result);
1131 }
1132 
1133 int
1135 {
1136  int result = false;
1137 
1138  if (StmtEqualString("IF(", iStmt)) {
1139  int i = FindMatchingPar(iStmt+2)+1;
1140  if ('0' <= stmt_buffer[i] && stmt_buffer[i] <= '9') {
1141  (void) CapitalizeStmt("IF", iStmt);
1142  result = true;
1143  }
1144  }
1145 
1146  return(result);
1147 }
1148 
1149 void
1150 FindIf(void)
1151 {
1152  if (StmtEqualString("IF(", iStmt)) {
1153  int i = FindMatchingPar(iStmt+2)+1;
1154  if (stmt_buffer[i] != '=') {
1155  (void) CapitalizeStmt("IF", iStmt);
1156  iStmt = i;
1157  }
1158  }
1159  else if (StmtEqualString("ELSEIF(", iStmt)) {
1160  int i = FindMatchingPar(iStmt+6)+1;
1161  if (stmt_buffer[i] != '=') {
1162  (void) CapitalizeStmt("ELSEIF", iStmt);
1163  iStmt = i;
1164  }
1165  }
1166 }
1167 
1168 void
1170 {
1171  if (!ProfZeroEgal) {
1172  int i = NeedKeyword();
1173 
1174  /*
1175  * on detecte le cas tordu: INTEGER FUNCTION(...) ou encore
1176  * plus tordu: CHARACTER*89 FUNCTION(...)
1177  */
1178  if (StmtEqualString("Integer", iStmt) ||
1179  StmtEqualString("Real", iStmt) ||
1180  StmtEqualString("Character", iStmt) ||
1181  StmtEqualString("Complex", iStmt) ||
1182  StmtEqualString("Doubleprecision", iStmt) ||
1183  StmtEqualString("Logical", iStmt)) {
1184  if (stmt_buffer[i] == '*' && isdigit(stmt_buffer[i+1])) {
1185  i += 2;
1186  while (isdigit(stmt_buffer[i]))
1187  i++;
1188  }
1189  if (StmtEqualString("FUNCTION", i)) {
1190  (void) CapitalizeStmt("FUNCTION", i);
1191  }
1192  }
1193  }
1194 }
1195 
1196 int
1198 {
1199  int result = false;
1200 
1201  if (!ProfZeroEgal && StmtEqualString("ASSIGN", iStmt)) {
1202  register size_t i = iStmt+6;
1203 
1204  if (isdigit(stmt_buffer[i])) {
1205  while (i < lStmt && isdigit(stmt_buffer[i]))
1206  i++;
1207 
1208  if (StmtEqualString("TO", i)) {
1209  (void) CapitalizeStmt("ASSIGN", iStmt);
1210  (void) CapitalizeStmt("TO", i);
1211  result = true;
1212  }
1213  }
1214  }
1215 
1216  return(result);
1217 }
1218 
1219 void
1221 {
1222  register size_t i = iStmt;
1223 
1224  while (i < lStmt) {
1225  if (stmt_buffer[i] == '.' && isalpha(stmt_buffer[i+1])) {
1226  register int j = 0;
1227 
1228  while (OperateurPoints[j] != NULL) {
1229  if (StmtEqualString(OperateurPoints[j], i)) {
1230  stmt_buffer[i] = '%';
1231  i += strlen(OperateurPoints[j]);
1232  stmt_buffer[i-1] = '%';
1233  break;
1234  }
1235  j += 1;
1236  }
1237 
1238  if (OperateurPoints[j] == NULL)
1239  i += 2;
1240  }
1241  else {
1242  i += 1;
1243  }
1244  }
1245 }
1246 
1247 size_t
1249 {
1250  register size_t i;
1251  int parenthese = 0;
1252 
1253  for (i = iStmt; i < lStmt; i++) {
1254  if (!IS_QUOTED(stmt_buffer[i])) {
1255  if (parenthese == 0 && stmt_buffer[i] == c)
1256  break;
1257 
1258  if(stmt_buffer[i] == '(') parenthese ++;
1259  if(stmt_buffer[i] == ')') parenthese --;
1260  }
1261  }
1262 
1263  return (i == lStmt) ? SIZE_UNDEF : i;
1264 }
1265 
1266 size_t
1268 {
1269  int parenthese;
1270 
1271  pips_assert("FindMatchingPar",
1272  stmt_buffer[i] == '(' && !IS_QUOTED(stmt_buffer[i]));
1273 
1274  i += 1;
1275  parenthese = 1;
1276 
1277  while (i < lStmt && parenthese > 0) {
1278  if (!IS_QUOTED(stmt_buffer[i])) {
1279  if(stmt_buffer[i] == '(') parenthese ++;
1280  if(stmt_buffer[i] == ')') parenthese --;
1281  }
1282  i += 1;
1283  }
1284 
1285  return (i == lStmt) ? SIZE_UNDEF : i-1;
1286 }
1287 
1288 // ??? should be a bool?
1289 int
1290 StmtEqualString(char *s, int i)
1291 {
1292  int result = false;
1293 
1294  if (strlen(s) <= lStmt-i) {
1295  while (*s)
1296  if (*s != stmt_buffer[i++])
1297  break;
1298  else
1299  s++;
1300 
1301  result = (*s) ? false : i;
1302  }
1303 
1304  return result;
1305 }
1306 
1307 int
1308 CapitalizeStmt(char s[], int i)
1309 {
1310  int l = i+strlen(s);
1311 
1312  if ((size_t) l <= lStmt) {
1313  /* la 1ere lettre n'est pas modifiee */
1314  i += 1;
1315  while (i < l) {
1316  stmt_buffer[i] = tolower(stmt_buffer[i]);
1317  i += 1;
1318  }
1319  }
1320  else {
1321  ParserError("CapitalizeStmt",
1322  "[scanner] internal error in CapitalizeStmt\n");
1323  }
1324 
1325  return(i);
1326 }
1327 
1328 int
1330 {
1331  register int i, j;
1332  char * kwcour;
1333 
1334  i = keywidx[(int) stmt_buffer[iStmt]-'A'];
1335 
1336  if (i != UNDEF) {
1337  while ((kwcour = keywtbl[i].keywstr)!=0 &&
1338  kwcour[0]==stmt_buffer[iStmt]) {
1339  if (StmtEqualString(kwcour, iStmt) != false) {
1340  j = CapitalizeStmt(kwcour, iStmt);
1341  return(j);
1342  }
1343  i += 1;
1344  }
1345  }
1346 
1347  ParserError("NeedKeyword", "[scanner] keyword expected\n");
1348 
1349  return(-1); /* just to avoid a gcc warning */
1350 
1351  /*NOTREACHED*/
1352 }
1353 
1355 {
1356  int i;
1357  FILE * syn_in = NULL;
1358 
1359  /* Preprocessed statement: Spaces have been eliminated as well as
1360  continuation lines, keyword have been emphasized and variables
1361  capitalized. */
1362  /*
1363  for(i=0; i<lStmt; i++)
1364  fprintf(stderr, "%c", (char) stmt_buffer[i]);
1365  fprintf(stderr,"\n");
1366  */
1367 
1368  syn_in = safe_fopen(CurrentFN, "r");
1369 
1370  /* Skip the initial lines */
1371 
1372  /* line_b_I, line_e_I */
1373  i = 1;
1374  while(i<line_b_I) {
1375  int c;
1376  if((c = getc(syn_in))==(int) '\n') i++;
1377  pips_assert("The end of file cannot be reached", c!=EOF);
1378  }
1379 
1380  /* Copy the data lines */
1381  while(i<=line_e_I) {
1382  int c;
1383  if((c = getc(syn_in))==(int) '\n') i++;
1384  pips_assert("The end of file cannot be reached", c!=EOF);
1385  putc(c, stderr);
1386  }
1387 
1389 }
1390 
1391 /*return the line number of the statement being parsed*/
1393  return StmtLineNumber - 1;
1394 }
1395 
void const char const char const int
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
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void * malloc(YYSIZE_T)
void free(void *)
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
static struct Skeyword keywtbl[]
CE FICHIER A ETE GENERE AUTOMATIQUEMENT.
Definition: keywtbl.h:33
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#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 user_warning(fn,...)
Definition: misc-local.h:262
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define false
Definition: newgen_types.h:80
int FindIfArith(void)
Definition: reader.c:1134
#define FIRST_LINE
Definition: reader.c:134
char * Comm
reader.c
Definition: reader.c:152
int PipsGetc(FILE *fp)
Routine de lecture pour l'analyseur lexical, lex ou flex.
Definition: reader.c:557
static int * getchar_buffer
Definition: reader.c:186
char * CurrComm
Definition: reader.c:152
static int tmp_e_I
Definition: reader.c:424
int line_e_C
Definition: reader.c:452
void FindPoints()
Definition: reader.c:1220
int IsCapKeyword(char *s)
Fonction appelee par sslex sur la reduction de la regle de reconnaissance des mot clefs.
Definition: reader.c:515
static void init_line_buffer(void)
Definition: reader.c:255
static size_t iStmt
indexes in the buffer...
Definition: reader.c:243
static int tmp_e_C
Definition: reader.c:424
int ReadLine(FILE *fp)
All physical lines of a statement are put together in a unique buffer called "line_buffer".
Definition: reader.c:765
#define CONTINUATION_LINE
Definition: reader.c:135
static bool parser_warn_for_columns_73_80
memoization des properties
Definition: reader.c:431
#define INITIAL_BUFFER_SIZE
Comm contains the comments for the current statement in ReadStmt().
Definition: reader.c:151
static void init_comment_buffers(void)
lazy initialization of the comment buffer
Definition: reader.c:160
char * PrevComm
Definition: reader.c:152
LOCAL int ProfZeroEgal
Definition: reader.c:377
void dump_current_statement()
Definition: reader.c:1354
#define LOCAL
Definition: reader.c:130
#define INQUOTEBACKSLASH
Definition: reader.c:360
void CheckParenthesis()
Definition: reader.c:1032
static int line_buffer_size
Definition: reader.c:252
int line_e_I
Definition: reader.c:452
int line_b_C
Definition: reader.c:452
static char * OperateurPoints[]
La table des operateurs du type '.XX.
Definition: reader.c:381
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
int NeedKeyword(void)
Definition: reader.c:1329
static int iLine
Definition: reader.c:274
#define EOF_LINE
Definition: reader.c:136
static void resize_comment_buffers(void)
Definition: reader.c:172
static char tmp_lab_I[6]
Definition: reader.c:425
int iCurrComm
Definition: reader.c:153
static int keywidx[26]
Une table pour accelerer les recherche des keywords.
Definition: reader.c:418
LOCAL int ProfZeroVirg
Definition: reader.c:377
size_t FindMatchingPar(size_t i)
Definition: reader.c:1267
static int l_getchar
Definition: reader.c:211
void FindAutre()
Definition: reader.c:1169
char lab_I[]
Definition: parser.c:69
static int tmp_b_I
Variables qui serviront a mettre a jour les numeros de la premiere et de la derniere ligne de comment...
Definition: reader.c:424
static int lLine
Definition: reader.c:274
static int * stmt_buffer
le buffer contenant le statement courant, l'indice courant et la longueur.
Definition: reader.c:218
void parser_reset_all_reader_buffers(void)
Definition: reader.c:313
static size_t lStmt
Definition: reader.c:243
#define NONINQUOTES
Definition: reader.c:357
LOCAL int LineNumber
Definition: reader.c:365
static int CommSize
Definition: reader.c:154
LOCAL int Column
Definition: reader.c:365
int FindAssign(void)
Definition: reader.c:1197
int FindImplicit(void)
Definition: reader.c:1114
#define QUOTE(c)
Definition: reader.c:123
#define INQUOTES
Definition: reader.c:358
#define SIZE_UNDEF
Definition: reader.c:244
static size_t stmt_buffer_size
Definition: reader.c:219
int get_statement_number()
eturn the line number of the statement being parsed
Definition: reader.c:1392
void ScanNewFile(void)
La fonction a appeler pour l'analyse d'un nouveau fichier.
Definition: reader.c:474
static int EofSeen
Definition: reader.c:155
static int tmp_b_C
Definition: reader.c:424
int CapitalizeStmt(char s[], int i)
Definition: reader.c:1308
static int i_getchar
Definition: reader.c:211
static void init_getchar_buffer(void)
number of elements in the array
Definition: reader.c:190
int FindDo(void)
Definition: reader.c:1087
int syn_wrap(void)
Definition: reader.c:466
int StmtEqualString(char *s, int i)
Definition: reader.c:1290
#define UNQUOTE(c)
Definition: reader.c:124
void append_data_current_stmt_buffer_to_declarations(void)
Definition: reader.c:276
static void init_stmt_buffer(void)
Definition: reader.c:222
int ReadStmt(FILE *fp)
regroupement des lignes du statement en une unique ligne sans continuation
Definition: reader.c:942
#define UNDEF
Definition: reader.c:132
int iPrevComm
Definition: reader.c:153
void init_parser_reader_properties()
Definition: reader.c:434
int FindDoWhile(void)
This function is redundant with FindDo() but much easier to understand.
Definition: reader.c:1073
static void resize_getchar_buffer(void)
Definition: reader.c:200
int GetChar(FILE *fp)
Routine de lecture physique.
Definition: reader.c:614
int iComm
Definition: reader.c:153
static int * line_buffer
le buffer contenant la ligne que l'on doit lire en avance pour se rendre compte qu'on a finit de lire...
Definition: reader.c:251
void FindIf()
Definition: reader.c:1150
static void resize_line_buffer(void)
Definition: reader.c:265
static void resize_stmt_buffer(void)
Definition: reader.c:232
static int EtatQuotes
Definition: reader.c:356
#define IS_QUOTED(c)
Definition: reader.c:122
static int getchar_buffer_size
Definition: reader.c:187
LOCAL int StmtLineNumber
Definition: reader.c:371
#define INQUOTEQUOTE
Definition: reader.c:359
size_t FindProfZero(int c)
Definition: reader.c:1248
code EntityCode(entity e)
this function checks that e has an initial value code.
Definition: entity.c:301
#define code_decls_text(x)
Definition: ri.h:786
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
static string buffer
Definition: string.c:113
int keywval
Definition: reader.c:410
char * keywstr
Definition: reader.c:409
FILE * syn_in
lex yacc interface
Definition: syntax.h:325
#define START_COMMENT_LINE
Legal characters to start a comment line.
Definition: syntax-local.h:30
char * CurrentFN
Pre-parser for Fortran syntax idiosyncrasy.
Definition: parser.c:49
bool ParserError(const char *f, const char *m)
Definition: parser.c:116