Line data Source code
1 : %{
2 : /* m2.flex implements lexical analysis for Modula-2.
3 :
4 : Copyright (C) 2004-2026 Free Software Foundation, Inc.
5 : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 :
7 : This file is part of GNU Modula-2.
8 :
9 : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3, or (at your option)
12 : any later version.
13 :
14 : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with GNU Modula-2; see the file COPYING3. If not see
21 : <http://www.gnu.org/licenses/>. */
22 :
23 : #include "gm2-gcc/gcc-consolidation.h"
24 :
25 : #include "GM2Reserved.h"
26 : #include "GM2LexBuf.h"
27 : #include "input.h"
28 : #include "m2options.h"
29 : #include "Gm2linemap.h"
30 :
31 : static int cpreprocessor = 0; /* Replace this with correct getter. */
32 :
33 : #if defined(GM2USEGGC)
34 : # include "ggc.h"
35 : #endif
36 :
37 : #include "timevar.h"
38 :
39 : #define START_FILE(F,L) m2linemap_StartFile(F,L)
40 : #define END_FILE() m2linemap_EndFile()
41 : #define START_LINE(N,S) m2linemap_StartLine(N,S)
42 : #define GET_LOCATION(COLUMN_START,COLUMN_END) \
43 : m2linemap_GetLocationRange(COLUMN_START,COLUMN_END)
44 : #define TIMEVAR_PUSH_LEX timevar_push (TV_LEX)
45 : #define TIMEVAR_POP_LEX timevar_pop (TV_LEX)
46 :
47 : #ifdef __cplusplus
48 : #define EXTERN extern "C"
49 : #endif
50 :
51 : #define FIRST_COLUMN 1
52 :
53 : /* m2.flex provides a lexical analyser for GNU Modula-2. */
54 :
55 : struct lineInfo {
56 : char *linebuf; /* line contents */
57 : int linelen; /* length */
58 : int tokenpos; /* start position of token within line */
59 : int toklen; /* a copy of yylen (length of token) */
60 : int nextpos; /* position after token */
61 : int lineno; /* line number of this line */
62 : int column; /* first column number of token on this line */
63 : bool inuse; /* do we need to keep this line info? */
64 : location_t location; /* the corresponding gcc location_t */
65 : struct lineInfo *next;
66 : };
67 :
68 : struct functionInfo {
69 : char *name; /* function name */
70 : bool module; /* is it really a module? */
71 : struct functionInfo *next; /* list of nested functions */
72 : };
73 :
74 : static int lineno =1; /* a running count of the file line number */
75 : static char *filename =NULL;
76 : static int commentLevel=0;
77 : static int commentCLevel=0;
78 : static struct lineInfo *currentLine=NULL;
79 : static struct functionInfo *currentFunction=NULL;
80 : static bool seenFunctionStart=false;
81 : static bool seenEnd=false;
82 : static bool seenModuleStart=false;
83 : static bool isDefinitionModule=false;
84 : static int totalLines=0;
85 :
86 : static void pushLine (void);
87 : static void popLine (void);
88 : static void finishedLine (void);
89 : static void resetpos (void);
90 : static void consumeLine (void);
91 : static void updatepos (void);
92 : static void skippos (void);
93 : static void poperrorskip (const char *);
94 : static void endOfComment (void);
95 : static void endOfCComment (void);
96 : static void splitSlashStar (void);
97 : static void handleDate (void);
98 : static void handleLine (void);
99 : static void handleFile (void);
100 : static void handleFunction (void);
101 : static void handleColumn (void);
102 : static void pushFunction (char *function, bool module);
103 : static void popFunction (void);
104 : static void checkFunction (void);
105 : EXTERN void m2flex_M2Error (const char *);
106 : EXTERN location_t m2flex_GetLocation (void);
107 : EXTERN int m2flex_GetColumnNo (void);
108 : EXTERN bool m2flex_OpenSource (char *s);
109 : EXTERN int m2flex_GetLineNo (void);
110 : EXTERN void m2flex_CloseSource (void);
111 : EXTERN char *m2flex_GetToken (void);
112 : EXTERN void _M2_m2flex_init (void);
113 : EXTERN int m2flex_GetTotalLines (void);
114 : extern void yylex (void);
115 :
116 : #define YY_DECL void yylex (void)
117 : %}
118 :
119 : %option nounput
120 : %x COMMENT COMMENT1 COMMENTC LINE0 LINE1 LINE2
121 :
122 : %%
123 :
124 4324592 : "(*" { updatepos();
125 4324592 : commentLevel=1; pushLine(); skippos();
126 4324592 : BEGIN COMMENT; }
127 8780289 : <COMMENT>"*)" { endOfComment(); }
128 4586814 : <COMMENT>"(*" { commentLevel++; pushLine(); updatepos(); skippos(); }
129 4470630 : <COMMENT>"<*" { if (commentLevel == 1) {
130 146044 : updatepos();
131 29860 : pushLine();
132 14927 : skippos();
133 14927 : BEGIN COMMENT1;
134 : } else {
135 6 : updatepos(); skippos();
136 : }
137 : }
138 17839706 : <COMMENT>\n.* { consumeLine(); }
139 755270988 : <COMMENT>. { updatepos(); skippos(); }
140 149270 : <COMMENT1>. { updatepos(); skippos(); }
141 755285915 : <COMMENT1>"*>" { updatepos(); skippos(); finishedLine(); BEGIN COMMENT; }
142 149270 : <COMMENT1>\n.* { consumeLine(); }
143 14927 : <COMMENT1>"*)" { poperrorskip("unterminated source code directive, missing *>");
144 0 : endOfComment(); }
145 0 : <COMMENT1><<EOF>> { poperrorskip("unterminated source code directive, missing *>"); BEGIN COMMENT; }
146 0 : <COMMENT><<EOF>> { poperrorskip("unterminated comment found at the end of the file, missing *)"); BEGIN INITIAL; }
147 12 :
148 0 : "/*" { /* Possibly handle C preprocessor comment. */
149 0 : if (cpreprocessor)
150 : {
151 0 : updatepos ();
152 0 : commentCLevel++;
153 0 : if (commentCLevel == 1)
154 : {
155 0 : pushLine ();
156 0 : skippos ();
157 : }
158 0 : BEGIN COMMENTC;
159 : }
160 : else
161 0 : splitSlashStar ();
162 : }
163 0 : <COMMENTC>. { updatepos(); skippos(); }
164 0 : <COMMENTC>\n.* { consumeLine(); }
165 0 : <COMMENTC>"*/" { endOfCComment(); }
166 18184 : ^\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
167 18184 : if (M2Options_GetLineDirectives ())
168 36368 : BEGIN LINE0;
169 : }
170 14100 : \n\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
171 14100 : if (M2Options_GetLineDirectives ())
172 14100 : BEGIN LINE0;
173 14100 : }
174 14100 : <LINE0>\#[ \t]* { updatepos(); }
175 46384 : <LINE0>[0-9]+[ \t]*\" { updatepos(); lineno=atoi(yytext); BEGIN LINE1; }
176 46384 : <LINE0>\n { m2flex_M2Error("missing initial quote after #line directive"); resetpos(); BEGIN INITIAL; }
177 32284 : <LINE0>[^\n]
178 0 : <LINE1>[^\"\n]+ { m2flex_M2Error("missing final quote after #line directive"); resetpos(); BEGIN INITIAL; }
179 50468 : <LINE1>.*\" { updatepos();
180 32284 : filename = (char *)xrealloc(filename, yyleng+1);
181 32284 : strcpy(filename, yytext);
182 32284 : filename[yyleng-1] = (char)0; /* remove trailing quote */
183 32284 : START_FILE (filename, lineno);
184 32284 : BEGIN LINE2;
185 : }
186 32284 : <LINE2>[ \t]* { updatepos(); }
187 32284 : <LINE2>\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
188 35680 : <LINE2>2[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
189 3396 : <LINE2>1[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
190 18700 : <LINE2>1[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
191 6792 : <LINE2>2[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
192 10188 : <LINE2>3[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
193 13584 :
194 0 : \n[^\#].* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
195 47815648 : \n { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
196 48049902 :
197 455313 : \"[^\"\n]*\" { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
198 699755 : \"[^\"\n]*$ { updatepos();
199 0 : m2flex_M2Error("missing terminating quote, \"");
200 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext);
201 0 : resetpos(); return;
202 0 : }
203 0 :
204 996601 : '[^'\n]*' { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
205 996607 : '[^'\n]*$ { updatepos();
206 6 : m2flex_M2Error("missing terminating quote, '");
207 6 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext);
208 12 : resetpos(); return;
209 6 : }
210 6 :
211 244903 : <<EOF>> { updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return; }
212 437675 : \+ { updatepos(); M2LexBuf_AddTok(M2Reserved_plustok); return; }
213 417450 : - { updatepos(); M2LexBuf_AddTok(M2Reserved_minustok); return; }
214 561279 : "*" { updatepos(); M2LexBuf_AddTok(M2Reserved_timestok); return; }
215 676595 : \/ { updatepos(); M2LexBuf_AddTok(M2Reserved_dividetok); return; }
216 3940251 : := { updatepos(); M2LexBuf_AddTok(M2Reserved_becomestok); return; }
217 14242 : \& { updatepos(); M2LexBuf_AddTok(M2Reserved_ambersandtok); return; }
218 6452842 : \. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodtok); return; }
219 11572914 : \, { updatepos(); M2LexBuf_AddTok(M2Reserved_commatok); return; }
220 21709238 : \; { updatepos(); M2LexBuf_AddTok(M2Reserved_semicolontok); return; }
221 26556038 : \( { updatepos(); M2LexBuf_AddTok(M2Reserved_lparatok); return; }
222 34056173 : \) { updatepos(); M2LexBuf_AddTok(M2Reserved_rparatok); return; }
223 16117765 : \[ { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
224 16117745 : \] { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
225 1134641 : \(\! { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
226 1134615 : \!\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
227 1359914 : \^ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
228 0 : \@ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
229 1396438 : \{ { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
230 36524 : \} { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
231 36524 : \(\: { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
232 36524 : \:\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
233 0 : \' { updatepos(); M2LexBuf_AddTok(M2Reserved_singlequotetok); return; }
234 1349540 : \= { updatepos(); M2LexBuf_AddTok(M2Reserved_equaltok); return; }
235 570728 : \# { updatepos(); M2LexBuf_AddTok(M2Reserved_hashtok); return; }
236 1780688 : \< { updatepos(); M2LexBuf_AddTok(M2Reserved_lesstok); return; }
237 848788 : \> { updatepos(); M2LexBuf_AddTok(M2Reserved_greatertok); return; }
238 431232 : \<\> { updatepos(); M2LexBuf_AddTok(M2Reserved_lessgreatertok); return; }
239 503990 : \<\= { updatepos(); M2LexBuf_AddTok(M2Reserved_lessequaltok); return; }
240 113174 : \>\= { updatepos(); M2LexBuf_AddTok(M2Reserved_greaterequaltok); return; }
241 699527 : "<*" { updatepos(); M2LexBuf_AddTok(M2Reserved_ldirectivetok); return; }
242 586687 : "*>" { updatepos(); M2LexBuf_AddTok(M2Reserved_rdirectivetok); return; }
243 576199 : \.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodtok); return; }
244 484941 : \.\.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodperiodtok); return; }
245 13239104 : \: { updatepos(); M2LexBuf_AddTok(M2Reserved_colontok); return; }
246 11344 : \" { updatepos(); M2LexBuf_AddTok(M2Reserved_doublequotestok); return; }
247 13209774 : \| { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
248 0 : \! { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
249 73272 : \~ { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
250 450210 : AND { updatepos(); M2LexBuf_AddTok(M2Reserved_andtok); return; }
251 1122787 : ARRAY { updatepos(); M2LexBuf_AddTok(M2Reserved_arraytok); return; }
252 2375524 : BEGIN { updatepos(); M2LexBuf_AddTok(M2Reserved_begintok); return; }
253 1123183 : BY { updatepos(); M2LexBuf_AddTok(M2Reserved_bytok); return; }
254 1970396 : CASE { updatepos(); M2LexBuf_AddTok(M2Reserved_casetok); return; }
255 69760 : CONST { updatepos(); M2LexBuf_AddTok(M2Reserved_consttok); return; }
256 207172 : DEFINITION { updatepos(); isDefinitionModule = true;
257 231454 : M2LexBuf_AddTok(M2Reserved_definitiontok); return; }
258 247937 : DIV { updatepos(); M2LexBuf_AddTok(M2Reserved_divtok); return; }
259 619052 : DO { updatepos(); M2LexBuf_AddTok(M2Reserved_dotok); return; }
260 895043 : ELSE { updatepos(); M2LexBuf_AddTok(M2Reserved_elsetok); return; }
261 763572 : ELSIF { updatepos(); M2LexBuf_AddTok(M2Reserved_elsiftok); return; }
262 5621470 : END { updatepos(); seenEnd=true;
263 4956794 : M2LexBuf_AddTok(M2Reserved_endtok); return; }
264 4812508 : EXCEPT { updatepos(); M2LexBuf_AddTok(M2Reserved_excepttok); return; }
265 106 : EXIT { updatepos(); M2LexBuf_AddTok(M2Reserved_exittok); return; }
266 86260 : EXPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_exporttok); return; }
267 6078 : FINALLY { updatepos(); M2LexBuf_AddTok(M2Reserved_finallytok); return; }
268 142622 : FOR { updatepos(); M2LexBuf_AddTok(M2Reserved_fortok); return; }
269 6032 : FORWARD { updatepos(); M2LexBuf_AddTok(M2Reserved_forwardtok); return; }
270 409061 : FROM { updatepos(); M2LexBuf_AddTok(M2Reserved_fromtok); return; }
271 1934923 : IF { updatepos(); M2LexBuf_AddTok(M2Reserved_iftok); return; }
272 426485 : IMPLEMENTATION { updatepos(); M2LexBuf_AddTok(M2Reserved_implementationtok); return; }
273 2336676 : IMPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_importtok); return; }
274 157220 : IN { updatepos(); M2LexBuf_AddTok(M2Reserved_intok); return; }
275 410511 : LOOP { updatepos(); M2LexBuf_AddTok(M2Reserved_looptok); return; }
276 215942 : MOD { updatepos(); M2LexBuf_AddTok(M2Reserved_modtok); return; }
277 268986 : MODULE { updatepos(); seenModuleStart=true;
278 393030 : M2LexBuf_AddTok(M2Reserved_moduletok); return; }
279 396062 : NOT { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
280 1172623 : OF { updatepos(); M2LexBuf_AddTok(M2Reserved_oftok); return; }
281 286306 : OR { updatepos(); M2LexBuf_AddTok(M2Reserved_ortok); return; }
282 1175455 : PACKEDSET { updatepos(); M2LexBuf_AddTok(M2Reserved_packedsettok); return; }
283 251637 : POINTER { updatepos(); M2LexBuf_AddTok(M2Reserved_pointertok); return; }
284 5239428 : PROCEDURE { updatepos(); seenFunctionStart=true;
285 5337701 : M2LexBuf_AddTok(M2Reserved_proceduretok); return; }
286 5310696 : QUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_qualifiedtok); return; }
287 11632 : UNQUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_unqualifiedtok); return; }
288 145717 : RECORD { updatepos(); M2LexBuf_AddTok(M2Reserved_recordtok); return; }
289 11728 : REM { updatepos(); M2LexBuf_AddTok(M2Reserved_remtok); return; }
290 143247 : REPEAT { updatepos(); M2LexBuf_AddTok(M2Reserved_repeattok); return; }
291 270 : RETRY { updatepos(); M2LexBuf_AddTok(M2Reserved_retrytok); return; }
292 1530247 : RETURN { updatepos(); M2LexBuf_AddTok(M2Reserved_returntok); return; }
293 2090 : SET { updatepos(); M2LexBuf_AddTok(M2Reserved_settok); return; }
294 3538000 : THEN { updatepos(); M2LexBuf_AddTok(M2Reserved_thentok); return; }
295 146505 : TO { updatepos(); M2LexBuf_AddTok(M2Reserved_totok); return; }
296 2195838 : TYPE { updatepos(); M2LexBuf_AddTok(M2Reserved_typetok); return; }
297 216219 : UNTIL { updatepos(); M2LexBuf_AddTok(M2Reserved_untiltok); return; }
298 1693849 : VAR { updatepos(); M2LexBuf_AddTok(M2Reserved_vartok); return; }
299 451764 : WHILE { updatepos(); M2LexBuf_AddTok(M2Reserved_whiletok); return; }
300 1772822 : WITH { updatepos(); M2LexBuf_AddTok(M2Reserved_withtok); return; }
301 380161 : ASM { updatepos(); M2LexBuf_AddTok(M2Reserved_asmtok); return; }
302 195443 : VOLATILE { updatepos(); M2LexBuf_AddTok(M2Reserved_volatiletok); return; }
303 27 : \_\_DATE\_\_ { updatepos(); handleDate(); return; }
304 128257 : \_\_LINE\_\_ { updatepos(); handleLine(); return; }
305 124654 : \_\_FILE\_\_ { updatepos(); handleFile(); return; }
306 251162 : \_\_FUNCTION\_\_ { updatepos(); handleFunction(); return; }
307 179262 : \_\_COLUMN\_\_ { updatepos(); handleColumn(); return; }
308 593788 : \_\_ATTRIBUTE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_attributetok); return; }
309 966002 : \_\_BUILTIN\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_builtintok); return; }
310 470868 : \_\_INLINE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_inlinetok); return; }
311 911394 :
312 0 :
313 28982 : (([0-9]*\.[0-9]+)(E[+-]?[0-9]+)?) { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_realtok, yytext); return; }
314 6 : [0-9]*\.E[+-]?[0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_realtok, yytext); return; }
315 70426656 : [a-zA-Z_][a-zA-Z0-9_]* { checkFunction(); updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_identtok, yytext); return; }
316 2407390 : [0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
317 70426680 : [0-1]+A { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
318 2410130 : [0-9]+B { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
319 133118 : [0-9]+C { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
320 14244 : [0-9A-F]+H { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
321 133094 : [\t\r ]+ { currentLine->tokenpos += yyleng; /* Ignore space. */; }
322 110744422 : . { updatepos(); m2flex_M2Error("unrecognised symbol"); skippos(); }
323 110732924 :
324 0 : %%
325 0 :
326 : /* have removed the -? from the beginning of the real/integer constant literal rules */
327 :
328 : /*
329 : * hand built routines
330 : */
331 :
332 : /*
333 : * handleFile - handles the __FILE__ construct by wraping it in double quotes and putting
334 : * it into the token buffer as a string.
335 : */
336 :
337 124654 : static void handleFile (void)
338 : {
339 124654 : char *s = (char *)alloca(strlen(filename)+2+1);
340 :
341 124654 : strcpy(s, "\"");
342 124654 : strcat(s, filename);
343 124654 : strcat(s, "\"");
344 124654 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
345 124654 : }
346 :
347 : /*
348 : * handleLine - handles the __LINE__ construct by passing an integer to
349 : * the token buffer.
350 : */
351 :
352 128242 : static void handleLine (void)
353 : {
354 128242 : M2LexBuf_AddTokInteger(M2Reserved_integertok, lineno);
355 128242 : }
356 :
357 : /*
358 : * handleColumn - handles the __COLUMN__ construct by passing an integer to
359 : * the token buffer.
360 : */
361 :
362 54608 : static void handleColumn (void)
363 : {
364 54608 : M2LexBuf_AddTokInteger(M2Reserved_integertok, m2flex_GetColumnNo());
365 54608 : }
366 :
367 : /*
368 : * handleDate - handles the __DATE__ construct by passing the date
369 : * as a string to the token buffer.
370 : */
371 :
372 0 : static void handleDate (void)
373 : {
374 0 : time_t clock = time ((time_t *)0);
375 0 : char *sdate = ctime (&clock);
376 0 : char *s = (char *) alloca (strlen (sdate) + 2 + 1);
377 0 : char *p = index (sdate, '\n');
378 :
379 0 : if (p != NULL) {
380 0 : *p = (char) 0;
381 : }
382 0 : strcpy(s, "\"");
383 0 : strcat(s, sdate);
384 0 : strcat(s, "\"");
385 0 : M2LexBuf_AddTokCharStar (M2Reserved_stringtok, s);
386 0 : }
387 :
388 : /*
389 : * handleFunction - handles the __FUNCTION__ construct by wrapping
390 : * it in double quotes and putting it into the token
391 : * buffer as a string.
392 : */
393 :
394 122920 : static void handleFunction (void)
395 : {
396 122920 : if (currentFunction == NULL)
397 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, const_cast<char *>("\"\""));
398 122920 : else if (currentFunction->module) {
399 6 : char *s = (char *) alloca(strlen(yytext) +
400 : strlen("\"module initialization\"") + 1);
401 6 : strcpy(s, "\"module ");
402 6 : strcat(s, currentFunction->name);
403 6 : strcat(s, " initialization\"");
404 6 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
405 : } else {
406 122914 : char *function = currentFunction->name;
407 122914 : char *s = (char *)alloca(strlen(function)+2+1);
408 122914 : strcpy(s, "\"");
409 122914 : strcat(s, function);
410 122914 : strcat(s, "\"");
411 122914 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
412 : }
413 122920 : }
414 :
415 : /*
416 : * pushFunction - pushes the function name onto the stack.
417 : */
418 :
419 1544941 : static void pushFunction (char *function, bool module)
420 : {
421 1544941 : if (currentFunction == NULL) {
422 97764 : currentFunction = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
423 97764 : currentFunction->name = xstrdup(function);
424 97764 : currentFunction->next = NULL;
425 97764 : currentFunction->module = module;
426 : } else {
427 1447177 : struct functionInfo *f = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
428 1447177 : f->name = xstrdup(function);
429 1447177 : f->next = currentFunction;
430 1447177 : f->module = module;
431 1447177 : currentFunction = f;
432 : }
433 1544941 : }
434 :
435 : /*
436 : * popFunction - pops the current function.
437 : */
438 :
439 1529822 : static void popFunction (void)
440 : {
441 1529822 : if (currentFunction != NULL && currentFunction->next != NULL) {
442 1447099 : struct functionInfo *f = currentFunction;
443 :
444 1447099 : currentFunction = currentFunction->next;
445 1447099 : if (f->name != NULL)
446 1447099 : free(f->name);
447 1447099 : free(f);
448 : }
449 1529822 : }
450 :
451 : /*
452 : * endOfComment - handles the end of comment
453 : */
454 :
455 4455697 : static void endOfComment (void)
456 : {
457 4455697 : commentLevel--;
458 4455697 : updatepos();
459 4455697 : skippos();
460 4455697 : if (commentLevel==0) {
461 4324580 : BEGIN INITIAL;
462 4324580 : finishedLine();
463 : } else
464 131117 : popLine();
465 4455697 : }
466 :
467 : /*
468 : * endOfCComment - handles the end of C comment.
469 : */
470 :
471 0 : static void endOfCComment (void)
472 : {
473 0 : commentCLevel = 0;
474 0 : updatepos();
475 0 : skippos();
476 0 : BEGIN INITIAL;
477 0 : finishedLine();
478 0 : }
479 :
480 : /*
481 : * m2flex_M2Error - displays the error message, s, after the code line and pointer
482 : * to the erroneous token.
483 : */
484 :
485 24 : EXTERN void m2flex_M2Error (const char *s)
486 : {
487 24 : if (currentLine->linebuf != NULL) {
488 12 : int i=1;
489 :
490 12 : printf("%s:%d:%s\n", filename, currentLine->lineno, currentLine->linebuf);
491 12 : printf("%s:%d:%*s", filename, currentLine->lineno, 1+currentLine->tokenpos, "^");
492 60 : while (i<currentLine->toklen) {
493 36 : putchar('^');
494 36 : i++;
495 : }
496 12 : putchar('\n');
497 : }
498 24 : if (s == NULL)
499 0 : printf("%s:%d\n", filename, currentLine->lineno);
500 : else
501 24 : printf("%s:%d:%s\n", filename, currentLine->lineno, s);
502 24 : }
503 :
504 12 : static void poperrorskip (const char *s)
505 : {
506 12 : int nextpos =currentLine->nextpos;
507 12 : int tokenpos=currentLine->tokenpos;
508 :
509 12 : popLine();
510 12 : m2flex_M2Error(s);
511 12 : if (currentLine != NULL) {
512 12 : currentLine->nextpos = nextpos;
513 12 : currentLine->tokenpos = tokenpos;
514 : }
515 12 : }
516 :
517 : /* skipnewline skips all '\n' at the start of the line and returns
518 : the new position. */
519 :
520 : static
521 : char *
522 0 : skipnewline (char *line)
523 : {
524 0 : while (((*line) != (char)0) && ((*line) == '\n'))
525 0 : line++;
526 0 : return line;
527 : }
528 :
529 : /* traceLine display the source line providing -fdebug-trace-line was
530 : enabled. */
531 :
532 : static
533 : void
534 65921892 : traceLine (void)
535 : {
536 65921892 : if (M2Options_GetDebugTraceLine ())
537 : {
538 0 : char *line = skipnewline (currentLine->linebuf);
539 0 : if (filename == NULL)
540 0 : printf("<stdin>:%d:%s\n", currentLine->lineno, line);
541 : else
542 0 : printf("%s:%d:%s\n", filename, currentLine->lineno, line);
543 : }
544 65921892 : }
545 :
546 : /*
547 : * consumeLine - reads a line into a buffer, it then pushes back the whole
548 : * line except the initial \n.
549 : */
550 :
551 65921892 : static void consumeLine (void)
552 : {
553 65921892 : if (currentLine->linelen<yyleng) {
554 280062 : currentLine->linebuf = (char *)xrealloc (currentLine->linebuf, yyleng);
555 280062 : currentLine->linelen = yyleng;
556 : }
557 65921892 : strcpy(currentLine->linebuf, yytext+1); /* copy all except the initial \n */
558 65921892 : lineno++;
559 65921892 : totalLines++;
560 65921892 : currentLine->lineno = lineno;
561 65921892 : currentLine->tokenpos=0;
562 65921892 : currentLine->nextpos=0;
563 65921892 : currentLine->column=FIRST_COLUMN;
564 65921892 : START_LINE (lineno, yyleng);
565 65921892 : yyless(1); /* push back all but the \n */
566 65921892 : traceLine ();
567 65921892 : }
568 :
569 0 : static void assert_location (location_t location ATTRIBUTE_UNUSED)
570 : {
571 : #if 0
572 : if ((location != BUILTINS_LOCATION) && (location != UNKNOWN_LOCATION) && (! M2Options_GetCpp ())) {
573 : expanded_location xl = expand_location (location);
574 : if (xl.line != currentLine->lineno) {
575 : m2flex_M2Error ("mismatched gcc location and front end token number");
576 : }
577 : }
578 : #endif
579 0 : }
580 :
581 : /*
582 : * splitSlashStar - called if we are not tokenizing source code after it
583 : * has been preprocessed by cpp. It is only called
584 : * if the current token was a / immediately followed by * and
585 : * therefore it will be split into two m2 tokens: / and *.
586 : */
587 :
588 0 : static void splitSlashStar (void)
589 : {
590 0 : seenFunctionStart = false;
591 0 : seenEnd = false;
592 0 : seenModuleStart = false;
593 0 : currentLine->nextpos = currentLine->tokenpos+1; /* "/". */
594 0 : currentLine->toklen = 1;
595 0 : currentLine->column = currentLine->tokenpos+1;
596 0 : currentLine->location =
597 0 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
598 : currentLine->column+currentLine->toklen-1));
599 0 : assert_location (GET_LOCATION (currentLine->column,
600 : currentLine->column+currentLine->toklen-1));
601 0 : M2LexBuf_AddTok (M2Reserved_dividetok);
602 0 : currentLine->nextpos = currentLine->tokenpos+1; /* "*". */
603 0 : currentLine->toklen = 1;
604 0 : currentLine->column = currentLine->tokenpos+1;
605 0 : currentLine->location =
606 0 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
607 : currentLine->column+currentLine->toklen-1));
608 0 : assert_location (GET_LOCATION (currentLine->column,
609 : currentLine->column+currentLine->toklen-1));
610 0 : M2LexBuf_AddTok (M2Reserved_timestok);
611 0 : }
612 :
613 :
614 : /*
615 : * updatepos - updates the current token position.
616 : * Should be used when a rule matches a token.
617 : */
618 :
619 939111814 : static void updatepos (void)
620 : {
621 939111814 : seenFunctionStart = false;
622 939111814 : seenEnd = false;
623 939111814 : seenModuleStart = false;
624 939111814 : currentLine->nextpos = currentLine->tokenpos+yyleng;
625 939111814 : currentLine->toklen = yyleng;
626 939111814 : currentLine->column = currentLine->tokenpos+1;
627 2817335442 : currentLine->location =
628 939111814 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
629 : currentLine->column+currentLine->toklen-1));
630 939111814 : assert_location (GET_LOCATION (currentLine->column,
631 : currentLine->column+currentLine->toklen-1));
632 939111814 : }
633 :
634 : /*
635 : * checkFunction - checks to see whether we have seen the start
636 : * or end of a function.
637 : */
638 :
639 70426656 : static void checkFunction (void)
640 : {
641 70426656 : if (! isDefinitionModule) {
642 48127414 : if (seenModuleStart)
643 98198 : pushFunction(yytext, 1);
644 48127414 : if (seenFunctionStart)
645 1446743 : pushFunction(yytext, 0);
646 48127414 : if (seenEnd && currentFunction != NULL &&
647 1970872 : (strcmp(currentFunction->name, yytext) == 0))
648 1529822 : popFunction();
649 : }
650 70426656 : seenFunctionStart = false;
651 70426656 : seenEnd = false;
652 70426656 : seenModuleStart = false;
653 70426656 : }
654 :
655 : /*
656 : * skippos - skips over this token. This function should be called
657 : * if we are not returning and thus not calling getToken.
658 : */
659 :
660 746521818 : static void skippos (void)
661 : {
662 8795216 : currentLine->tokenpos = currentLine->nextpos;
663 737711675 : }
664 :
665 : /*
666 : * initLine - initializes a currentLine
667 : */
668 :
669 14951 : static void initLine (void)
670 : {
671 14951 : currentLine = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
672 :
673 14951 : if (currentLine == NULL)
674 : perror("xmalloc");
675 14951 : currentLine->linebuf = NULL;
676 14951 : currentLine->linelen = 0;
677 14951 : currentLine->tokenpos = 0;
678 14951 : currentLine->toklen = 0;
679 14951 : currentLine->nextpos = 0;
680 14951 : currentLine->lineno = lineno;
681 14951 : currentLine->column = FIRST_COLUMN;
682 14951 : currentLine->inuse = true;
683 14951 : currentLine->next = NULL;
684 14951 : }
685 :
686 : /*
687 : * pushLine - pushes a new line structure.
688 : */
689 :
690 4485587 : static void pushLine (void)
691 : {
692 4485587 : if (currentLine == NULL)
693 14951 : initLine();
694 4470636 : else if (currentLine->inuse) {
695 146068 : struct lineInfo *l = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
696 :
697 146068 : if (currentLine->linebuf == NULL) {
698 14408 : l->linebuf = NULL;
699 14408 : l->linelen = 0;
700 : } else {
701 131660 : l->linebuf = (char *)xstrdup (currentLine->linebuf);
702 131660 : l->linelen = strlen (l->linebuf)+1;
703 : }
704 146068 : l->tokenpos = currentLine->tokenpos;
705 146068 : l->toklen = currentLine->toklen;
706 146068 : l->nextpos = currentLine->nextpos;
707 146068 : l->lineno = currentLine->lineno;
708 146068 : l->column = currentLine->column;
709 146068 : l->next = currentLine;
710 146068 : currentLine = l;
711 : }
712 4485587 : currentLine->inuse = true;
713 4485587 : }
714 :
715 : /*
716 : * popLine - pops a line structure.
717 : */
718 :
719 131129 : static void popLine (void)
720 : {
721 131129 : if (currentLine != NULL) {
722 131129 : struct lineInfo *l = currentLine;
723 :
724 131129 : if (currentLine->linebuf != NULL)
725 131129 : free(currentLine->linebuf);
726 131129 : currentLine = l->next;
727 131129 : free(l);
728 : }
729 131129 : }
730 :
731 : /*
732 : * resetpos - resets the position of the next token to the start of the line.
733 : */
734 :
735 259866 : static void resetpos (void)
736 : {
737 6 : if (currentLine != NULL)
738 259866 : currentLine->nextpos = 0;
739 0 : }
740 :
741 : /*
742 : * finishedLine - indicates that the current line does not need to be
743 : * preserved when a pushLine occurs.
744 : */
745 :
746 4339507 : static void finishedLine (void)
747 : {
748 14927 : currentLine->inuse = false;
749 4324580 : }
750 :
751 : /*
752 : * m2flex_GetToken - returns a new token.
753 : */
754 :
755 192217149 : EXTERN char *m2flex_GetToken (void)
756 : {
757 192217149 : TIMEVAR_PUSH_LEX;
758 192217149 : if (currentLine == NULL)
759 0 : initLine();
760 192217149 : currentLine->tokenpos = currentLine->nextpos;
761 192217149 : yylex();
762 192217149 : TIMEVAR_POP_LEX;
763 192217149 : return yytext;
764 : }
765 :
766 : /*
767 : * CloseSource - provided for semantic sugar
768 : */
769 :
770 0 : EXTERN void m2flex_CloseSource (void)
771 : {
772 0 : END_FILE ();
773 0 : }
774 :
775 : /*
776 : * OpenSource - returns true if file s can be opened and
777 : * all tokens are taken from this file.
778 : */
779 :
780 259861 : EXTERN bool m2flex_OpenSource (char *s)
781 : {
782 259861 : FILE *f = fopen(s, "r");
783 :
784 259861 : if (f == NULL)
785 : return( false );
786 : else {
787 259860 : isDefinitionModule = false;
788 350241 : while (currentFunction != NULL)
789 : {
790 90381 : struct functionInfo *f = currentFunction;
791 90381 : currentFunction = f->next;
792 90381 : if (f->name != NULL)
793 90381 : free(f->name);
794 90381 : free(f);
795 : }
796 259860 : yy_delete_buffer (YY_CURRENT_BUFFER);
797 259860 : yy_switch_to_buffer (yy_create_buffer(f, YY_BUF_SIZE));
798 259860 : filename = xstrdup (s);
799 259860 : lineno = 1;
800 259860 : if (currentLine == NULL)
801 14951 : pushLine ();
802 : else
803 244909 : currentLine->lineno = lineno;
804 259860 : START_FILE (filename, lineno);
805 259860 : BEGIN INITIAL; resetpos ();
806 259860 : return true;
807 : }
808 : }
809 :
810 : /*
811 : * m2flex_GetLineNo - returns the current line number.
812 : */
813 :
814 192509293 : EXTERN int m2flex_GetLineNo (void)
815 : {
816 192509293 : if (currentLine == NULL)
817 : return 0;
818 : else
819 192509293 : return currentLine->lineno;
820 : }
821 :
822 : /*
823 : * m2flex_GetColumnNo - returns the column where the current
824 : * token starts.
825 : */
826 :
827 192563901 : EXTERN int m2flex_GetColumnNo (void)
828 : {
829 192563901 : if (currentLine == NULL)
830 : return FIRST_COLUMN;
831 : else
832 192563901 : return currentLine->column;
833 : }
834 :
835 : /*
836 : * m2flex_GetLocation - returns the gcc location_t of the current token.
837 : */
838 :
839 192217149 : EXTERN location_t m2flex_GetLocation (void)
840 : {
841 192217149 : if (currentLine == NULL)
842 : return 0;
843 : else
844 192217149 : return currentLine->location;
845 : }
846 :
847 : /*
848 : * GetTotalLines - returns the total number of lines parsed.
849 : */
850 :
851 0 : EXTERN int m2flex_GetTotalLines (void)
852 : {
853 0 : return totalLines;
854 : }
855 :
856 : /*
857 : * yywrap is called when end of file is seen. We push an eof token
858 : * and tell the lexical analysis to stop.
859 : */
860 :
861 244915 : int yywrap (void)
862 : {
863 244915 : updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return 1;
864 : }
865 :
866 0 : EXTERN void _M2_m2flex_init (void) {}
867 0 : EXTERN void _M2_m2flex_fini (void) {}
|