1 /* $Id: lexer.l 23366 2017-02-03 16:21:23Z coelho $ */
3 /******************** LEXICAL ANALYZER **************************
5 Here are the lexical rules, based on the work of people from
6 Open Source Quality projects (http://osq.cs.berkeley.edu/), used
7 by the CCured source-to-source translator for C
10 *****************************************************************/
14 * Copyright (c) 2001-2003,
15 * George C. Necula <necula@cs.berkeley.edu>
16 * Scott McPeak <smcpeak@cs.berkeley.edu>
17 * Wes Weimer <weimer@cs.berkeley.edu>
18 * Ben Liblit <liblit@cs.berkeley.edu>
19 * All rights reserved.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are
25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
32 * 3. The names of the contributors may not be used to endorse or promote
33 * products derived from this software without specific prior written
36 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
37 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
38 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
40 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
41 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
42 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
43 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
44 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 (* FrontC -- lexical analyzer
51 ** 1.0 3.22.99 Hugues Cassé First version.
52 ** 2.0 George Necula 12/12/00: Many extensions
59 #include "pips_config.h"
73 #include "preprocessor.h"
76 int csplit_line_number = 1; /**< To be exported to the parser for
77 splitting the preprocessed file */
78 int user_line_number = 1; /**< To be exported to the parser for error
79 messages related to the user file */
81 /* To track current file position: */
82 #define YY_USER_ACTION update_csplit_file_offset_information();
83 size_t current_csplit_file_offset = 0;
84 size_t csplit_file_offset_beginning = 0;
86 /* To track nesting in brackets */
87 static int bracket_depth = 0;
89 /* A state-machine to gather the trailing comments of a statement with an
90 heuristic to decide if some comments and spaces will go into the
91 previous or next top-level construct: */
92 enum gather_comment_state_t {
93 PUT_IN_NEXT_TOP_LEVEL_CONSTRUCT, /**< Normal mode: comments and spaces
94 are associated to the top-level
95 construct to encounter: */
96 GATHER_SPACES, /**< We gather only spaces in the previous top-level
98 GATHER_COMMENT, /**< We gather comments in the previous top-level construct */
100 /* Indeed it does not work since csplit_copy() is called from splitc.y
101 when a function definition is found and thus we cannot gather the
102 comment in it... :-( */
103 enum gather_comment_state_t
104 gather_comment_state_machine = PUT_IN_NEXT_TOP_LEVEL_CONSTRUCT;
107 static void gdb_marker()
109 /* Just to be able to set an easy breakpoint */
114 /* Reinitialise global position numbers for a new file. */
115 void reset_csplit_line_number()
117 csplit_line_number = 1;
118 user_line_number = 1;
119 current_csplit_file_offset = 0;
120 csplit_file_offset_beginning = 0;
121 gather_comment_state_machine = PUT_IN_NEXT_TOP_LEVEL_CONSTRUCT;
125 static int csplit_current_beginning = 1000000;
126 static int user_current_beginning = 1000000;
129 /* If we encounter a possible function begin, just snapshot the position
130 of the function beginning: */
131 static void update_csplit_current_beginning() {
132 user_current_beginning = csplit_current_beginning > csplit_line_number?
133 user_line_number : user_current_beginning;
134 csplit_current_beginning = csplit_current_beginning > csplit_line_number?
135 csplit_line_number : csplit_current_beginning;
136 /* From now, the comments and spaces are associated to the current
137 top-level construct: */
138 gather_comment_state_machine = PUT_IN_NEXT_TOP_LEVEL_CONSTRUCT;
142 /* This function is called at the end of any top-level C construct: */
143 void reset_csplit_current_beginning()
147 csplit_current_beginning = 1000000;
148 user_current_beginning = 1000000;
149 csplit_is_static_p = false;
151 /* Snapshot the current file position as a potential function begin: */
152 csplit_file_offset_beginning = current_csplit_file_offset;
154 /* Aggregate following spaces and comments on the sameline to the
155 previous top-level construct: */
156 gather_comment_state_machine = GATHER_COMMENT;
159 if(!string_undefined_p(csplit_current_function_name))
160 free(csplit_current_function_name);
161 csplit_current_function_name = string_undefined;
163 if(!string_undefined_p(csplit_current_function_name2))
164 free(csplit_current_function_name2);
165 csplit_current_function_name2 = string_undefined;
167 if(!string_undefined_p(csplit_definite_function_name))
168 free(csplit_definite_function_name);
169 csplit_definite_function_name = string_undefined;
171 if(!string_undefined_p(csplit_definite_function_signature))
172 free(csplit_definite_function_signature);
173 csplit_definite_function_signature = string_undefined;
175 if((leaked=check_signature_balance())!=0) {
176 /* FI: I'm not ready to abort() here... */
177 pips_debug(5, "Likely memory leaks: %d\n", leaked);
181 int get_csplit_current_beginning()
183 return csplit_current_beginning;
187 /* Get the current line number in the file to split from the user point of
188 view (before preprocessor expansion): */
189 int get_user_current_beginning() {
190 return user_current_beginning;
194 /* Get the file position in the file to split where the current function
196 size_t get_csplit_file_offset_beginning() {
197 return csplit_file_offset_beginning;
201 /* Get the current file position in the file to split: */
202 size_t get_current_csplit_file_offset() {
203 return current_csplit_file_offset;
207 /* Function called each time a token is read to trac file position
209 void update_csplit_file_offset_information() {
210 current_csplit_file_offset += yyleng;
214 static int lf_count(string s)
220 if(*cs=='\n') count++;
226 /* The lexer cannot handle the ambiguity between named types and
227 *variables without extra-help.
230 #define TOKEN_UNDEFINED (-1)
231 static int previous_keyword_token = TOKEN_UNDEFINED;
233 /* This is going to be the previous token because LEXER_RETURN is not
234 used in case the lexer handles either a named type or a variable. */
235 #define LEXER_RETURN(t) return(previous_keyword_token=t)
237 /* See if id is a keyword, a typedef or an identifier.
238 * Returns the token number for keywords and typedefs.
239 * Returns 0 for variable identifiers.
241 static int is_c_preprocessor_keyword_typedef(char * id)
243 /* No need to bother for scopes when dealing with C keywords,
244 * but do not take into account top-level typedefs which may be masked.
246 int t = is_c_keyword_typedef(id);
247 if(t==0 || t==TK_NAMED_TYPE) {
248 // id may be a keyword, but scopes must be used
249 string sn = get_preprocessor_current_scope();
250 string scoped_id = strdup(concatenate(id, "%", sn, NULL));
251 t = is_c_keyword_typedef(scoped_id);
254 int i, n = preprocessor_scope_number();
255 for(i=2; i<=n && t==0; i++) {
256 sn = get_preprocessor_nth_scope(i);
257 scoped_id = strdup(concatenate(id, "%", sn, NULL));
258 t = is_c_keyword_typedef(scoped_id);
261 fprintf(stderr, "Token \"%s\" identified as TK_NAMED_TYPE.\n",
266 /* Check again for a global typedef */
267 t = is_c_keyword_typedef(id);
270 /* FI: we *bet* here that "extern foo(t1, t2, t3);"
271 * with t1, t2 and t3 named type is not possible:-(
273 #define TK_TYPE_P(tk) \
274 ((tk)==TK_CHAR || (tk)==TK_INT || \
275 (tk)==TK_DOUBLE || (tk)==TK_FLOAT || (tk)==TK_COMPLEX || \
276 (tk)==TK_ENUM || (tk)==TK_STRUCT || (tk)==TK_UNION || \
277 (tk)==TK_SIGNED|| (tk)==TK_UNSIGNED|| (tk)==TK_LONG|| (tk)==TK_SHORT ||\
280 && (TK_TYPE_P(previous_keyword_token)
281 ||previous_keyword_token==TK_NAMED_TYPE)) {
284 pips_debug(1, "Token \"%s\" is in fact assumed to be an identifier.\n",
287 previous_keyword_token = t;
288 if(t==TK_STATIC && bracket_depth>0)
289 t = TK_STATIC_DIMENSION;
295 /* To track file line number automatically: */
304 intsuffix (({lsuffix})|({usuffix})|({usuffix}{lsuffix})|({lsuffix}{usuffix}))
306 intnum ({decdigit}+{intsuffix}?)
307 octnum (0{octdigit}+{intsuffix}?)
308 hexnum ({hexprefix}{hexdigit}+{intsuffix}?)
309 exponent ([eE][\+\-]?{decdigit}+)
310 fraction (\.{decdigit}+)
311 decfloat (({intnum}?{fraction})|({intnum}{exponent})|({intnum}?{fraction}{exponent})|({intnum}\.)|({intnum}\.{exponent}))
312 hexfraction (({hexdigit}*"."{hexdigit}+)|({hexdigit}+))
313 binexponent ([pP][\+\-]?{decdigit}+)
314 floatonlynum ({decfloat}{floatsuffix}?)
315 floatexponent ([pP][\+\-]?{floatonlynum})
316 hexfloat (({hexprefix}{hexfraction}{binexponent})|({hexprefix}{hexdigit}+{binexponent})|({hexprefix}{hexdigit}{floatexponent}))
319 floatnum (({decfloat}|{hexfloat}){floatsuffix}?)
320 complexnum (({decfloat}|{hexfloat})({complexsuffix}{floatsuffix}?|{floatsuffix}{complexsuffix}))
321 ident ({letter}|"_")({letter}|{decdigit}|"_")*
322 attribident (({letter}|"_")({letter}|{decdigit}|"_"|":"))
324 /* From C norm A.1: */
325 hex_escape ({escape}x{hexdigit}{1,2})
326 wide_hex_escape ({escape}x{hexdigit}{1,8})
327 oct_escape ({escape}{octdigit}{1,3})
328 char_escape ({escape}[abfnrtv\'\\?"])
330 universal-character-name ({escape}(u{hexdigit}{4}|U{hexdigit}{8}))
335 ("/*"([^*]|("*"+[^/*]))*"*"+"/")|("//"("\\\n"|[^\n])*"\n"?) { // help emacs: */
336 // Bug in the Flex 2.5.35 manual A.4.3, "/***/" fails. :-(
337 csplit_line_number += lf_count(yytext);
338 user_line_number += lf_count(yytext);
341 pips_debug(5,"Comment \"%s\"\n",yytext);
343 if (gather_comment_state_machine == GATHER_COMMENT)
344 /* This comment is associated to previous
345 top-level construct: */
346 reset_csplit_current_beginning();
347 if (gather_comment_state_machine == GATHER_SPACES)
348 /* We encounter a comment whereas we were
349 gathering spaces into the previous
350 top-level construct. So now this comment
351 will go in the next top-level construct: */
352 gather_comment_state_machine = PUT_IN_NEXT_TOP_LEVEL_CONSTRUCT;
355 ^"#"("\\\n"|[^\n])* {
356 /* Look for a # up to the end of line,
357 dealing with any backslashed new lines: */
358 /* csplit_line_number++; */
359 pips_debug(5,"Pragma comment %s\n",yytext);
360 /* Must be a line pragma left by the preprocessor:
367 if(strstr(yytext, "#pragma")==yytext) {
368 // FC 2016-06-18: Why not count pragma lines? This just breaks line numbering...
369 // commented out: user_line_number--;
371 /* the preprocessor seems to provide line information in pragmas
372 which are not #line pragmas. */
373 else if(/* strstr(yytext, "#line")==yytext && */ (n=strlen(yytext))>=4) {
374 int initial_C_line_number = -1;
375 char include_file[n] ;
376 int items = sscanf(yytext+1, "%d \"%[^\"]\"", &initial_C_line_number,include_file);
378 /* Get rid of the pragma LF itslef */
379 user_line_number = initial_C_line_number-1;
381 if(!current_file_path) current_file_path = strdup(include_file);
382 else if(!current_include_file_path) current_include_file_path=strdup(include_file);
383 else if(strcmp(include_file,current_file_path)==0) { free(current_include_file_path) ; current_include_file_path=NULL; }
387 pips_user_warning("No line number in # pragma: \"%s\".\n", yytext);
388 splitc_error("Ill. formated # pragma\n");
394 csplit_line_number++;
396 pips_debug(5, "New line %d, ext=%d, func=%d\n", csplit_line_number, csplit_is_external, csplit_is_function);
398 if (gather_comment_state_machine == GATHER_COMMENT) {
399 /* We encounter a newline, stop gathering
400 comments and gather spaces from now: */
401 //gather_comment_state_machine = GATHER_SPACES;
402 /* Well, ideed, we want to be compatible with
403 old behaviour: associate newlines and other
404 from now to next top-level construct: */
405 gather_comment_state_machine = PUT_IN_NEXT_TOP_LEVEL_CONSTRUCT;
406 /* Associate the current \n to the previous
407 top-level construct: */
408 reset_csplit_current_beginning();
410 if (gather_comment_state_machine == GATHER_SPACES) {
411 /* Add this newline to the previous top-level
413 reset_csplit_current_beginning();
418 /* Eat up whitespaces. After the previous '\n'
419 since it includes '\n' and we want
421 if (gather_comment_state_machine == GATHER_COMMENT
422 || gather_comment_state_machine == GATHER_SPACES) {
423 /* Add this space to the previous top-level
425 reset_csplit_current_beginning();
430 LEXER_RETURN(TK_PRAGMA);
433 \'([^\\]|{char_escape}|{oct_escape}|{hex_escape}|{universal-character-name})\' {
434 /* Have a look to Flex A.4.3 too... */
435 /* Escaped character constants. Their
436 syntax is understood in PIPS character
437 constant construtors. */
438 pips_debug(9,"TK_CHARCON: %s\n",yytext);
439 splitc_lval.string = strdup(yytext);
440 LEXER_RETURN(TK_CHARCON);
443 L\'([^\\]|{char_escape}|{oct_escape}|{wide_hex_escape}|{universal-character-name})\' {
444 /* Escaped wide character constants. Their
445 syntax is understood in PIPS character
446 constant construtors. */
447 pips_debug(9,"TK_CHARCON wide character constant: %s\n",yytext);
448 splitc_lval.string = strdup(yytext);
449 LEXER_RETURN(TK_CHARCON);
452 \"(\\\"|[^\"\\]|\\[^\"])*\" {
453 pips_debug(5,"TK_STRINGCON regular or wide string: %s\n",yytext);
454 /* the "world" in L"Hello, " "world" should be treated as
455 wide even though there's no L immediately preceding it */
456 splitc_lval.string = strdup(yytext);
457 LEXER_RETURN(TK_STRINGCON);
460 L\"(\\\"|[^\"\\]|\\[^\"])*\" {
461 pips_debug(5,"TK_WSTRINGCON wide string: %s\n",yytext);
462 splitc_lval.string = strdup(yytext);
463 LEXER_RETURN(TK_WSTRINGCON);
466 pips_debug(5,"TK_FLOATCON %s\n",yytext);
467 splitc_lval.string = strdup(yytext);
468 LEXER_RETURN(TK_FLOATCON);
471 pips_debug(5,"TK_COMPLEXCON %s\n",yytext);
472 splitc_lval.string = strdup(yytext);
473 LEXER_RETURN(TK_COMPLEXCON);
476 pips_debug(5,"Hexnum TK_INTCON %s\n",yytext);
477 splitc_lval.string = strdup(yytext);
478 LEXER_RETURN(TK_INTCON);
481 pips_debug(5,"Octnum TK_INTCON %s\n",yytext);
482 splitc_lval.string = strdup(yytext);
483 LEXER_RETURN(TK_INTCON);
486 pips_debug(5,"TK_INTCON %s\n",yytext);
487 splitc_lval.string = strdup(yytext);
488 LEXER_RETURN(TK_INTCON);
491 pips_debug(5,"TK_EOF %s\n",yytext);
495 pips_debug(5,"TK_ELLIPSIS %s\n",yytext);
496 LEXER_RETURN(TK_ELLIPSIS);
499 pips_debug(5,"TK_PLUS_EQ %s\n",yytext);
500 LEXER_RETURN(TK_PLUS_EQ);
503 pips_debug(5,"TK_MINUS_EQ %s\n",yytext);
504 LEXER_RETURN(TK_MINUS_EQ);
507 pips_debug(5,"TK_STAR_EQ %s\n",yytext);
508 LEXER_RETURN(TK_STAR_EQ);
511 pips_debug(5,"TK_SLASH_EQ %s\n",yytext);
512 LEXER_RETURN(TK_SLASH_EQ);
515 pips_debug(5,"TK_PERCENT_EQ %s\n",yytext);
516 LEXER_RETURN(TK_PERCENT_EQ);
519 pips_debug(5,"TK_PIPE_EQ %s\n",yytext);
520 LEXER_RETURN(TK_PIPE_EQ);
523 pips_debug(5,"TK_AND_EQ %s\n",yytext);
524 LEXER_RETURN(TK_AND_EQ);
527 pips_debug(5,"TK_CIRC_EQ %s\n",yytext);
528 LEXER_RETURN(TK_CIRC_EQ);
531 pips_debug(5,"TK_INF_INF_EQ %s\n",yytext);
532 LEXER_RETURN(TK_INF_INF_EQ);
535 pips_debug(5,"TK_SUP_SUP_EQ %s\n",yytext);
536 LEXER_RETURN(TK_SUP_SUP_EQ);
539 pips_debug(5,"TK_INF_INF %s\n",yytext);
540 LEXER_RETURN(TK_INF_INF);
543 pips_debug(5,"TK_SUP_SUP %s\n",yytext);
544 LEXER_RETURN(TK_SUP_SUP);
547 pips_debug(5,"TK_EQ_EQ %s\n",yytext);
548 LEXER_RETURN(TK_EQ_EQ);
551 pips_debug(5,"TK_EXCLAM_EQ %s\n",yytext);
552 LEXER_RETURN(TK_EXCLAM_EQ);
555 pips_debug(5,"TK_INF_EQ %s\n",yytext);
556 LEXER_RETURN(TK_INF_EQ);
559 pips_debug(5,"TK_SUP_EQ %s\n",yytext);
560 LEXER_RETURN(TK_SUP_EQ);
563 pips_debug(5,"TK_EQ %s\n",yytext);
567 pips_debug(5,"TK_INF %s\n",yytext);
568 LEXER_RETURN(TK_INF);
571 pips_debug(5,"TK_SUP %s\n",yytext);
572 LEXER_RETURN(TK_SUP);
575 pips_debug(5,"TK_PLUS_PLUS %s\n",yytext);
576 LEXER_RETURN(TK_PLUS_PLUS);
579 pips_debug(5,"TK_MINUS_MINUS %s\n",yytext);
580 LEXER_RETURN(TK_MINUS_MINUS);
583 pips_debug(5,"TK_ARROW %s\n",yytext);
584 LEXER_RETURN(TK_ARROW);
587 pips_debug(5,"TK_PLUS %s\n",yytext);
588 LEXER_RETURN(TK_PLUS);
591 pips_debug(5,"TK_MINUS %s\n",yytext);
592 LEXER_RETURN(TK_MINUS);
595 pips_debug(5,"TK_STAR %s\n",yytext);
596 LEXER_RETURN(TK_STAR);
599 pips_debug(5,"TK_SLASH %s\n",yytext);
600 LEXER_RETURN(TK_SLASH);
603 pips_debug(5,"TK_PERCENT %s\n",yytext);
604 LEXER_RETURN(TK_PERCENT);
607 pips_debug(5,"TK_EXCLAM %s\n",yytext);
608 LEXER_RETURN(TK_EXCLAM);
611 pips_debug(5,"TK_AND_AND %s\n",yytext);
612 LEXER_RETURN(TK_AND_AND);
615 pips_debug(5,"TK_PIPE_PIPE %s\n",yytext);
616 LEXER_RETURN(TK_PIPE_PIPE);
619 pips_debug(5,"TK_AND %s\n",yytext);
620 LEXER_RETURN(TK_AND);
623 pips_debug(5,"TK_PIPE %s\n",yytext);
624 LEXER_RETURN(TK_PIPE);
627 pips_debug(5,"TK_CIRC %s\n",yytext);
628 LEXER_RETURN(TK_CIRC);
631 pips_debug(5,"TK_QUEST %s\n",yytext);
632 LEXER_RETURN(TK_QUEST);
635 pips_debug(5,"TK_COLON %s\n",yytext);
636 LEXER_RETURN(TK_COLON);
639 pips_debug(5,"TK_TILDE %s\n",yytext);
640 LEXER_RETURN(TK_TILDE);
643 pips_debug(5,"TK_LBRACE %s\n",yytext);
644 LEXER_RETURN(TK_LBRACE);
647 pips_debug(5,"TK_RBRACE %s\n",yytext);
648 LEXER_RETURN(TK_RBRACE);
651 pips_debug(5,"TK_LBRACKET %s\n",yytext);
653 LEXER_RETURN(TK_LBRACKET);
656 pips_debug(5,"TK_RBRACKET %s\n",yytext);
658 LEXER_RETURN(TK_RBRACKET);
661 pips_debug(5,"TK_LPAREN %s\n",yytext);
662 LEXER_RETURN(TK_LPAREN);
665 pips_debug(5,"TK_RPAREN %s\n",yytext);
666 LEXER_RETURN(TK_RPAREN);
669 pips_debug(5,"TK_SEMICOLON %s\n",yytext);
670 LEXER_RETURN(TK_SEMICOLON);
673 pips_debug(5,"TK_COMMA %s\n",yytext);
674 LEXER_RETURN(TK_COMMA);
677 pips_debug(5,"TK_DOT %s\n",yytext);
678 LEXER_RETURN(TK_DOT);
681 pips_debug(5,"TK_SIZEOF %s\n",yytext);
682 LEXER_RETURN(TK_SIZEOF);
685 pips_debug(5,"TK_ASM %s\n",yytext);
686 LEXER_RETURN(TK_ASM);
689 /* convert __va_list from bsd into __builtin_va_list */
690 pips_debug(5,"TK_VA_LIST %s\n",yytext);
691 yytext = strdup("__builtin_va_list");
692 int t = is_c_preprocessor_keyword_typedef(yytext);
693 update_csplit_current_beginning();
694 pips_assert("builtin valist found\n",t>0);
695 pips_debug(5,"Keyword or typedef name: %s\n",yytext);
696 splitc_lval.string = strdup(yytext);
701 /* FI: when we change our minds and want to make these tokens, we must
702 * insert them in keyword_typedef_table.
705 pips_debug(5,"TK_ATTRIBUTE %s\n",yytext);
706 LEXER_RETURN(TK_ATTRIBUTE);
709 pips_user_warning("gcc extension keyword \"__extension__\" is ignored\n");
712 pips_user_warning("gcc extension keyword \"__inline\" is ignored\n");
715 pips_user_warning("gcc extension keyword \"__inline__\" is ignored\n");
718 pips_user_warning("gcc extension keyword \"__signed__\" is ignored\n");
721 /* C keywords or identifiers */
722 int t = is_c_preprocessor_keyword_typedef(yytext);
723 update_csplit_current_beginning();
726 pips_debug(5,"Keyword or typedef name: %s\n",yytext);
727 splitc_lval.string = strdup(yytext);
732 pips_debug(5,"TK_IDENT: %s\n",yytext);
733 /* Might not work if a function returns a struct declared locally in the function declaration, or a pointer to such a structure */
734 if(string_undefined_p(csplit_current_function_name)) {
735 csplit_current_function_name = strdup(yytext);
736 pips_debug(5, "Temptative function name found: \"%s\"\n",
737 csplit_current_function_name);
739 else if(string_undefined_p(csplit_current_function_name2)) {
740 pips_debug(5, "Identifier \"%s\" ignored because of two previous identifiers \"%s\"\n",
741 yytext, csplit_current_function_name);
742 csplit_current_function_name2 = strdup(yytext);
745 free(csplit_current_function_name2);
746 pips_debug(5, "Identifier \"%s\" not ignored in spite of two previous identifiers \"%s\"\n",
747 yytext, csplit_current_function_name);
748 csplit_current_function_name2 = strdup(yytext);
751 splitc_lval.string = strdup(yytext);
752 LEXER_RETURN(TK_IDENT);
756 pips_debug(5,"TK_EOF %s\n",yytext);
757 LEXER_RETURN(TK_EOF);
761 csplit_parser_warning("Unrecognized character '%s'\n", yytext);
762 pips_user_warning("Preprocessor directives must have disappeared thanks to the C preprocessor.\n"
763 "Check the input code and/or modify the preprocessor options using environment variables PIPS_CPP.\n");
766 csplit_parser_warning("Unrecognized character '%s'\n", yytext);
770 /* This function is renamed splitc_error(). It should probably reset more variables */
771 void splitc_error(const char * msg)
773 /* I should call csplit_parser_error() or the equivalent module */
774 string ifn = get_splitc_input_file_name();
775 string current_line = safe_read_nth_line(ifn, csplit_line_number);
776 /* pips_user_warning(
777 "C %s near \"%s\" at preprocessed line %d (user line %d):\n%s\n\n",
778 msg, yytext, csplit_line_number, user_line_number,
781 "C %s near \"%s\" at line %d in file \"%s\":\n%s\n\n",
782 msg, yytext, user_line_number,
783 preprocessor_current_initial_file_name,
786 pips_user_error("Syntax error detected by PIPS C preprocessor.\n"
788 " 1. check the legality of the source code with a production C compiler\n"
789 " 2. see if the issue is linked to a non-standard C feature\n"
790 " 3. see if the issue is a C feature unsupported by PIPS C parser\n"
791 " 4. see if the source code can be rewritten differently.\n");
794 int yywrap() { return 1;}