Branch data Line data Source code
1 : : %{
2 : : /* m2.flex implements lexical analysis for Modula-2.
3 : :
4 : : Copyright (C) 2004-2025 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 : 4464931 : "(*" { updatepos();
125 : 4464931 : commentLevel=1; pushLine(); skippos();
126 : 4464931 : BEGIN COMMENT; }
127 : 9074526 : <COMMENT>"*)" { endOfComment(); }
128 : 4754271 : <COMMENT>"(*" { commentLevel++; pushLine(); updatepos(); skippos(); }
129 : 4626514 : <COMMENT>"<*" { if (commentLevel == 1) {
130 : 161589 : updatepos();
131 : 33832 : pushLine();
132 : 16913 : skippos();
133 : 16913 : BEGIN COMMENT1;
134 : : } else {
135 : 6 : updatepos(); skippos();
136 : : }
137 : : }
138 : 18618905 : <COMMENT>\n.* { consumeLine(); }
139 : 786253815 : <COMMENT>. { updatepos(); skippos(); }
140 : 169130 : <COMMENT1>. { updatepos(); skippos(); }
141 : 786270728 : <COMMENT1>"*>" { updatepos(); skippos(); finishedLine(); BEGIN COMMENT; }
142 : 169130 : <COMMENT1>\n.* { consumeLine(); }
143 : 16913 : <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 : 18254 : ^\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
167 : 18254 : if (M2Options_GetLineDirectives ())
168 : 36508 : BEGIN LINE0;
169 : : }
170 : 14695 : \n\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
171 : 14695 : if (M2Options_GetLineDirectives ())
172 : 14695 : BEGIN LINE0;
173 : 14695 : }
174 : 14695 : <LINE0>\#[ \t]* { updatepos(); }
175 : 47644 : <LINE0>[0-9]+[ \t]*\" { updatepos(); lineno=atoi(yytext); BEGIN LINE1; }
176 : 47644 : <LINE0>\n { m2flex_M2Error("missing initial quote after #line directive"); resetpos(); BEGIN INITIAL; }
177 : 32949 : <LINE0>[^\n]
178 : 0 : <LINE1>[^\"\n]+ { m2flex_M2Error("missing final quote after #line directive"); resetpos(); BEGIN INITIAL; }
179 : 51203 : <LINE1>.*\" { updatepos();
180 : 32949 : filename = (char *)xrealloc(filename, yyleng+1);
181 : 32949 : strcpy(filename, yytext);
182 : 32949 : filename[yyleng-1] = (char)0; /* remove trailing quote */
183 : 32949 : START_FILE (filename, lineno);
184 : 32949 : BEGIN LINE2;
185 : : }
186 : 32949 : <LINE2>[ \t]* { updatepos(); }
187 : 32949 : <LINE2>\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
188 : 36345 : <LINE2>2[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
189 : 3396 : <LINE2>1[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
190 : 19365 : <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 : 48634570 : \n { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
196 : 48881911 :
197 : 455070 : \"[^\"\n]*\" { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
198 : 712599 : \"[^\"\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 : 998489 : '[^'\n]*' { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
205 : 998495 : '[^'\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 : 257990 : <<EOF>> { updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return; }
212 : 437489 : \+ { updatepos(); M2LexBuf_AddTok(M2Reserved_plustok); return; }
213 : 419524 : - { updatepos(); M2LexBuf_AddTok(M2Reserved_minustok); return; }
214 : 561074 : "*" { updatepos(); M2LexBuf_AddTok(M2Reserved_timestok); return; }
215 : 691726 : \/ { updatepos(); M2LexBuf_AddTok(M2Reserved_dividetok); return; }
216 : 3940316 : := { updatepos(); M2LexBuf_AddTok(M2Reserved_becomestok); return; }
217 : 14212 : \& { updatepos(); M2LexBuf_AddTok(M2Reserved_ambersandtok); return; }
218 : 6456242 : \. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodtok); return; }
219 : 11850719 : \, { updatepos(); M2LexBuf_AddTok(M2Reserved_commatok); return; }
220 : 22121774 : \; { updatepos(); M2LexBuf_AddTok(M2Reserved_semicolontok); return; }
221 : 26968707 : \( { updatepos(); M2LexBuf_AddTok(M2Reserved_lparatok); return; }
222 : 34600257 : \) { updatepos(); M2LexBuf_AddTok(M2Reserved_rparatok); return; }
223 : 16252367 : \[ { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
224 : 16252347 : \] { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
225 : 1134379 : \(\! { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
226 : 1134353 : \!\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
227 : 1350131 : \^ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
228 : 0 : \@ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
229 : 1386937 : \{ { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
230 : 36806 : \} { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
231 : 36806 : \(\: { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
232 : 36806 : \:\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
233 : 0 : \' { updatepos(); M2LexBuf_AddTok(M2Reserved_singlequotetok); return; }
234 : 1366175 : \= { updatepos(); M2LexBuf_AddTok(M2Reserved_equaltok); return; }
235 : 561055 : \# { updatepos(); M2LexBuf_AddTok(M2Reserved_hashtok); return; }
236 : 1796762 : \< { updatepos(); M2LexBuf_AddTok(M2Reserved_lesstok); return; }
237 : 839339 : \> { updatepos(); M2LexBuf_AddTok(M2Reserved_greatertok); return; }
238 : 430671 : \<\> { updatepos(); M2LexBuf_AddTok(M2Reserved_lessgreatertok); return; }
239 : 504462 : \<\= { updatepos(); M2LexBuf_AddTok(M2Reserved_lessequaltok); return; }
240 : 113298 : \>\= { updatepos(); M2LexBuf_AddTok(M2Reserved_greaterequaltok); return; }
241 : 759436 : "<*" { updatepos(); M2LexBuf_AddTok(M2Reserved_ldirectivetok); return; }
242 : 646472 : "*>" { updatepos(); M2LexBuf_AddTok(M2Reserved_rdirectivetok); return; }
243 : 636825 : \.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodtok); return; }
244 : 544662 : \.\.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodperiodtok); return; }
245 : 13611478 : \: { updatepos(); M2LexBuf_AddTok(M2Reserved_colontok); return; }
246 : 11404 : \" { updatepos(); M2LexBuf_AddTok(M2Reserved_doublequotestok); return; }
247 : 13581625 : \| { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
248 : 0 : \! { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
249 : 73714 : \~ { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
250 : 442618 : AND { updatepos(); M2LexBuf_AddTok(M2Reserved_andtok); return; }
251 : 1186903 : ARRAY { updatepos(); M2LexBuf_AddTok(M2Reserved_arraytok); return; }
252 : 2364951 : BEGIN { updatepos(); M2LexBuf_AddTok(M2Reserved_begintok); return; }
253 : 1187299 : BY { updatepos(); M2LexBuf_AddTok(M2Reserved_bytok); return; }
254 : 1967398 : CASE { updatepos(); M2LexBuf_AddTok(M2Reserved_casetok); return; }
255 : 73112 : CONST { updatepos(); M2LexBuf_AddTok(M2Reserved_consttok); return; }
256 : 218388 : DEFINITION { updatepos(); isDefinitionModule = true;
257 : 246039 : M2LexBuf_AddTok(M2Reserved_definitiontok); return; }
258 : 259143 : DIV { updatepos(); M2LexBuf_AddTok(M2Reserved_divtok); return; }
259 : 621202 : DO { updatepos(); M2LexBuf_AddTok(M2Reserved_dotok); return; }
260 : 889331 : ELSE { updatepos(); M2LexBuf_AddTok(M2Reserved_elsetok); return; }
261 : 765946 : ELSIF { updatepos(); M2LexBuf_AddTok(M2Reserved_elsiftok); return; }
262 : 5626707 : END { updatepos(); seenEnd=true;
263 : 4967940 : M2LexBuf_AddTok(M2Reserved_endtok); return; }
264 : 4823430 : EXCEPT { updatepos(); M2LexBuf_AddTok(M2Reserved_excepttok); return; }
265 : 106 : EXIT { updatepos(); M2LexBuf_AddTok(M2Reserved_exittok); return; }
266 : 91561 : EXPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_exporttok); return; }
267 : 6066 : FINALLY { updatepos(); M2LexBuf_AddTok(M2Reserved_finallytok); return; }
268 : 148201 : FOR { updatepos(); M2LexBuf_AddTok(M2Reserved_fortok); return; }
269 : 6020 : FORWARD { updatepos(); M2LexBuf_AddTok(M2Reserved_forwardtok); return; }
270 : 417543 : FROM { updatepos(); M2LexBuf_AddTok(M2Reserved_fromtok); return; }
271 : 1932871 : IF { updatepos(); M2LexBuf_AddTok(M2Reserved_iftok); return; }
272 : 438693 : IMPLEMENTATION { updatepos(); M2LexBuf_AddTok(M2Reserved_implementationtok); return; }
273 : 2342785 : IMPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_importtok); return; }
274 : 161356 : IN { updatepos(); M2LexBuf_AddTok(M2Reserved_intok); return; }
275 : 418703 : LOOP { updatepos(); M2LexBuf_AddTok(M2Reserved_looptok); return; }
276 : 215898 : MOD { updatepos(); M2LexBuf_AddTok(M2Reserved_modtok); return; }
277 : 284082 : MODULE { updatepos(); seenModuleStart=true;
278 : 407919 : M2LexBuf_AddTok(M2Reserved_moduletok); return; }
279 : 411761 : NOT { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
280 : 1236787 : OF { updatepos(); M2LexBuf_AddTok(M2Reserved_oftok); return; }
281 : 287286 : OR { updatepos(); M2LexBuf_AddTok(M2Reserved_ortok); return; }
282 : 1239613 : PACKEDSET { updatepos(); M2LexBuf_AddTok(M2Reserved_packedsettok); return; }
283 : 252854 : POINTER { updatepos(); M2LexBuf_AddTok(M2Reserved_pointertok); return; }
284 : 5402354 : PROCEDURE { updatepos(); seenFunctionStart=true;
285 : 5501504 : M2LexBuf_AddTok(M2Reserved_proceduretok); return; }
286 : 5478911 : QUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_qualifiedtok); return; }
287 : 11650 : UNQUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_unqualifiedtok); return; }
288 : 151640 : RECORD { updatepos(); M2LexBuf_AddTok(M2Reserved_recordtok); return; }
289 : 11746 : REM { updatepos(); M2LexBuf_AddTok(M2Reserved_remtok); return; }
290 : 144024 : REPEAT { updatepos(); M2LexBuf_AddTok(M2Reserved_repeattok); return; }
291 : 270 : RETRY { updatepos(); M2LexBuf_AddTok(M2Reserved_retrytok); return; }
292 : 1514762 : RETURN { updatepos(); M2LexBuf_AddTok(M2Reserved_returntok); return; }
293 : 2161 : SET { updatepos(); M2LexBuf_AddTok(M2Reserved_settok); return; }
294 : 3520550 : THEN { updatepos(); M2LexBuf_AddTok(M2Reserved_thentok); return; }
295 : 147595 : TO { updatepos(); M2LexBuf_AddTok(M2Reserved_totok); return; }
296 : 2198772 : TYPE { updatepos(); M2LexBuf_AddTok(M2Reserved_typetok); return; }
297 : 217375 : UNTIL { updatepos(); M2LexBuf_AddTok(M2Reserved_untiltok); return; }
298 : 1739764 : VAR { updatepos(); M2LexBuf_AddTok(M2Reserved_vartok); return; }
299 : 452720 : WHILE { updatepos(); M2LexBuf_AddTok(M2Reserved_whiletok); return; }
300 : 1815158 : WITH { updatepos(); M2LexBuf_AddTok(M2Reserved_withtok); return; }
301 : 380980 : ASM { updatepos(); M2LexBuf_AddTok(M2Reserved_asmtok); return; }
302 : 196626 : VOLATILE { updatepos(); M2LexBuf_AddTok(M2Reserved_volatiletok); return; }
303 : 27 : \_\_DATE\_\_ { updatepos(); handleDate(); return; }
304 : 128023 : \_\_LINE\_\_ { updatepos(); handleLine(); return; }
305 : 124456 : \_\_FILE\_\_ { updatepos(); handleFile(); return; }
306 : 250742 : \_\_FUNCTION\_\_ { updatepos(); handleFunction(); return; }
307 : 178968 : \_\_COLUMN\_\_ { updatepos(); handleColumn(); return; }
308 : 596444 : \_\_ATTRIBUTE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_attributetok); return; }
309 : 967842 : \_\_BUILTIN\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_builtintok); return; }
310 : 473710 : \_\_INLINE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_inlinetok); return; }
311 : 913330 :
312 : 0 :
313 : 28934 : (([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 : 71669915 : [a-zA-Z_][a-zA-Z0-9_]* { checkFunction(); updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_identtok, yytext); return; }
316 : 2416606 : [0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
317 : 71669939 : [0-1]+A { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
318 : 2419340 : [0-9]+B { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
319 : 136147 : [0-9]+C { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
320 : 14242 : [0-9A-F]+H { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
321 : 136123 : [\t\r ]+ { currentLine->tokenpos += yyleng; /* Ignore space. */; }
322 : 112575278 : . { updatepos(); m2flex_M2Error("unrecognised symbol"); skippos(); }
323 : 112563776 :
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 : 124456 : static void handleFile (void)
338 : : {
339 : 124456 : char *s = (char *)alloca(strlen(filename)+2+1);
340 : :
341 : 124456 : strcpy(s, "\"");
342 : 124456 : strcat(s, filename);
343 : 124456 : strcat(s, "\"");
344 : 124456 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
345 : 124456 : }
346 : :
347 : : /*
348 : : * handleLine - handles the __LINE__ construct by passing an integer to
349 : : * the token buffer.
350 : : */
351 : :
352 : 128008 : static void handleLine (void)
353 : : {
354 : 128008 : M2LexBuf_AddTokInteger(M2Reserved_integertok, lineno);
355 : 128008 : }
356 : :
357 : : /*
358 : : * handleColumn - handles the __COLUMN__ construct by passing an integer to
359 : : * the token buffer.
360 : : */
361 : :
362 : 54512 : static void handleColumn (void)
363 : : {
364 : 54512 : M2LexBuf_AddTokInteger(M2Reserved_integertok, m2flex_GetColumnNo());
365 : 54512 : }
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 : 122734 : static void handleFunction (void)
395 : : {
396 : 122734 : if (currentFunction == NULL)
397 : 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, const_cast<char *>("\"\""));
398 : 122734 : 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 : 122728 : char *function = currentFunction->name;
407 : 122728 : char *s = (char *)alloca(strlen(function)+2+1);
408 : 122728 : strcpy(s, "\"");
409 : 122728 : strcat(s, function);
410 : 122728 : strcat(s, "\"");
411 : 122728 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
412 : : }
413 : 122734 : }
414 : :
415 : : /*
416 : : * pushFunction - pushes the function name onto the stack.
417 : : */
418 : :
419 : 1546770 : static void pushFunction (char *function, bool module)
420 : : {
421 : 1546770 : if (currentFunction == NULL) {
422 : 101604 : currentFunction = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
423 : 101604 : currentFunction->name = xstrdup(function);
424 : 101604 : currentFunction->next = NULL;
425 : 101604 : currentFunction->module = module;
426 : : } else {
427 : 1445166 : struct functionInfo *f = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
428 : 1445166 : f->name = xstrdup(function);
429 : 1445166 : f->next = currentFunction;
430 : 1445166 : f->module = module;
431 : 1445166 : currentFunction = f;
432 : : }
433 : 1546770 : }
434 : :
435 : : /*
436 : : * popFunction - pops the current function.
437 : : */
438 : :
439 : 1529665 : static void popFunction (void)
440 : : {
441 : 1529665 : if (currentFunction != NULL && currentFunction->next != NULL) {
442 : 1445088 : struct functionInfo *f = currentFunction;
443 : :
444 : 1445088 : currentFunction = currentFunction->next;
445 : 1445088 : if (f->name != NULL)
446 : 1445088 : free(f->name);
447 : 1445088 : free(f);
448 : : }
449 : 1529665 : }
450 : :
451 : : /*
452 : : * endOfComment - handles the end of comment
453 : : */
454 : :
455 : 4609595 : static void endOfComment (void)
456 : : {
457 : 4609595 : commentLevel--;
458 : 4609595 : updatepos();
459 : 4609595 : skippos();
460 : 4609595 : if (commentLevel==0) {
461 : 4464919 : BEGIN INITIAL;
462 : 4464919 : finishedLine();
463 : : } else
464 : 144676 : popLine();
465 : 4609595 : }
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 : 67533765 : traceLine (void)
535 : : {
536 : 67533765 : 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 : 67533765 : }
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 : 67533765 : static void consumeLine (void)
552 : : {
553 : 67533765 : if (currentLine->linelen<yyleng) {
554 : 313400 : currentLine->linebuf = (char *)xrealloc (currentLine->linebuf, yyleng);
555 : 313400 : currentLine->linelen = yyleng;
556 : : }
557 : 67533765 : strcpy(currentLine->linebuf, yytext+1); /* copy all except the initial \n */
558 : 67533765 : lineno++;
559 : 67533765 : totalLines++;
560 : 67533765 : currentLine->lineno = lineno;
561 : 67533765 : currentLine->tokenpos=0;
562 : 67533765 : currentLine->nextpos=0;
563 : 67533765 : currentLine->column=FIRST_COLUMN;
564 : 67533765 : START_LINE (lineno, yyleng);
565 : 67533765 : yyless(1); /* push back all but the \n */
566 : 67533765 : traceLine ();
567 : 67533765 : }
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 : 972769785 : static void updatepos (void)
620 : : {
621 : 972769785 : seenFunctionStart = false;
622 : 972769785 : seenEnd = false;
623 : 972769785 : seenModuleStart = false;
624 : 972769785 : currentLine->nextpos = currentLine->tokenpos+yyleng;
625 : 972769785 : currentLine->toklen = yyleng;
626 : 972769785 : currentLine->column = currentLine->tokenpos+1;
627 : 2918309355 : currentLine->location =
628 : 972769785 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
629 : : currentLine->column+currentLine->toklen-1));
630 : 972769785 : assert_location (GET_LOCATION (currentLine->column,
631 : : currentLine->column+currentLine->toklen-1));
632 : 972769785 : }
633 : :
634 : : /*
635 : : * checkFunction - checks to see whether we have seen the start
636 : : * or end of a function.
637 : : */
638 : :
639 : 71669915 : static void checkFunction (void)
640 : : {
641 : 71669915 : if (! isDefinitionModule) {
642 : 48075911 : if (seenModuleStart)
643 : 102030 : pushFunction(yytext, 1);
644 : 48075911 : if (seenFunctionStart)
645 : 1444740 : pushFunction(yytext, 0);
646 : 48075911 : if (seenEnd && currentFunction != NULL &&
647 : 1969809 : (strcmp(currentFunction->name, yytext) == 0))
648 : 1529665 : popFunction();
649 : : }
650 : 71669915 : seenFunctionStart = false;
651 : 71669915 : seenEnd = false;
652 : 71669915 : seenModuleStart = false;
653 : 71669915 : }
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 : 777057074 : static void skippos (void)
661 : : {
662 : 9091439 : currentLine->tokenpos = currentLine->nextpos;
663 : 767948722 : }
664 : :
665 : : /*
666 : : * initLine - initializes a currentLine
667 : : */
668 : :
669 : 16937 : static void initLine (void)
670 : : {
671 : 16937 : currentLine = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
672 : :
673 : 16937 : if (currentLine == NULL)
674 : : perror("xmalloc");
675 : 16937 : currentLine->linebuf = NULL;
676 : 16937 : currentLine->linelen = 0;
677 : 16937 : currentLine->tokenpos = 0;
678 : 16937 : currentLine->toklen = 0;
679 : 16937 : currentLine->nextpos = 0;
680 : 16937 : currentLine->lineno = lineno;
681 : 16937 : currentLine->column = FIRST_COLUMN;
682 : 16937 : currentLine->inuse = true;
683 : 16937 : currentLine->next = NULL;
684 : 16937 : }
685 : :
686 : : /*
687 : : * pushLine - pushes a new line structure.
688 : : */
689 : :
690 : 4643457 : static void pushLine (void)
691 : : {
692 : 4643457 : if (currentLine == NULL)
693 : 16937 : initLine();
694 : 4626520 : else if (currentLine->inuse) {
695 : 161613 : struct lineInfo *l = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
696 : :
697 : 161613 : if (currentLine->linebuf == NULL) {
698 : 16401 : l->linebuf = NULL;
699 : 16401 : l->linelen = 0;
700 : : } else {
701 : 145212 : l->linebuf = (char *)xstrdup (currentLine->linebuf);
702 : 145212 : l->linelen = strlen (l->linebuf)+1;
703 : : }
704 : 161613 : l->tokenpos = currentLine->tokenpos;
705 : 161613 : l->toklen = currentLine->toklen;
706 : 161613 : l->nextpos = currentLine->nextpos;
707 : 161613 : l->lineno = currentLine->lineno;
708 : 161613 : l->column = currentLine->column;
709 : 161613 : l->next = currentLine;
710 : 161613 : currentLine = l;
711 : : }
712 : 4643457 : currentLine->inuse = true;
713 : 4643457 : }
714 : :
715 : : /*
716 : : * popLine - pops a line structure.
717 : : */
718 : :
719 : 144688 : static void popLine (void)
720 : : {
721 : 144688 : if (currentLine != NULL) {
722 : 144688 : struct lineInfo *l = currentLine;
723 : :
724 : 144688 : if (currentLine->linebuf != NULL)
725 : 144688 : free(currentLine->linebuf);
726 : 144688 : currentLine = l->next;
727 : 144688 : free(l);
728 : : }
729 : 144688 : }
730 : :
731 : : /*
732 : : * resetpos - resets the position of the next token to the start of the line.
733 : : */
734 : :
735 : 274939 : static void resetpos (void)
736 : : {
737 : 6 : if (currentLine != NULL)
738 : 274939 : 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 : 4481832 : static void finishedLine (void)
747 : : {
748 : 16913 : currentLine->inuse = false;
749 : 4464919 : }
750 : :
751 : : /*
752 : : * m2flex_GetToken - returns a new token.
753 : : */
754 : :
755 : 195324187 : EXTERN char *m2flex_GetToken (void)
756 : : {
757 : 195324187 : TIMEVAR_PUSH_LEX;
758 : 195324187 : if (currentLine == NULL)
759 : 0 : initLine();
760 : 195324187 : currentLine->tokenpos = currentLine->nextpos;
761 : 195324187 : yylex();
762 : 195324187 : TIMEVAR_POP_LEX;
763 : 195324187 : 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 : 274934 : EXTERN bool m2flex_OpenSource (char *s)
781 : : {
782 : 274934 : FILE *f = fopen(s, "r");
783 : :
784 : 274934 : if (f == NULL)
785 : : return( false );
786 : : else {
787 : 274933 : isDefinitionModule = false;
788 : 367325 : while (currentFunction != NULL)
789 : : {
790 : 92392 : struct functionInfo *f = currentFunction;
791 : 92392 : currentFunction = f->next;
792 : 92392 : if (f->name != NULL)
793 : 92392 : free(f->name);
794 : 92392 : free(f);
795 : : }
796 : 274933 : yy_delete_buffer (YY_CURRENT_BUFFER);
797 : 274933 : yy_switch_to_buffer (yy_create_buffer(f, YY_BUF_SIZE));
798 : 274933 : filename = xstrdup (s);
799 : 274933 : lineno = 1;
800 : 274933 : if (currentLine == NULL)
801 : 16937 : pushLine ();
802 : : else
803 : 257996 : currentLine->lineno = lineno;
804 : 274933 : START_FILE (filename, lineno);
805 : 274933 : BEGIN INITIAL; resetpos ();
806 : 274933 : return true;
807 : : }
808 : : }
809 : :
810 : : /*
811 : : * m2flex_GetLineNo - returns the current line number.
812 : : */
813 : :
814 : 195632069 : EXTERN int m2flex_GetLineNo (void)
815 : : {
816 : 195632069 : if (currentLine == NULL)
817 : : return 0;
818 : : else
819 : 195632069 : return currentLine->lineno;
820 : : }
821 : :
822 : : /*
823 : : * m2flex_GetColumnNo - returns the column where the current
824 : : * token starts.
825 : : */
826 : :
827 : 195686581 : EXTERN int m2flex_GetColumnNo (void)
828 : : {
829 : 195686581 : if (currentLine == NULL)
830 : : return FIRST_COLUMN;
831 : : else
832 : 195686581 : return currentLine->column;
833 : : }
834 : :
835 : : /*
836 : : * m2flex_GetLocation - returns the gcc location_t of the current token.
837 : : */
838 : :
839 : 195324187 : EXTERN location_t m2flex_GetLocation (void)
840 : : {
841 : 195324187 : if (currentLine == NULL)
842 : : return 0;
843 : : else
844 : 195324187 : 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 : 258002 : int yywrap (void)
862 : : {
863 : 258002 : 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) {}
|