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 : : #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 : : /* m2.flex provides a lexical analyser for GNU Modula-2. */
52 : :
53 : : struct lineInfo {
54 : : char *linebuf; /* line contents */
55 : : int linelen; /* length */
56 : : int tokenpos; /* start position of token within line */
57 : : int toklen; /* a copy of yylen (length of token) */
58 : : int nextpos; /* position after token */
59 : : int lineno; /* line number of this line */
60 : : int column; /* first column number of token on this line */
61 : : bool inuse; /* do we need to keep this line info? */
62 : : location_t location; /* the corresponding gcc location_t */
63 : : struct lineInfo *next;
64 : : };
65 : :
66 : : struct functionInfo {
67 : : char *name; /* function name */
68 : : bool module; /* is it really a module? */
69 : : struct functionInfo *next; /* list of nested functions */
70 : : };
71 : :
72 : : static int lineno =1; /* a running count of the file line number */
73 : : static char *filename =NULL;
74 : : static int commentLevel=0;
75 : : static int commentCLevel=0;
76 : : static struct lineInfo *currentLine=NULL;
77 : : static struct functionInfo *currentFunction=NULL;
78 : : static bool seenFunctionStart=false;
79 : : static bool seenEnd=false;
80 : : static bool seenModuleStart=false;
81 : : static bool isDefinitionModule=false;
82 : : static int totalLines=0;
83 : :
84 : : static void pushLine (void);
85 : : static void popLine (void);
86 : : static void finishedLine (void);
87 : : static void resetpos (void);
88 : : static void consumeLine (void);
89 : : static void updatepos (void);
90 : : static void skippos (void);
91 : : static void poperrorskip (const char *);
92 : : static void endOfComment (void);
93 : : static void endOfCComment (void);
94 : : static void splitSlashStar (void);
95 : : static void handleDate (void);
96 : : static void handleLine (void);
97 : : static void handleFile (void);
98 : : static void handleFunction (void);
99 : : static void handleColumn (void);
100 : : static void pushFunction (char *function, bool module);
101 : : static void popFunction (void);
102 : : static void checkFunction (void);
103 : : EXTERN void m2flex_M2Error (const char *);
104 : : EXTERN location_t m2flex_GetLocation (void);
105 : : EXTERN int m2flex_GetColumnNo (void);
106 : : EXTERN bool m2flex_OpenSource (char *s);
107 : : EXTERN int m2flex_GetLineNo (void);
108 : : EXTERN void m2flex_CloseSource (void);
109 : : EXTERN char *m2flex_GetToken (void);
110 : : EXTERN void _M2_m2flex_init (void);
111 : : EXTERN int m2flex_GetTotalLines (void);
112 : : extern void yylex (void);
113 : :
114 : : #define YY_DECL void yylex (void)
115 : : %}
116 : :
117 : : %option nounput
118 : : %x COMMENT COMMENT1 COMMENTC LINE0 LINE1 LINE2
119 : :
120 : : %%
121 : :
122 : 2990836 : "(*" { updatepos();
123 : 2990836 : commentLevel=1; pushLine(); skippos();
124 : 2990836 : BEGIN COMMENT; }
125 : 6119942 : <COMMENT>"*)" { endOfComment(); }
126 : 3267388 : <COMMENT>"(*" { commentLevel++; pushLine(); updatepos(); skippos(); }
127 : 3145349 : <COMMENT>"<*" { if (commentLevel == 1) {
128 : 154519 : updatepos();
129 : 32480 : pushLine();
130 : 16237 : skippos();
131 : 16237 : BEGIN COMMENT1;
132 : : } else {
133 : 6 : updatepos(); skippos();
134 : : }
135 : : }
136 : 13333419 : <COMMENT>\n.* { consumeLine(); }
137 : 567582429 : <COMMENT>. { updatepos(); skippos(); }
138 : 162370 : <COMMENT1>. { updatepos(); skippos(); }
139 : 567598666 : <COMMENT1>"*>" { updatepos(); skippos(); finishedLine(); BEGIN COMMENT; }
140 : 162370 : <COMMENT1>\n.* { consumeLine(); }
141 : 16237 : <COMMENT1>"*)" { poperrorskip("unterminated source code directive, missing *>");
142 : 0 : endOfComment(); }
143 : 0 : <COMMENT1><<EOF>> { poperrorskip("unterminated source code directive, missing *>"); BEGIN COMMENT; }
144 : 0 : <COMMENT><<EOF>> { poperrorskip("unterminated comment found at the end of the file, missing *)"); BEGIN INITIAL; }
145 : 12 :
146 : 0 : "/*" { /* Possibly handle C preprocessor comment. */
147 : 0 : if (cpreprocessor)
148 : : {
149 : 0 : updatepos ();
150 : 0 : commentCLevel++;
151 : 0 : if (commentCLevel == 1)
152 : : {
153 : 0 : pushLine ();
154 : 0 : skippos ();
155 : : }
156 : 0 : BEGIN COMMENTC;
157 : : }
158 : : else
159 : 0 : splitSlashStar ();
160 : : }
161 : 0 : <COMMENTC>. { updatepos(); skippos(); }
162 : 0 : <COMMENTC>\n.* { consumeLine(); }
163 : 0 : <COMMENTC>"*/" { endOfCComment(); }
164 : 14958 : ^\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
165 : 14958 : if (M2Options_GetLineDirectives ())
166 : 29916 : BEGIN LINE0;
167 : : }
168 : 12223 : \n\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
169 : 12223 : if (M2Options_GetLineDirectives ())
170 : 12223 : BEGIN LINE0;
171 : 12223 : }
172 : 12223 : <LINE0>\#[ \t]* { updatepos(); }
173 : 39404 : <LINE0>[0-9]+[ \t]*\" { updatepos(); lineno=atoi(yytext); BEGIN LINE1; }
174 : 39404 : <LINE0>\n { m2flex_M2Error("missing initial quote after #line directive"); resetpos(); BEGIN INITIAL; }
175 : 27181 : <LINE0>[^\n]
176 : 0 : <LINE1>[^\"\n]+ { m2flex_M2Error("missing final quote after #line directive"); resetpos(); BEGIN INITIAL; }
177 : 42139 : <LINE1>.*\" { updatepos();
178 : 27181 : filename = (char *)xrealloc(filename, yyleng+1);
179 : 27181 : strcpy(filename, yytext);
180 : 27181 : filename[yyleng-1] = (char)0; /* remove trailing quote */
181 : 27181 : START_FILE (filename, lineno);
182 : 27181 : BEGIN LINE2;
183 : : }
184 : 27181 : <LINE2>[ \t]* { updatepos(); }
185 : 27181 : <LINE2>\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
186 : 29959 : <LINE2>2[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
187 : 2778 : <LINE2>1[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
188 : 16069 : <LINE2>1[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
189 : 5556 : <LINE2>2[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
190 : 8334 : <LINE2>3[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
191 : 11112 :
192 : 0 : \n[^\#].* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
193 : 29250021 : \n { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
194 : 29431907 :
195 : 303743 : \"[^\"\n]*\" { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
196 : 493963 : \"[^\"\n]*$ { updatepos();
197 : 0 : m2flex_M2Error("missing terminating quote, \"");
198 : 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext);
199 : 0 : resetpos(); return;
200 : 0 : }
201 : 0 :
202 : 447006 : '[^'\n]*' { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
203 : 447012 : '[^'\n]*$ { updatepos();
204 : 6 : m2flex_M2Error("missing terminating quote, '");
205 : 6 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext);
206 : 12 : resetpos(); return;
207 : 6 : }
208 : 6 :
209 : 190656 : <<EOF>> { updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return; }
210 : 180475 : \+ { updatepos(); M2LexBuf_AddTok(M2Reserved_plustok); return; }
211 : 181637 : - { updatepos(); M2LexBuf_AddTok(M2Reserved_minustok); return; }
212 : 249608 : "*" { updatepos(); M2LexBuf_AddTok(M2Reserved_timestok); return; }
213 : 373243 : \/ { updatepos(); M2LexBuf_AddTok(M2Reserved_dividetok); return; }
214 : 2122609 : := { updatepos(); M2LexBuf_AddTok(M2Reserved_becomestok); return; }
215 : 950 : \& { updatepos(); M2LexBuf_AddTok(M2Reserved_ambersandtok); return; }
216 : 3363862 : \. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodtok); return; }
217 : 7663369 : \, { updatepos(); M2LexBuf_AddTok(M2Reserved_commatok); return; }
218 : 13025491 : \; { updatepos(); M2LexBuf_AddTok(M2Reserved_semicolontok); return; }
219 : 15356569 : \( { updatepos(); M2LexBuf_AddTok(M2Reserved_lparatok); return; }
220 : 19408311 : \) { updatepos(); M2LexBuf_AddTok(M2Reserved_rparatok); return; }
221 : 8514465 : \[ { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
222 : 8514445 : \] { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
223 : 821265 : \(\! { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
224 : 821239 : \!\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
225 : 733382 : \^ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
226 : 0 : \@ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
227 : 755038 : \{ { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
228 : 21656 : \} { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
229 : 21656 : \(\: { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
230 : 21656 : \:\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
231 : 0 : \' { updatepos(); M2LexBuf_AddTok(M2Reserved_singlequotetok); return; }
232 : 944154 : \= { updatepos(); M2LexBuf_AddTok(M2Reserved_equaltok); return; }
233 : 358563 : \# { updatepos(); M2LexBuf_AddTok(M2Reserved_hashtok); return; }
234 : 1146009 : \< { updatepos(); M2LexBuf_AddTok(M2Reserved_lesstok); return; }
235 : 508865 : \> { updatepos(); M2LexBuf_AddTok(M2Reserved_greatertok); return; }
236 : 201939 : \<\> { updatepos(); M2LexBuf_AddTok(M2Reserved_lessgreatertok); return; }
237 : 298088 : \<\= { updatepos(); M2LexBuf_AddTok(M2Reserved_lessequaltok); return; }
238 : 54230 : \>\= { updatepos(); M2LexBuf_AddTok(M2Reserved_greaterequaltok); return; }
239 : 659437 : "<*" { updatepos(); M2LexBuf_AddTok(M2Reserved_ldirectivetok); return; }
240 : 565797 : "*>" { updatepos(); M2LexBuf_AddTok(M2Reserved_rdirectivetok); return; }
241 : 595450 : \.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodtok); return; }
242 : 522487 : \.\.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodperiodtok); return; }
243 : 7515018 : \: { updatepos(); M2LexBuf_AddTok(M2Reserved_colontok); return; }
244 : 10836 : \" { updatepos(); M2LexBuf_AddTok(M2Reserved_doublequotestok); return; }
245 : 7441393 : \| { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
246 : 0 : \! { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
247 : 10174 : \~ { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
248 : 251056 : AND { updatepos(); M2LexBuf_AddTok(M2Reserved_andtok); return; }
249 : 612323 : ARRAY { updatepos(); M2LexBuf_AddTok(M2Reserved_arraytok); return; }
250 : 1233021 : BEGIN { updatepos(); M2LexBuf_AddTok(M2Reserved_begintok); return; }
251 : 612695 : BY { updatepos(); M2LexBuf_AddTok(M2Reserved_bytok); return; }
252 : 986758 : CASE { updatepos(); M2LexBuf_AddTok(M2Reserved_casetok); return; }
253 : 56829 : CONST { updatepos(); M2LexBuf_AddTok(M2Reserved_consttok); return; }
254 : 129886 : DEFINITION { updatepos(); isDefinitionModule = true;
255 : 181550 : M2LexBuf_AddTok(M2Reserved_definitiontok); return; }
256 : 166348 : DIV { updatepos(); M2LexBuf_AddTok(M2Reserved_divtok); return; }
257 : 331599 : DO { updatepos(); M2LexBuf_AddTok(M2Reserved_dotok); return; }
258 : 468139 : ELSE { updatepos(); M2LexBuf_AddTok(M2Reserved_elsetok); return; }
259 : 423311 : ELSIF { updatepos(); M2LexBuf_AddTok(M2Reserved_elsiftok); return; }
260 : 2996542 : END { updatepos(); seenEnd=true;
261 : 2661370 : M2LexBuf_AddTok(M2Reserved_endtok); return; }
262 : 2569850 : EXCEPT { updatepos(); M2LexBuf_AddTok(M2Reserved_excepttok); return; }
263 : 106 : EXIT { updatepos(); M2LexBuf_AddTok(M2Reserved_exittok); return; }
264 : 73617 : EXPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_exporttok); return; }
265 : 5720 : FINALLY { updatepos(); M2LexBuf_AddTok(M2Reserved_finallytok); return; }
266 : 94281 : FOR { updatepos(); M2LexBuf_AddTok(M2Reserved_fortok); return; }
267 : 5674 : FORWARD { updatepos(); M2LexBuf_AddTok(M2Reserved_forwardtok); return; }
268 : 274186 : FROM { updatepos(); M2LexBuf_AddTok(M2Reserved_fromtok); return; }
269 : 1035661 : IF { updatepos(); M2LexBuf_AddTok(M2Reserved_iftok); return; }
270 : 312670 : IMPLEMENTATION { updatepos(); M2LexBuf_AddTok(M2Reserved_implementationtok); return; }
271 : 1322784 : IMPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_importtok); return; }
272 : 71004 : IN { updatepos(); M2LexBuf_AddTok(M2Reserved_intok); return; }
273 : 295444 : LOOP { updatepos(); M2LexBuf_AddTok(M2Reserved_looptok); return; }
274 : 76476 : MOD { updatepos(); M2LexBuf_AddTok(M2Reserved_modtok); return; }
275 : 215604 : MODULE { updatepos(); seenModuleStart=true;
276 : 272155 : M2LexBuf_AddTok(M2Reserved_moduletok); return; }
277 : 279967 : NOT { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
278 : 619001 : OF { updatepos(); M2LexBuf_AddTok(M2Reserved_oftok); return; }
279 : 175142 : OR { updatepos(); M2LexBuf_AddTok(M2Reserved_ortok); return; }
280 : 619097 : PACKEDSET { updatepos(); M2LexBuf_AddTok(M2Reserved_packedsettok); return; }
281 : 179891 : POINTER { updatepos(); M2LexBuf_AddTok(M2Reserved_pointertok); return; }
282 : 3092238 : PROCEDURE { updatepos(); seenFunctionStart=true;
283 : 3169515 : M2LexBuf_AddTok(M2Reserved_proceduretok); return; }
284 : 3158841 : QUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_qualifiedtok); return; }
285 : 6432 : UNQUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_unqualifiedtok); return; }
286 : 116135 : RECORD { updatepos(); M2LexBuf_AddTok(M2Reserved_recordtok); return; }
287 : 6528 : REM { updatepos(); M2LexBuf_AddTok(M2Reserved_remtok); return; }
288 : 103319 : REPEAT { updatepos(); M2LexBuf_AddTok(M2Reserved_repeattok); return; }
289 : 222 : RETRY { updatepos(); M2LexBuf_AddTok(M2Reserved_retrytok); return; }
290 : 581295 : RETURN { updatepos(); M2LexBuf_AddTok(M2Reserved_returntok); return; }
291 : 1909 : SET { updatepos(); M2LexBuf_AddTok(M2Reserved_settok); return; }
292 : 1654725 : THEN { updatepos(); M2LexBuf_AddTok(M2Reserved_thentok); return; }
293 : 92088 : TO { updatepos(); M2LexBuf_AddTok(M2Reserved_totok); return; }
294 : 1222846 : TYPE { updatepos(); M2LexBuf_AddTok(M2Reserved_typetok); return; }
295 : 144188 : UNTIL { updatepos(); M2LexBuf_AddTok(M2Reserved_untiltok); return; }
296 : 1012249 : VAR { updatepos(); M2LexBuf_AddTok(M2Reserved_vartok); return; }
297 : 239459 : WHILE { updatepos(); M2LexBuf_AddTok(M2Reserved_whiletok); return; }
298 : 1049801 : WITH { updatepos(); M2LexBuf_AddTok(M2Reserved_withtok); return; }
299 : 185600 : ASM { updatepos(); M2LexBuf_AddTok(M2Reserved_asmtok); return; }
300 : 133097 : VOLATILE { updatepos(); M2LexBuf_AddTok(M2Reserved_volatiletok); return; }
301 : 24 : \_\_DATE\_\_ { updatepos(); handleDate(); return; }
302 : 80120 : \_\_LINE\_\_ { updatepos(); handleLine(); return; }
303 : 77120 : \_\_FILE\_\_ { updatepos(); handleFile(); return; }
304 : 155560 : \_\_FUNCTION\_\_ { updatepos(); handleFunction(); return; }
305 : 128820 : \_\_COLUMN\_\_ { updatepos(); handleColumn(); return; }
306 : 158690 : \_\_ATTRIBUTE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_attributetok); return; }
307 : 185438 : \_\_BUILTIN\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_builtintok); return; }
308 : 83238 : \_\_INLINE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_inlinetok); return; }
309 : 133738 :
310 : 0 :
311 : 9148 : (([0-9]*\.[0-9]+)(E[+-]?[0-9]+)?) { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_realtok, yytext); return; }
312 : 6 : [0-9]*\.E[+-]?[0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_realtok, yytext); return; }
313 : 41166518 : [a-zA-Z_][a-zA-Z0-9_]* { checkFunction(); updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_identtok, yytext); return; }
314 : 1148748 : [0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
315 : 41166542 : [0-1]+A { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
316 : 1151326 : [0-9]+B { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
317 : 129500 : [0-9]+C { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
318 : 13438 : [0-9A-F]+H { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
319 : 129476 : [\t\r ]+ { currentLine->tokenpos += yyleng; /* Ignore space. */; }
320 : 63047479 : . { updatepos(); m2flex_M2Error("unrecognised symbol"); skippos(); }
321 : 63036625 :
322 : 0 : %%
323 : 0 :
324 : : /* have removed the -? from the beginning of the real/integer constant literal rules */
325 : :
326 : : /*
327 : : * hand built routines
328 : : */
329 : :
330 : : /*
331 : : * handleFile - handles the __FILE__ construct by wraping it in double quotes and putting
332 : : * it into the token buffer as a string.
333 : : */
334 : :
335 : 77120 : static void handleFile (void)
336 : : {
337 : 77120 : char *s = (char *)alloca(strlen(filename)+2+1);
338 : :
339 : 77120 : strcpy(s, "\"");
340 : 77120 : strcat(s, filename);
341 : 77120 : strcat(s, "\"");
342 : 77120 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
343 : 77120 : }
344 : :
345 : : /*
346 : : * handleLine - handles the __LINE__ construct by passing an integer to
347 : : * the token buffer.
348 : : */
349 : :
350 : 80108 : static void handleLine (void)
351 : : {
352 : 80108 : M2LexBuf_AddTokInteger(M2Reserved_integertok, lineno);
353 : 80108 : }
354 : :
355 : : /*
356 : : * handleColumn - handles the __COLUMN__ construct by passing an integer to
357 : : * the token buffer.
358 : : */
359 : :
360 : 51700 : static void handleColumn (void)
361 : : {
362 : 51700 : M2LexBuf_AddTokInteger(M2Reserved_integertok, m2flex_GetColumnNo());
363 : 51700 : }
364 : :
365 : : /*
366 : : * handleDate - handles the __DATE__ construct by passing the date
367 : : * as a string to the token buffer.
368 : : */
369 : :
370 : 0 : static void handleDate (void)
371 : : {
372 : 0 : time_t clock = time ((time_t *)0);
373 : 0 : char *sdate = ctime (&clock);
374 : 0 : char *s = (char *) alloca (strlen (sdate) + 2 + 1);
375 : 0 : char *p = index (sdate, '\n');
376 : :
377 : 0 : if (p != NULL) {
378 : 0 : *p = (char) 0;
379 : : }
380 : 0 : strcpy(s, "\"");
381 : 0 : strcat(s, sdate);
382 : 0 : strcat(s, "\"");
383 : 0 : M2LexBuf_AddTokCharStar (M2Reserved_stringtok, s);
384 : 0 : }
385 : :
386 : : /*
387 : : * handleFunction - handles the __FUNCTION__ construct by wrapping
388 : : * it in double quotes and putting it into the token
389 : : * buffer as a string.
390 : : */
391 : :
392 : 75452 : static void handleFunction (void)
393 : : {
394 : 75452 : if (currentFunction == NULL)
395 : 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, const_cast<char *>("\"\""));
396 : 75452 : else if (currentFunction->module) {
397 : 6 : char *s = (char *) alloca(strlen(yytext) +
398 : : strlen("\"module initialization\"") + 1);
399 : 6 : strcpy(s, "\"module ");
400 : 6 : strcat(s, currentFunction->name);
401 : 6 : strcat(s, " initialization\"");
402 : 6 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
403 : : } else {
404 : 75446 : char *function = currentFunction->name;
405 : 75446 : char *s = (char *)alloca(strlen(function)+2+1);
406 : 75446 : strcpy(s, "\"");
407 : 75446 : strcat(s, function);
408 : 75446 : strcat(s, "\"");
409 : 75446 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
410 : : }
411 : 75452 : }
412 : :
413 : : /*
414 : : * pushFunction - pushes the function name onto the stack.
415 : : */
416 : :
417 : 980280 : static void pushFunction (char *function, bool module)
418 : : {
419 : 980280 : if (currentFunction == NULL) {
420 : 81824 : currentFunction = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
421 : 81824 : currentFunction->name = xstrdup(function);
422 : 81824 : currentFunction->next = NULL;
423 : 81824 : currentFunction->module = module;
424 : : } else {
425 : 898456 : struct functionInfo *f = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
426 : 898456 : f->name = xstrdup(function);
427 : 898456 : f->next = currentFunction;
428 : 898456 : f->module = module;
429 : 898456 : currentFunction = f;
430 : : }
431 : 980280 : }
432 : :
433 : : /*
434 : : * popFunction - pops the current function.
435 : : */
436 : :
437 : 963851 : static void popFunction (void)
438 : : {
439 : 963851 : if (currentFunction != NULL && currentFunction->next != NULL) {
440 : 898378 : struct functionInfo *f = currentFunction;
441 : :
442 : 898378 : currentFunction = currentFunction->next;
443 : 898378 : if (f->name != NULL)
444 : 898378 : free(f->name);
445 : 898378 : free(f);
446 : : }
447 : 963851 : }
448 : :
449 : : /*
450 : : * endOfComment - handles the end of comment
451 : : */
452 : :
453 : 3129106 : static void endOfComment (void)
454 : : {
455 : 3129106 : commentLevel--;
456 : 3129106 : updatepos();
457 : 3129106 : skippos();
458 : 3129106 : if (commentLevel==0) {
459 : 2990824 : BEGIN INITIAL;
460 : 2990824 : finishedLine();
461 : : } else
462 : 138282 : popLine();
463 : 3129106 : }
464 : :
465 : : /*
466 : : * endOfCComment - handles the end of C comment.
467 : : */
468 : :
469 : 0 : static void endOfCComment (void)
470 : : {
471 : 0 : commentCLevel = 0;
472 : 0 : updatepos();
473 : 0 : skippos();
474 : 0 : BEGIN INITIAL;
475 : 0 : finishedLine();
476 : 0 : }
477 : :
478 : : /*
479 : : * m2flex_M2Error - displays the error message, s, after the code line and pointer
480 : : * to the erroneous token.
481 : : */
482 : :
483 : 24 : EXTERN void m2flex_M2Error (const char *s)
484 : : {
485 : 24 : if (currentLine->linebuf != NULL) {
486 : 12 : int i=1;
487 : :
488 : 12 : printf("%s:%d:%s\n", filename, currentLine->lineno, currentLine->linebuf);
489 : 12 : printf("%s:%d:%*s", filename, currentLine->lineno, 1+currentLine->tokenpos, "^");
490 : 60 : while (i<currentLine->toklen) {
491 : 36 : putchar('^');
492 : 36 : i++;
493 : : }
494 : 12 : putchar('\n');
495 : : }
496 : 24 : if (s == NULL)
497 : 0 : printf("%s:%d\n", filename, currentLine->lineno);
498 : : else
499 : 24 : printf("%s:%d:%s\n", filename, currentLine->lineno, s);
500 : 24 : }
501 : :
502 : 12 : static void poperrorskip (const char *s)
503 : : {
504 : 12 : int nextpos =currentLine->nextpos;
505 : 12 : int tokenpos=currentLine->tokenpos;
506 : :
507 : 12 : popLine();
508 : 12 : m2flex_M2Error(s);
509 : 12 : if (currentLine != NULL) {
510 : 12 : currentLine->nextpos = nextpos;
511 : 12 : currentLine->tokenpos = tokenpos;
512 : : }
513 : 12 : }
514 : :
515 : : /* skipnewline skips all '\n' at the start of the line and returns
516 : : the new position. */
517 : :
518 : : static
519 : : char *
520 : 0 : skipnewline (char *line)
521 : : {
522 : 0 : while (((*line) != (char)0) && ((*line) == '\n'))
523 : 0 : line++;
524 : 0 : return line;
525 : : }
526 : :
527 : : /* traceLine display the source line providing -fdebug-trace-line was
528 : : enabled. */
529 : :
530 : : static
531 : : void
532 : 42792507 : traceLine (void)
533 : : {
534 : 42792507 : if (M2Options_GetDebugTraceLine ())
535 : : {
536 : 0 : char *line = skipnewline (currentLine->linebuf);
537 : 0 : if (filename == NULL)
538 : 0 : printf("<stdin>:%d:%s\n", currentLine->lineno, line);
539 : : else
540 : 0 : printf("%s:%d:%s\n", filename, currentLine->lineno, line);
541 : : }
542 : 42792507 : }
543 : :
544 : : /*
545 : : * consumeLine - reads a line into a buffer, it then pushes back the whole
546 : : * line except the initial \n.
547 : : */
548 : :
549 : 42792507 : static void consumeLine (void)
550 : : {
551 : 42792507 : if (currentLine->linelen<yyleng) {
552 : 297877 : currentLine->linebuf = (char *)xrealloc (currentLine->linebuf, yyleng);
553 : 297877 : currentLine->linelen = yyleng;
554 : : }
555 : 42792507 : strcpy(currentLine->linebuf, yytext+1); /* copy all except the initial \n */
556 : 42792507 : lineno++;
557 : 42792507 : totalLines++;
558 : 42792507 : currentLine->lineno = lineno;
559 : 42792507 : currentLine->tokenpos=0;
560 : 42792507 : currentLine->nextpos=0;
561 : 42792507 : currentLine->column=0;
562 : 42792507 : START_LINE (lineno, yyleng);
563 : 42792507 : yyless(1); /* push back all but the \n */
564 : 42792507 : traceLine ();
565 : 42792507 : }
566 : :
567 : 0 : static void assert_location (location_t location ATTRIBUTE_UNUSED)
568 : : {
569 : : #if 0
570 : : if ((location != BUILTINS_LOCATION) && (location != UNKNOWN_LOCATION) && (! M2Options_GetCpp ())) {
571 : : expanded_location xl = expand_location (location);
572 : : if (xl.line != currentLine->lineno) {
573 : : m2flex_M2Error ("mismatched gcc location and front end token number");
574 : : }
575 : : }
576 : : #endif
577 : 0 : }
578 : :
579 : : /*
580 : : * splitSlashStar - called if we are not tokenizing source code after it
581 : : * has been preprocessed by cpp. It is only called
582 : : * if the current token was a / immediately followed by * and
583 : : * therefore it will be split into two m2 tokens: / and *.
584 : : */
585 : :
586 : 0 : static void splitSlashStar (void)
587 : : {
588 : 0 : seenFunctionStart = false;
589 : 0 : seenEnd = false;
590 : 0 : seenModuleStart = false;
591 : 0 : currentLine->nextpos = currentLine->tokenpos+1; /* "/". */
592 : 0 : currentLine->toklen = 1;
593 : 0 : currentLine->column = currentLine->tokenpos+1;
594 : 0 : currentLine->location =
595 : 0 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
596 : : currentLine->column+currentLine->toklen-1));
597 : 0 : assert_location (GET_LOCATION (currentLine->column,
598 : : currentLine->column+currentLine->toklen-1));
599 : 0 : M2LexBuf_AddTok (M2Reserved_dividetok);
600 : 0 : currentLine->nextpos = currentLine->tokenpos+1; /* "*". */
601 : 0 : currentLine->toklen = 1;
602 : 0 : currentLine->column = currentLine->tokenpos+1;
603 : 0 : currentLine->location =
604 : 0 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
605 : : currentLine->column+currentLine->toklen-1));
606 : 0 : assert_location (GET_LOCATION (currentLine->column,
607 : : currentLine->column+currentLine->toklen-1));
608 : 0 : M2LexBuf_AddTok (M2Reserved_timestok);
609 : 0 : }
610 : :
611 : :
612 : : /*
613 : : * updatepos - updates the current token position.
614 : : * Should be used when a rule matches a token.
615 : : */
616 : :
617 : 671099904 : static void updatepos (void)
618 : : {
619 : 671099904 : seenFunctionStart = false;
620 : 671099904 : seenEnd = false;
621 : 671099904 : seenModuleStart = false;
622 : 671099904 : currentLine->nextpos = currentLine->tokenpos+yyleng;
623 : 671099904 : currentLine->toklen = yyleng;
624 : : /* if (currentLine->column == 0) */
625 : 671099904 : currentLine->column = currentLine->tokenpos+1;
626 : 2013299712 : currentLine->location =
627 : 671099904 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
628 : : currentLine->column+currentLine->toklen-1));
629 : 671099904 : assert_location (GET_LOCATION (currentLine->column,
630 : : currentLine->column+currentLine->toklen-1));
631 : 671099904 : }
632 : :
633 : : /*
634 : : * checkFunction - checks to see whether we have seen the start
635 : : * or end of a function.
636 : : */
637 : :
638 : 41166518 : static void checkFunction (void)
639 : : {
640 : 41166518 : if (! isDefinitionModule) {
641 : 25657733 : if (seenModuleStart)
642 : 82250 : pushFunction(yytext, 1);
643 : 25657733 : if (seenFunctionStart)
644 : 898030 : pushFunction(yytext, 0);
645 : 25657733 : if (seenEnd && currentFunction != NULL &&
646 : 1014875 : (strcmp(currentFunction->name, yytext) == 0))
647 : 963851 : popFunction();
648 : : }
649 : 41166518 : seenFunctionStart = false;
650 : 41166518 : seenEnd = false;
651 : 41166518 : seenModuleStart = false;
652 : 41166518 : }
653 : :
654 : : /*
655 : : * skippos - skips over this token. This function should be called
656 : : * if we are not returning and thus not calling getToken.
657 : : */
658 : :
659 : 560702084 : static void skippos (void)
660 : : {
661 : 6136179 : currentLine->tokenpos = currentLine->nextpos;
662 : 554549668 : }
663 : :
664 : : /*
665 : : * initLine - initializes a currentLine
666 : : */
667 : :
668 : 16261 : static void initLine (void)
669 : : {
670 : 16261 : currentLine = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
671 : :
672 : 16261 : if (currentLine == NULL)
673 : : perror("xmalloc");
674 : 16261 : currentLine->linebuf = NULL;
675 : 16261 : currentLine->linelen = 0;
676 : 16261 : currentLine->tokenpos = 0;
677 : 16261 : currentLine->toklen = 0;
678 : 16261 : currentLine->nextpos = 0;
679 : 16261 : currentLine->lineno = lineno;
680 : 16261 : currentLine->column = 0;
681 : 16261 : currentLine->inuse = true;
682 : 16261 : currentLine->next = NULL;
683 : 16261 : }
684 : :
685 : : /*
686 : : * pushLine - pushes a new line structure.
687 : : */
688 : :
689 : 3161616 : static void pushLine (void)
690 : : {
691 : 3161616 : if (currentLine == NULL)
692 : 16261 : initLine();
693 : 3145355 : else if (currentLine->inuse) {
694 : 154543 : struct lineInfo *l = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
695 : :
696 : 154543 : if (currentLine->linebuf == NULL) {
697 : 15745 : l->linebuf = NULL;
698 : 15745 : l->linelen = 0;
699 : : } else {
700 : 138798 : l->linebuf = (char *)xstrdup (currentLine->linebuf);
701 : 138798 : l->linelen = strlen (l->linebuf)+1;
702 : : }
703 : 154543 : l->tokenpos = currentLine->tokenpos;
704 : 154543 : l->toklen = currentLine->toklen;
705 : 154543 : l->nextpos = currentLine->nextpos;
706 : 154543 : l->lineno = currentLine->lineno;
707 : 154543 : l->column = currentLine->column;
708 : 154543 : l->next = currentLine;
709 : 154543 : currentLine = l;
710 : : }
711 : 3161616 : currentLine->inuse = true;
712 : 3161616 : }
713 : :
714 : : /*
715 : : * popLine - pops a line structure.
716 : : */
717 : :
718 : 138294 : static void popLine (void)
719 : : {
720 : 138294 : if (currentLine != NULL) {
721 : 138294 : struct lineInfo *l = currentLine;
722 : :
723 : 138294 : if (currentLine->linebuf != NULL)
724 : 138294 : free(currentLine->linebuf);
725 : 138294 : currentLine = l->next;
726 : 138294 : free(l);
727 : : }
728 : 138294 : }
729 : :
730 : : /*
731 : : * resetpos - resets the position of the next token to the start of the line.
732 : : */
733 : :
734 : 206929 : static void resetpos (void)
735 : : {
736 : 6 : if (currentLine != NULL)
737 : 206929 : currentLine->nextpos = 0;
738 : 0 : }
739 : :
740 : : /*
741 : : * finishedLine - indicates that the current line does not need to be
742 : : * preserved when a pushLine occurs.
743 : : */
744 : :
745 : 3007061 : static void finishedLine (void)
746 : : {
747 : 16237 : currentLine->inuse = false;
748 : 2990824 : }
749 : :
750 : : /*
751 : : * m2flex_GetToken - returns a new token.
752 : : */
753 : :
754 : 110099496 : EXTERN char *m2flex_GetToken (void)
755 : : {
756 : 110099496 : TIMEVAR_PUSH_LEX;
757 : 110099496 : if (currentLine == NULL)
758 : 0 : initLine();
759 : 110099496 : currentLine->tokenpos = currentLine->nextpos;
760 : 110099496 : yylex();
761 : 110099496 : TIMEVAR_POP_LEX;
762 : 110099496 : return yytext;
763 : : }
764 : :
765 : : /*
766 : : * CloseSource - provided for semantic sugar
767 : : */
768 : :
769 : 0 : EXTERN void m2flex_CloseSource (void)
770 : : {
771 : 0 : END_FILE ();
772 : 0 : }
773 : :
774 : : /*
775 : : * OpenSource - returns true if file s can be opened and
776 : : * all tokens are taken from this file.
777 : : */
778 : :
779 : 206924 : EXTERN bool m2flex_OpenSource (char *s)
780 : : {
781 : 206924 : FILE *f = fopen(s, "r");
782 : :
783 : 206924 : if (f == NULL)
784 : : return( false );
785 : : else {
786 : 206923 : isDefinitionModule = false;
787 : 279734 : while (currentFunction != NULL)
788 : : {
789 : 72811 : struct functionInfo *f = currentFunction;
790 : 72811 : currentFunction = f->next;
791 : 72811 : if (f->name != NULL)
792 : 72811 : free(f->name);
793 : 72811 : free(f);
794 : : }
795 : 206923 : yy_delete_buffer (YY_CURRENT_BUFFER);
796 : 206923 : yy_switch_to_buffer (yy_create_buffer(f, YY_BUF_SIZE));
797 : 206923 : filename = xstrdup (s);
798 : 206923 : lineno = 1;
799 : 206923 : if (currentLine == NULL)
800 : 16261 : pushLine ();
801 : : else
802 : 190662 : currentLine->lineno = lineno;
803 : 206923 : START_FILE (filename, lineno);
804 : 206923 : BEGIN INITIAL; resetpos ();
805 : 206923 : return true;
806 : : }
807 : : }
808 : :
809 : : /*
810 : : * m2flex_GetLineNo - returns the current line number.
811 : : */
812 : :
813 : 110333600 : EXTERN int m2flex_GetLineNo (void)
814 : : {
815 : 110333600 : if (currentLine != NULL)
816 : 110333600 : return currentLine->lineno;
817 : : else
818 : : return 0;
819 : : }
820 : :
821 : : /*
822 : : * m2flex_GetColumnNo - returns the column where the current
823 : : * token starts.
824 : : */
825 : :
826 : 110385300 : EXTERN int m2flex_GetColumnNo (void)
827 : : {
828 : 110385300 : if (currentLine != NULL)
829 : 110385300 : return currentLine->column;
830 : : else
831 : : return 0;
832 : : }
833 : :
834 : : /*
835 : : * m2flex_GetLocation - returns the gcc location_t of the current token.
836 : : */
837 : :
838 : 110099496 : EXTERN location_t m2flex_GetLocation (void)
839 : : {
840 : 110099496 : if (currentLine != NULL)
841 : 110099496 : return currentLine->location;
842 : : else
843 : : return 0;
844 : : }
845 : :
846 : : /*
847 : : * GetTotalLines - returns the total number of lines parsed.
848 : : */
849 : :
850 : 0 : EXTERN int m2flex_GetTotalLines (void)
851 : : {
852 : 0 : return totalLines;
853 : : }
854 : :
855 : : /*
856 : : * yywrap is called when end of file is seen. We push an eof token
857 : : * and tell the lexical analysis to stop.
858 : : */
859 : :
860 : 190668 : int yywrap (void)
861 : : {
862 : 190668 : updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return 1;
863 : : }
864 : :
865 : 0 : EXTERN void _M2_m2flex_init (void) {}
866 : 0 : EXTERN void _M2_m2flex_fini (void) {}
|