Branch data Line data Source code
1 : : %{
2 : : /* m2.flex implements lexical analysis for Modula-2.
3 : :
4 : : Copyright (C) 2004-2024 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 : :
30 : : static int cpreprocessor = 0; /* Replace this with correct getter. */
31 : :
32 : : #if defined(GM2USEGGC)
33 : : # include "ggc.h"
34 : : #endif
35 : :
36 : : #include "timevar.h"
37 : :
38 : : #define START_FILE(F,L) m2linemap_StartFile(F,L)
39 : : #define END_FILE() m2linemap_EndFile()
40 : : #define START_LINE(N,S) m2linemap_StartLine(N,S)
41 : : #define GET_LOCATION(COLUMN_START,COLUMN_END) \
42 : : m2linemap_GetLocationRange(COLUMN_START,COLUMN_END)
43 : : #define TIMEVAR_PUSH_LEX timevar_push (TV_LEX)
44 : : #define TIMEVAR_POP_LEX timevar_pop (TV_LEX)
45 : :
46 : : #ifdef __cplusplus
47 : : #define EXTERN extern "C"
48 : : #endif
49 : :
50 : : /* m2.flex provides a lexical analyser for GNU Modula-2. */
51 : :
52 : : struct lineInfo {
53 : : char *linebuf; /* line contents */
54 : : int linelen; /* length */
55 : : int tokenpos; /* start position of token within line */
56 : : int toklen; /* a copy of yylen (length of token) */
57 : : int nextpos; /* position after token */
58 : : int lineno; /* line number of this line */
59 : : int column; /* first column number of token on this line */
60 : : bool inuse; /* do we need to keep this line info? */
61 : : location_t location; /* the corresponding gcc location_t */
62 : : struct lineInfo *next;
63 : : };
64 : :
65 : : struct functionInfo {
66 : : char *name; /* function name */
67 : : bool module; /* is it really a module? */
68 : : struct functionInfo *next; /* list of nested functions */
69 : : };
70 : :
71 : : static int lineno =1; /* a running count of the file line number */
72 : : static char *filename =NULL;
73 : : static int commentLevel=0;
74 : : static int commentCLevel=0;
75 : : static struct lineInfo *currentLine=NULL;
76 : : static struct functionInfo *currentFunction=NULL;
77 : : static bool seenFunctionStart=false;
78 : : static bool seenEnd=false;
79 : : static bool seenModuleStart=false;
80 : : static bool isDefinitionModule=false;
81 : : static int totalLines=0;
82 : :
83 : : static void pushLine (void);
84 : : static void popLine (void);
85 : : static void finishedLine (void);
86 : : static void resetpos (void);
87 : : static void consumeLine (void);
88 : : static void updatepos (void);
89 : : static void skippos (void);
90 : : static void poperrorskip (const char *);
91 : : static void endOfComment (void);
92 : : static void endOfCComment (void);
93 : : static void splitSlashStar (void);
94 : : static void handleDate (void);
95 : : static void handleLine (void);
96 : : static void handleFile (void);
97 : : static void handleFunction (void);
98 : : static void handleColumn (void);
99 : : static void pushFunction (char *function, bool module);
100 : : static void popFunction (void);
101 : : static void checkFunction (void);
102 : : EXTERN void m2flex_M2Error (const char *);
103 : : EXTERN location_t m2flex_GetLocation (void);
104 : : EXTERN int m2flex_GetColumnNo (void);
105 : : EXTERN bool m2flex_OpenSource (char *s);
106 : : EXTERN int m2flex_GetLineNo (void);
107 : : EXTERN void m2flex_CloseSource (void);
108 : : EXTERN char *m2flex_GetToken (void);
109 : : EXTERN void _M2_m2flex_init (void);
110 : : EXTERN int m2flex_GetTotalLines (void);
111 : : extern void yylex (void);
112 : :
113 : : #define YY_DECL void yylex (void)
114 : : %}
115 : :
116 : : %option nounput
117 : : %x COMMENT COMMENT1 COMMENTC LINE0 LINE1 LINE2
118 : :
119 : : %%
120 : :
121 : 2863530 : "(*" { updatepos();
122 : 2863530 : commentLevel=1; pushLine(); skippos();
123 : 2863530 : BEGIN COMMENT; }
124 : 5865267 : <COMMENT>"*)" { endOfComment(); }
125 : 3139944 : <COMMENT>"(*" { commentLevel++; pushLine(); updatepos(); skippos(); }
126 : 3018535 : <COMMENT>"<*" { if (commentLevel == 1) {
127 : 154999 : updatepos();
128 : 33590 : pushLine();
129 : 16792 : skippos();
130 : 16792 : BEGIN COMMENT1;
131 : : } else {
132 : 6 : updatepos(); skippos();
133 : : }
134 : : }
135 : 13026665 : <COMMENT>\n.* { consumeLine(); }
136 : 555434088 : <COMMENT>. { updatepos(); skippos(); }
137 : 167920 : <COMMENT1>. { updatepos(); skippos(); }
138 : 555450880 : <COMMENT1>"*>" { updatepos(); skippos(); finishedLine(); BEGIN COMMENT; }
139 : 167920 : <COMMENT1>\n.* { consumeLine(); }
140 : 16792 : <COMMENT1>"*)" { poperrorskip("unterminated source code directive, missing *>");
141 : 0 : endOfComment(); }
142 : 0 : <COMMENT1><<EOF>> { poperrorskip("unterminated source code directive, missing *>"); BEGIN COMMENT; }
143 : 0 : <COMMENT><<EOF>> { poperrorskip("unterminated comment found at the end of the file, missing *)"); BEGIN INITIAL; }
144 : 0 :
145 : 0 : "/*" { /* Possibly handle C preprocessor comment. */
146 : 0 : if (cpreprocessor)
147 : : {
148 : 0 : updatepos ();
149 : 0 : commentCLevel++;
150 : 0 : if (commentCLevel == 1)
151 : : {
152 : 0 : pushLine ();
153 : 0 : skippos ();
154 : : }
155 : 0 : BEGIN COMMENTC;
156 : : }
157 : : else
158 : 0 : splitSlashStar ();
159 : : }
160 : 0 : <COMMENTC>. { updatepos(); skippos(); }
161 : 0 : <COMMENTC>\n.* { consumeLine(); }
162 : 0 : <COMMENTC>"*/" { endOfCComment(); }
163 : 13866 : ^\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
164 : 13866 : if (M2Options_GetLineDirectives ())
165 : 27732 : BEGIN LINE0;
166 : : }
167 : 11869 : \n\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
168 : 11869 : if (M2Options_GetLineDirectives ())
169 : 11869 : BEGIN LINE0;
170 : 11869 : }
171 : 11869 : <LINE0>\#[ \t]* { updatepos(); }
172 : 37604 : <LINE0>[0-9]+[ \t]*\" { updatepos(); lineno=atoi(yytext); BEGIN LINE1; }
173 : 37604 : <LINE0>\n { m2flex_M2Error("missing initial quote after #line directive"); resetpos(); BEGIN INITIAL; }
174 : 25735 : <LINE0>[^\n]
175 : 0 : <LINE1>[^\"\n]+ { m2flex_M2Error("missing final quote after #line directive"); resetpos(); BEGIN INITIAL; }
176 : 39601 : <LINE1>.*\" { updatepos();
177 : 25735 : filename = (char *)xrealloc(filename, yyleng+1);
178 : 25735 : strcpy(filename, yytext);
179 : 25735 : filename[yyleng-1] = (char)0; /* remove trailing quote */
180 : 25735 : START_FILE (filename, lineno);
181 : 25735 : BEGIN LINE2;
182 : : }
183 : 25735 : <LINE2>[ \t]* { updatepos(); }
184 : 25735 : <LINE2>\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
185 : 28297 : <LINE2>2[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
186 : 2562 : <LINE2>1[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
187 : 15487 : <LINE2>1[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
188 : 5124 : <LINE2>2[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
189 : 7686 : <LINE2>3[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
190 : 10248 :
191 : 0 : \n[^\#].* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
192 : 27963116 : \n { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
193 : 28144075 :
194 : 289115 : \"[^\"\n]*\" { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
195 : 477760 : \"[^\"\n]*$ { updatepos();
196 : 0 : m2flex_M2Error("missing terminating quote, \"");
197 : 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext);
198 : 0 : resetpos(); return;
199 : 0 : }
200 : 0 :
201 : 427048 : '[^'\n]*' { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
202 : 427054 : '[^'\n]*$ { updatepos();
203 : 6 : m2flex_M2Error("missing terminating quote, '");
204 : 6 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext);
205 : 12 : resetpos(); return;
206 : 6 : }
207 : 6 :
208 : 188967 : <<EOF>> { updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return; }
209 : 171895 : \+ { updatepos(); M2LexBuf_AddTok(M2Reserved_plustok); return; }
210 : 175082 : - { updatepos(); M2LexBuf_AddTok(M2Reserved_minustok); return; }
211 : 237794 : "*" { updatepos(); M2LexBuf_AddTok(M2Reserved_timestok); return; }
212 : 364987 : \/ { updatepos(); M2LexBuf_AddTok(M2Reserved_dividetok); return; }
213 : 2016861 : := { updatepos(); M2LexBuf_AddTok(M2Reserved_becomestok); return; }
214 : 938 : \& { updatepos(); M2LexBuf_AddTok(M2Reserved_ambersandtok); return; }
215 : 3195845 : \. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodtok); return; }
216 : 7383886 : \, { updatepos(); M2LexBuf_AddTok(M2Reserved_commatok); return; }
217 : 12522274 : \; { updatepos(); M2LexBuf_AddTok(M2Reserved_semicolontok); return; }
218 : 14715771 : \( { updatepos(); M2LexBuf_AddTok(M2Reserved_lparatok); return; }
219 : 18609276 : \) { updatepos(); M2LexBuf_AddTok(M2Reserved_rparatok); return; }
220 : 8119295 : \[ { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
221 : 8119269 : \] { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
222 : 787410 : \(\! { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
223 : 787384 : \!\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
224 : 691878 : \^ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
225 : 0 : \@ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
226 : 712376 : \{ { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
227 : 20498 : \} { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
228 : 20498 : \(\: { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
229 : 20498 : \:\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
230 : 0 : \' { updatepos(); M2LexBuf_AddTok(M2Reserved_singlequotetok); return; }
231 : 911426 : \= { updatepos(); M2LexBuf_AddTok(M2Reserved_equaltok); return; }
232 : 342425 : \# { updatepos(); M2LexBuf_AddTok(M2Reserved_hashtok); return; }
233 : 1103279 : \< { updatepos(); M2LexBuf_AddTok(M2Reserved_lesstok); return; }
234 : 485689 : \> { updatepos(); M2LexBuf_AddTok(M2Reserved_greatertok); return; }
235 : 191937 : \<\> { updatepos(); M2LexBuf_AddTok(M2Reserved_lessgreatertok); return; }
236 : 281702 : \<\= { updatepos(); M2LexBuf_AddTok(M2Reserved_lessequaltok); return; }
237 : 51824 : \>\= { updatepos(); M2LexBuf_AddTok(M2Reserved_greaterequaltok); return; }
238 : 663204 : "<*" { updatepos(); M2LexBuf_AddTok(M2Reserved_ldirectivetok); return; }
239 : 576506 : "*>" { updatepos(); M2LexBuf_AddTok(M2Reserved_rdirectivetok); return; }
240 : 605499 : \.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodtok); return; }
241 : 540304 : \.\.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodperiodtok); return; }
242 : 7199553 : \: { updatepos(); M2LexBuf_AddTok(M2Reserved_colontok); return; }
243 : 15538 : \" { updatepos(); M2LexBuf_AddTok(M2Reserved_doublequotestok); return; }
244 : 7129090 : \| { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
245 : 0 : \! { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
246 : 10270 : \~ { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
247 : 239462 : AND { updatepos(); M2LexBuf_AddTok(M2Reserved_andtok); return; }
248 : 600080 : ARRAY { updatepos(); M2LexBuf_AddTok(M2Reserved_arraytok); return; }
249 : 1168302 : BEGIN { updatepos(); M2LexBuf_AddTok(M2Reserved_begintok); return; }
250 : 600344 : BY { updatepos(); M2LexBuf_AddTok(M2Reserved_bytok); return; }
251 : 933489 : CASE { updatepos(); M2LexBuf_AddTok(M2Reserved_casetok); return; }
252 : 56458 : CONST { updatepos(); M2LexBuf_AddTok(M2Reserved_consttok); return; }
253 : 130300 : DEFINITION { updatepos(); isDefinitionModule = true;
254 : 181845 : M2LexBuf_AddTok(M2Reserved_definitiontok); return; }
255 : 164639 : DIV { updatepos(); M2LexBuf_AddTok(M2Reserved_divtok); return; }
256 : 312587 : DO { updatepos(); M2LexBuf_AddTok(M2Reserved_dotok); return; }
257 : 444832 : ELSE { updatepos(); M2LexBuf_AddTok(M2Reserved_elsetok); return; }
258 : 399871 : ELSIF { updatepos(); M2LexBuf_AddTok(M2Reserved_elsiftok); return; }
259 : 2849798 : END { updatepos(); seenEnd=true;
260 : 2531238 : M2LexBuf_AddTok(M2Reserved_endtok); return; }
261 : 2444146 : EXCEPT { updatepos(); M2LexBuf_AddTok(M2Reserved_excepttok); return; }
262 : 106 : EXIT { updatepos(); M2LexBuf_AddTok(M2Reserved_exittok); return; }
263 : 74217 : EXPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_exporttok); return; }
264 : 5426 : FINALLY { updatepos(); M2LexBuf_AddTok(M2Reserved_finallytok); return; }
265 : 94209 : FOR { updatepos(); M2LexBuf_AddTok(M2Reserved_fortok); return; }
266 : 250488 : FROM { updatepos(); M2LexBuf_AddTok(M2Reserved_fromtok); return; }
267 : 1004133 : IF { updatepos(); M2LexBuf_AddTok(M2Reserved_iftok); return; }
268 : 304430 : IMPLEMENTATION { updatepos(); M2LexBuf_AddTok(M2Reserved_implementationtok); return; }
269 : 1260900 : IMPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_importtok); return; }
270 : 70158 : IN { updatepos(); M2LexBuf_AddTok(M2Reserved_intok); return; }
271 : 284854 : LOOP { updatepos(); M2LexBuf_AddTok(M2Reserved_looptok); return; }
272 : 72576 : MOD { updatepos(); M2LexBuf_AddTok(M2Reserved_modtok); return; }
273 : 214106 : MODULE { updatepos(); seenModuleStart=true;
274 : 267883 : M2LexBuf_AddTok(M2Reserved_moduletok); return; }
275 : 275839 : NOT { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
276 : 606608 : OF { updatepos(); M2LexBuf_AddTok(M2Reserved_oftok); return; }
277 : 167270 : OR { updatepos(); M2LexBuf_AddTok(M2Reserved_ortok); return; }
278 : 606692 : PACKEDSET { updatepos(); M2LexBuf_AddTok(M2Reserved_packedsettok); return; }
279 : 171975 : POINTER { updatepos(); M2LexBuf_AddTok(M2Reserved_pointertok); return; }
280 : 2976260 : PROCEDURE { updatepos(); seenFunctionStart=true;
281 : 3050517 : M2LexBuf_AddTok(M2Reserved_proceduretok); return; }
282 : 3043751 : QUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_qualifiedtok); return; }
283 : 6156 : UNQUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_unqualifiedtok); return; }
284 : 115367 : RECORD { updatepos(); M2LexBuf_AddTok(M2Reserved_recordtok); return; }
285 : 6252 : REM { updatepos(); M2LexBuf_AddTok(M2Reserved_remtok); return; }
286 : 99179 : REPEAT { updatepos(); M2LexBuf_AddTok(M2Reserved_repeattok); return; }
287 : 222 : RETRY { updatepos(); M2LexBuf_AddTok(M2Reserved_retrytok); return; }
288 : 542066 : RETURN { updatepos(); M2LexBuf_AddTok(M2Reserved_returntok); return; }
289 : 1921 : SET { updatepos(); M2LexBuf_AddTok(M2Reserved_settok); return; }
290 : 1561912 : THEN { updatepos(); M2LexBuf_AddTok(M2Reserved_thentok); return; }
291 : 88612 : TO { updatepos(); M2LexBuf_AddTok(M2Reserved_totok); return; }
292 : 1165416 : TYPE { updatepos(); M2LexBuf_AddTok(M2Reserved_typetok); return; }
293 : 138204 : UNTIL { updatepos(); M2LexBuf_AddTok(M2Reserved_untiltok); return; }
294 : 975998 : VAR { updatepos(); M2LexBuf_AddTok(M2Reserved_vartok); return; }
295 : 226675 : WHILE { updatepos(); M2LexBuf_AddTok(M2Reserved_whiletok); return; }
296 : 1006632 : WITH { updatepos(); M2LexBuf_AddTok(M2Reserved_withtok); return; }
297 : 175306 : ASM { updatepos(); M2LexBuf_AddTok(M2Reserved_asmtok); return; }
298 : 124823 : VOLATILE { updatepos(); M2LexBuf_AddTok(M2Reserved_volatiletok); return; }
299 : 18 : \_\_DATE\_\_ { updatepos(); handleDate(); return; }
300 : 76610 : \_\_LINE\_\_ { updatepos(); handleLine(); return; }
301 : 73616 : \_\_FILE\_\_ { updatepos(); handleFile(); return; }
302 : 148474 : \_\_FUNCTION\_\_ { updatepos(); handleFunction(); return; }
303 : 123012 : \_\_COLUMN\_\_ { updatepos(); handleColumn(); return; }
304 : 151346 : \_\_ATTRIBUTE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_attributetok); return; }
305 : 174872 : \_\_BUILTIN\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_builtintok); return; }
306 : 79476 : \_\_INLINE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_inlinetok); return; }
307 : 125476 :
308 : 0 :
309 : 8878 : (([0-9]*\.[0-9]+)(E[+-]?[0-9]+)?) { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_realtok, yytext); return; }
310 : 6 : [0-9]*\.E[+-]?[0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_realtok, yytext); return; }
311 : 39469040 : [a-zA-Z_][a-zA-Z0-9_]* { checkFunction(); updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_identtok, yytext); return; }
312 : 1098636 : [0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
313 : 39469064 : [0-1]+A { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
314 : 1101082 : [0-9]+B { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
315 : 127008 : [0-9]+C { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
316 : 12802 : [0-9A-F]+H { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
317 : 126984 : [\t\r ]+ { currentLine->tokenpos += yyleng; /* Ignore space. */; }
318 : 60452037 : . { updatepos(); m2flex_M2Error("unrecognised symbol"); skippos(); }
319 : 60441687 :
320 : 0 : %%
321 : 0 :
322 : : /* have removed the -? from the beginning of the real/integer constant literal rules */
323 : :
324 : : /*
325 : : * hand built routines
326 : : */
327 : :
328 : : /*
329 : : * handleFile - handles the __FILE__ construct by wraping it in double quotes and putting
330 : : * it into the token buffer as a string.
331 : : */
332 : :
333 : 73616 : static void handleFile (void)
334 : : {
335 : 73616 : char *s = (char *)alloca(strlen(filename)+2+1);
336 : :
337 : 73616 : strcpy(s, "\"");
338 : 73616 : strcat(s, filename);
339 : 73616 : strcat(s, "\"");
340 : 73616 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
341 : 73616 : }
342 : :
343 : : /*
344 : : * handleLine - handles the __LINE__ construct by passing an integer to
345 : : * the token buffer.
346 : : */
347 : :
348 : 76604 : static void handleLine (void)
349 : : {
350 : 76604 : M2LexBuf_AddTokInteger(M2Reserved_integertok, lineno);
351 : 76604 : }
352 : :
353 : : /*
354 : : * handleColumn - handles the __COLUMN__ construct by passing an integer to
355 : : * the token buffer.
356 : : */
357 : :
358 : 49396 : static void handleColumn (void)
359 : : {
360 : 49396 : M2LexBuf_AddTokInteger(M2Reserved_integertok, m2flex_GetColumnNo());
361 : 49396 : }
362 : :
363 : : /*
364 : : * handleDate - handles the __DATE__ construct by passing the date
365 : : * as a string to the token buffer.
366 : : */
367 : :
368 : 0 : static void handleDate (void)
369 : : {
370 : 0 : time_t clock = time ((time_t *)0);
371 : 0 : char *sdate = ctime (&clock);
372 : 0 : char *s = (char *) alloca (strlen (sdate) + 2 + 1);
373 : 0 : char *p = index (sdate, '\n');
374 : :
375 : 0 : if (p != NULL) {
376 : 0 : *p = (char) 0;
377 : : }
378 : 0 : strcpy(s, "\"");
379 : 0 : strcat(s, sdate);
380 : 0 : strcat(s, "\"");
381 : 0 : M2LexBuf_AddTokCharStar (M2Reserved_stringtok, s);
382 : 0 : }
383 : :
384 : : /*
385 : : * handleFunction - handles the __FUNCTION__ construct by wrapping
386 : : * it in double quotes and putting it into the token
387 : : * buffer as a string.
388 : : */
389 : :
390 : 71870 : static void handleFunction (void)
391 : : {
392 : 71870 : if (currentFunction == NULL)
393 : 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, const_cast<char *>("\"\""));
394 : 71870 : else if (currentFunction->module) {
395 : 6 : char *s = (char *) alloca(strlen(yytext) +
396 : : strlen("\"module initialization\"") + 1);
397 : 6 : strcpy(s, "\"module ");
398 : 6 : strcat(s, currentFunction->name);
399 : 6 : strcat(s, " initialization\"");
400 : 6 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
401 : : } else {
402 : 71864 : char *function = currentFunction->name;
403 : 71864 : char *s = (char *)alloca(strlen(function)+2+1);
404 : 71864 : strcpy(s, "\"");
405 : 71864 : strcat(s, function);
406 : 71864 : strcat(s, "\"");
407 : 71864 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
408 : : }
409 : 71870 : }
410 : :
411 : : /*
412 : : * pushFunction - pushes the function name onto the stack.
413 : : */
414 : :
415 : 931793 : static void pushFunction (char *function, bool module)
416 : : {
417 : 931793 : if (currentFunction == NULL) {
418 : 80126 : currentFunction = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
419 : 80126 : currentFunction->name = xstrdup(function);
420 : 80126 : currentFunction->next = NULL;
421 : 80126 : currentFunction->module = module;
422 : : } else {
423 : 851667 : struct functionInfo *f = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
424 : 851667 : f->name = xstrdup(function);
425 : 851667 : f->next = currentFunction;
426 : 851667 : f->module = module;
427 : 851667 : currentFunction = f;
428 : : }
429 : 931793 : }
430 : :
431 : : /*
432 : : * popFunction - pops the current function.
433 : : */
434 : :
435 : 914971 : static void popFunction (void)
436 : : {
437 : 914971 : if (currentFunction != NULL && currentFunction->next != NULL) {
438 : 851661 : struct functionInfo *f = currentFunction;
439 : :
440 : 851661 : currentFunction = currentFunction->next;
441 : 851661 : if (f->name != NULL)
442 : 851661 : free(f->name);
443 : 851661 : free(f);
444 : : }
445 : 914971 : }
446 : :
447 : : /*
448 : : * endOfComment - handles the end of comment
449 : : */
450 : :
451 : 3001737 : static void endOfComment (void)
452 : : {
453 : 3001737 : commentLevel--;
454 : 3001737 : updatepos();
455 : 3001737 : skippos();
456 : 3001737 : if (commentLevel==0) {
457 : 2863530 : BEGIN INITIAL;
458 : 2863530 : finishedLine();
459 : : } else
460 : 138207 : popLine();
461 : 3001737 : }
462 : :
463 : : /*
464 : : * endOfCComment - handles the end of C comment.
465 : : */
466 : :
467 : 0 : static void endOfCComment (void)
468 : : {
469 : 0 : commentCLevel = 0;
470 : 0 : updatepos();
471 : 0 : skippos();
472 : 0 : BEGIN INITIAL;
473 : 0 : finishedLine();
474 : 0 : }
475 : :
476 : : /*
477 : : * m2flex_M2Error - displays the error message, s, after the code line and pointer
478 : : * to the erroneous token.
479 : : */
480 : :
481 : 12 : EXTERN void m2flex_M2Error (const char *s)
482 : : {
483 : 12 : if (currentLine->linebuf != NULL) {
484 : 12 : int i=1;
485 : :
486 : 12 : printf("%s:%d:%s\n", filename, currentLine->lineno, currentLine->linebuf);
487 : 12 : printf("%s:%d:%*s", filename, currentLine->lineno, 1+currentLine->tokenpos, "^");
488 : 60 : while (i<currentLine->toklen) {
489 : 36 : putchar('^');
490 : 36 : i++;
491 : : }
492 : 12 : putchar('\n');
493 : : }
494 : 12 : if (s == NULL)
495 : 0 : printf("%s:%d\n", filename, currentLine->lineno);
496 : : else
497 : 12 : printf("%s:%d:%s\n", filename, currentLine->lineno, s);
498 : 12 : }
499 : :
500 : 0 : static void poperrorskip (const char *s)
501 : : {
502 : 0 : int nextpos =currentLine->nextpos;
503 : 0 : int tokenpos=currentLine->tokenpos;
504 : :
505 : 0 : popLine();
506 : 0 : m2flex_M2Error(s);
507 : 0 : if (currentLine != NULL) {
508 : 0 : currentLine->nextpos = nextpos;
509 : 0 : currentLine->tokenpos = tokenpos;
510 : : }
511 : 0 : }
512 : :
513 : : /* skipnewline skips all '\n' at the start of the line and returns
514 : : the new position. */
515 : :
516 : : static
517 : : char *
518 : 0 : skipnewline (char *line)
519 : : {
520 : 0 : while (((*line) != (char)0) && ((*line) == '\n'))
521 : 0 : line++;
522 : 0 : return line;
523 : : }
524 : :
525 : : /* traceLine display the source line providing -fdebug-trace-line was
526 : : enabled. */
527 : :
528 : : static
529 : : void
530 : 41196475 : traceLine (void)
531 : : {
532 : 41196475 : if (M2Options_GetDebugTraceLine ())
533 : : {
534 : 0 : char *line = skipnewline (currentLine->linebuf);
535 : 0 : if (filename == NULL)
536 : 0 : printf("<stdin>:%d:%s\n", currentLine->lineno, line);
537 : : else
538 : 0 : printf("%s:%d:%s\n", filename, currentLine->lineno, line);
539 : : }
540 : 41196475 : }
541 : :
542 : : /*
543 : : * consumeLine - reads a line into a buffer, it then pushes back the whole
544 : : * line except the initial \n.
545 : : */
546 : :
547 : 41196475 : static void consumeLine (void)
548 : : {
549 : 41196475 : if (currentLine->linelen<yyleng) {
550 : 302910 : currentLine->linebuf = (char *)xrealloc (currentLine->linebuf, yyleng);
551 : 302910 : currentLine->linelen = yyleng;
552 : : }
553 : 41196475 : strcpy(currentLine->linebuf, yytext+1); /* copy all except the initial \n */
554 : 41196475 : lineno++;
555 : 41196475 : totalLines++;
556 : 41196475 : currentLine->lineno = lineno;
557 : 41196475 : currentLine->tokenpos=0;
558 : 41196475 : currentLine->nextpos=0;
559 : 41196475 : currentLine->column=0;
560 : 41196475 : START_LINE (lineno, yyleng);
561 : 41196475 : yyless(1); /* push back all but the \n */
562 : 41196475 : traceLine ();
563 : 41196475 : }
564 : :
565 : 0 : static void assert_location (location_t location ATTRIBUTE_UNUSED)
566 : : {
567 : : #if 0
568 : : if ((location != BUILTINS_LOCATION) && (location != UNKNOWN_LOCATION) && (! M2Options_GetCpp ())) {
569 : : expanded_location xl = expand_location (location);
570 : : if (xl.line != currentLine->lineno) {
571 : : m2flex_M2Error ("mismatched gcc location and front end token number");
572 : : }
573 : : }
574 : : #endif
575 : 0 : }
576 : :
577 : : /*
578 : : * splitSlashStar - called if we are not tokenizing source code after it
579 : : * has been preprocessed by cpp. It is only called
580 : : * if the current token was a / immediately followed by * and
581 : : * therefore it will be split into two m2 tokens: / and *.
582 : : */
583 : :
584 : 0 : static void splitSlashStar (void)
585 : : {
586 : 0 : seenFunctionStart = false;
587 : 0 : seenEnd = false;
588 : 0 : seenModuleStart = false;
589 : 0 : currentLine->nextpos = currentLine->tokenpos+1; /* "/". */
590 : 0 : currentLine->toklen = 1;
591 : 0 : currentLine->column = currentLine->tokenpos+1;
592 : 0 : currentLine->location =
593 : 0 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
594 : : currentLine->column+currentLine->toklen-1));
595 : 0 : assert_location (GET_LOCATION (currentLine->column,
596 : : currentLine->column+currentLine->toklen-1));
597 : 0 : M2LexBuf_AddTok (M2Reserved_dividetok);
598 : 0 : currentLine->nextpos = currentLine->tokenpos+1; /* "*". */
599 : 0 : currentLine->toklen = 1;
600 : 0 : currentLine->column = currentLine->tokenpos+1;
601 : 0 : currentLine->location =
602 : 0 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
603 : : currentLine->column+currentLine->toklen-1));
604 : 0 : assert_location (GET_LOCATION (currentLine->column,
605 : : currentLine->column+currentLine->toklen-1));
606 : 0 : M2LexBuf_AddTok (M2Reserved_timestok);
607 : 0 : }
608 : :
609 : :
610 : : /*
611 : : * updatepos - updates the current token position.
612 : : * Should be used when a rule matches a token.
613 : : */
614 : :
615 : 654468978 : static void updatepos (void)
616 : : {
617 : 654468978 : seenFunctionStart = false;
618 : 654468978 : seenEnd = false;
619 : 654468978 : seenModuleStart = false;
620 : 654468978 : currentLine->nextpos = currentLine->tokenpos+yyleng;
621 : 654468978 : currentLine->toklen = yyleng;
622 : : /* if (currentLine->column == 0) */
623 : 654468978 : currentLine->column = currentLine->tokenpos+1;
624 : 1963406934 : currentLine->location =
625 : 654468978 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
626 : : currentLine->column+currentLine->toklen-1));
627 : 654468978 : assert_location (GET_LOCATION (currentLine->column,
628 : : currentLine->column+currentLine->toklen-1));
629 : 654468978 : }
630 : :
631 : : /*
632 : : * checkFunction - checks to see whether we have seen the start
633 : : * or end of a function.
634 : : */
635 : :
636 : 39469040 : static void checkFunction (void)
637 : : {
638 : 39469040 : if (! isDefinitionModule) {
639 : 24317110 : if (seenModuleStart)
640 : 80552 : pushFunction(yytext, 1);
641 : 24317110 : if (seenFunctionStart)
642 : 851241 : pushFunction(yytext, 0);
643 : 24317110 : if (seenEnd && currentFunction != NULL &&
644 : 961423 : (strcmp(currentFunction->name, yytext) == 0))
645 : 914971 : popFunction();
646 : : }
647 : 39469040 : seenFunctionStart = false;
648 : 39469040 : seenEnd = false;
649 : 39469040 : seenModuleStart = false;
650 : 39469040 : }
651 : :
652 : : /*
653 : : * skippos - skips over this token. This function should be called
654 : : * if we are not returning and thus not calling getToken.
655 : : */
656 : :
657 : 548612407 : static void skippos (void)
658 : : {
659 : 5882059 : currentLine->tokenpos = currentLine->nextpos;
660 : 542713556 : }
661 : :
662 : : /*
663 : : * initLine - initializes a currentLine
664 : : */
665 : :
666 : 16816 : static void initLine (void)
667 : : {
668 : 16816 : currentLine = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
669 : :
670 : 16816 : if (currentLine == NULL)
671 : : perror("xmalloc");
672 : 16816 : currentLine->linebuf = NULL;
673 : 16816 : currentLine->linelen = 0;
674 : 16816 : currentLine->tokenpos = 0;
675 : 16816 : currentLine->toklen = 0;
676 : 16816 : currentLine->nextpos = 0;
677 : 16816 : currentLine->lineno = lineno;
678 : 16816 : currentLine->column = 0;
679 : 16816 : currentLine->inuse = true;
680 : 16816 : currentLine->next = NULL;
681 : 16816 : }
682 : :
683 : : /*
684 : : * pushLine - pushes a new line structure.
685 : : */
686 : :
687 : 3035345 : static void pushLine (void)
688 : : {
689 : 3035345 : if (currentLine == NULL)
690 : 16816 : initLine();
691 : 3018529 : else if (currentLine->inuse) {
692 : 155017 : struct lineInfo *l = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
693 : :
694 : 155017 : if (currentLine->linebuf == NULL) {
695 : 16336 : l->linebuf = NULL;
696 : 16336 : l->linelen = 0;
697 : : } else {
698 : 138681 : l->linebuf = (char *)xstrdup (currentLine->linebuf);
699 : 138681 : l->linelen = strlen (l->linebuf)+1;
700 : : }
701 : 155017 : l->tokenpos = currentLine->tokenpos;
702 : 155017 : l->toklen = currentLine->toklen;
703 : 155017 : l->nextpos = currentLine->nextpos;
704 : 155017 : l->lineno = currentLine->lineno;
705 : 155017 : l->column = currentLine->column;
706 : 155017 : l->next = currentLine;
707 : 155017 : currentLine = l;
708 : : }
709 : 3035345 : currentLine->inuse = true;
710 : 3035345 : }
711 : :
712 : : /*
713 : : * popLine - pops a line structure.
714 : : */
715 : :
716 : 138207 : static void popLine (void)
717 : : {
718 : 138207 : if (currentLine != NULL) {
719 : 138207 : struct lineInfo *l = currentLine;
720 : :
721 : 138207 : if (currentLine->linebuf != NULL)
722 : 138207 : free(currentLine->linebuf);
723 : 138207 : currentLine = l->next;
724 : 138207 : free(l);
725 : : }
726 : 138207 : }
727 : :
728 : : /*
729 : : * resetpos - resets the position of the next token to the start of the line.
730 : : */
731 : :
732 : 205789 : static void resetpos (void)
733 : : {
734 : 6 : if (currentLine != NULL)
735 : 205789 : currentLine->nextpos = 0;
736 : 0 : }
737 : :
738 : : /*
739 : : * finishedLine - indicates that the current line does not need to be
740 : : * preserved when a pushLine occurs.
741 : : */
742 : :
743 : 2880322 : static void finishedLine (void)
744 : : {
745 : 16792 : currentLine->inuse = false;
746 : 2863530 : }
747 : :
748 : : /*
749 : : * m2flex_GetToken - returns a new token.
750 : : */
751 : :
752 : 105565720 : EXTERN char *m2flex_GetToken (void)
753 : : {
754 : 105565720 : TIMEVAR_PUSH_LEX;
755 : 105565720 : if (currentLine == NULL)
756 : 0 : initLine();
757 : 105565720 : currentLine->tokenpos = currentLine->nextpos;
758 : 105565720 : yylex();
759 : 105565720 : TIMEVAR_POP_LEX;
760 : 105565720 : return yytext;
761 : : }
762 : :
763 : : /*
764 : : * CloseSource - provided for semantic sugar
765 : : */
766 : :
767 : 0 : EXTERN void m2flex_CloseSource (void)
768 : : {
769 : 0 : END_FILE ();
770 : 0 : }
771 : :
772 : : /*
773 : : * OpenSource - returns true if file s can be opened and
774 : : * all tokens are taken from this file.
775 : : */
776 : :
777 : 205784 : EXTERN bool m2flex_OpenSource (char *s)
778 : : {
779 : 205784 : FILE *f = fopen(s, "r");
780 : :
781 : 205784 : if (f == NULL)
782 : : return( false );
783 : : else {
784 : 205783 : isDefinitionModule = false;
785 : 276119 : while (currentFunction != NULL)
786 : : {
787 : 70336 : struct functionInfo *f = currentFunction;
788 : 70336 : currentFunction = f->next;
789 : 70336 : if (f->name != NULL)
790 : 70336 : free(f->name);
791 : 70336 : free(f);
792 : : }
793 : 205783 : yy_delete_buffer (YY_CURRENT_BUFFER);
794 : 205783 : yy_switch_to_buffer (yy_create_buffer(f, YY_BUF_SIZE));
795 : 205783 : filename = xstrdup (s);
796 : 205783 : lineno = 1;
797 : 205783 : if (currentLine == NULL)
798 : 16816 : pushLine ();
799 : : else
800 : 188967 : currentLine->lineno = lineno;
801 : 205783 : START_FILE (filename, lineno);
802 : 205783 : BEGIN INITIAL; resetpos ();
803 : 205783 : return true;
804 : : }
805 : : }
806 : :
807 : : /*
808 : : * m2flex_GetLineNo - returns the current line number.
809 : : */
810 : :
811 : 105797238 : EXTERN int m2flex_GetLineNo (void)
812 : : {
813 : 105797238 : if (currentLine != NULL)
814 : 105797238 : return currentLine->lineno;
815 : : else
816 : : return 0;
817 : : }
818 : :
819 : : /*
820 : : * m2flex_GetColumnNo - returns the column where the current
821 : : * token starts.
822 : : */
823 : :
824 : 105846634 : EXTERN int m2flex_GetColumnNo (void)
825 : : {
826 : 105846634 : if (currentLine != NULL)
827 : 105846634 : return currentLine->column;
828 : : else
829 : : return 0;
830 : : }
831 : :
832 : : /*
833 : : * m2flex_GetLocation - returns the gcc location_t of the current token.
834 : : */
835 : :
836 : 105565720 : EXTERN location_t m2flex_GetLocation (void)
837 : : {
838 : 105565720 : if (currentLine != NULL)
839 : 105565720 : return currentLine->location;
840 : : else
841 : : return 0;
842 : : }
843 : :
844 : : /*
845 : : * GetTotalLines - returns the total number of lines parsed.
846 : : */
847 : :
848 : 0 : EXTERN int m2flex_GetTotalLines (void)
849 : : {
850 : 0 : return totalLines;
851 : : }
852 : :
853 : : /*
854 : : * yywrap is called when end of file is seen. We push an eof token
855 : : * and tell the lexical analysis to stop.
856 : : */
857 : :
858 : 188967 : int yywrap (void)
859 : : {
860 : 188967 : updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return 1;
861 : : }
862 : :
863 : 0 : EXTERN void _M2_m2flex_init (void) {}
864 : 0 : EXTERN void _M2_m2flex_fini (void) {}
|