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 : : /* 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 : 2936247 : "(*" { updatepos();
123 : 2936247 : commentLevel=1; pushLine(); skippos();
124 : 2936247 : BEGIN COMMENT; }
125 : 6000688 : <COMMENT>"*)" { endOfComment(); }
126 : 3192647 : <COMMENT>"(*" { commentLevel++; pushLine(); updatepos(); skippos(); }
127 : 3079194 : <COMMENT>"<*" { if (commentLevel == 1) {
128 : 142953 : updatepos();
129 : 29500 : pushLine();
130 : 14747 : skippos();
131 : 14747 : BEGIN COMMENT1;
132 : : } else {
133 : 6 : updatepos(); skippos();
134 : : }
135 : : }
136 : 12929871 : <COMMENT>\n.* { consumeLine(); }
137 : 550132234 : <COMMENT>. { updatepos(); skippos(); }
138 : 147470 : <COMMENT1>. { updatepos(); skippos(); }
139 : 550146981 : <COMMENT1>"*>" { updatepos(); skippos(); finishedLine(); BEGIN COMMENT; }
140 : 147470 : <COMMENT1>\n.* { consumeLine(); }
141 : 14747 : <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 : 15058 : ^\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
165 : 15058 : if (M2Options_GetLineDirectives ())
166 : 30116 : BEGIN LINE0;
167 : : }
168 : 11833 : \n\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
169 : 11833 : if (M2Options_GetLineDirectives ())
170 : 11833 : BEGIN LINE0;
171 : 11833 : }
172 : 11833 : <LINE0>\#[ \t]* { updatepos(); }
173 : 38724 : <LINE0>[0-9]+[ \t]*\" { updatepos(); lineno=atoi(yytext); BEGIN LINE1; }
174 : 38724 : <LINE0>\n { m2flex_M2Error("missing initial quote after #line directive"); resetpos(); BEGIN INITIAL; }
175 : 26891 : <LINE0>[^\n]
176 : 0 : <LINE1>[^\"\n]+ { m2flex_M2Error("missing final quote after #line directive"); resetpos(); BEGIN INITIAL; }
177 : 41949 : <LINE1>.*\" { updatepos();
178 : 26891 : filename = (char *)xrealloc(filename, yyleng+1);
179 : 26891 : strcpy(filename, yytext);
180 : 26891 : filename[yyleng-1] = (char)0; /* remove trailing quote */
181 : 26891 : START_FILE (filename, lineno);
182 : 26891 : BEGIN LINE2;
183 : : }
184 : 26891 : <LINE2>[ \t]* { updatepos(); }
185 : 26891 : <LINE2>\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
186 : 29699 : <LINE2>2[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
187 : 2808 : <LINE2>1[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
188 : 15659 : <LINE2>1[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
189 : 5616 : <LINE2>2[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
190 : 8424 : <LINE2>3[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
191 : 11232 :
192 : 0 : \n[^\#].* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
193 : 29090851 : \n { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
194 : 29265995 :
195 : 309802 : \"[^\"\n]*\" { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
196 : 493370 : \"[^\"\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 : 452307 : '[^'\n]*' { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
203 : 452313 : '[^'\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 : 184010 : <<EOF>> { updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return; }
210 : 183349 : \+ { updatepos(); M2LexBuf_AddTok(M2Reserved_plustok); return; }
211 : 182535 : - { updatepos(); M2LexBuf_AddTok(M2Reserved_minustok); return; }
212 : 253664 : "*" { updatepos(); M2LexBuf_AddTok(M2Reserved_timestok); return; }
213 : 367501 : \/ { updatepos(); M2LexBuf_AddTok(M2Reserved_dividetok); return; }
214 : 2155295 : := { updatepos(); M2LexBuf_AddTok(M2Reserved_becomestok); return; }
215 : 956 : \& { updatepos(); M2LexBuf_AddTok(M2Reserved_ambersandtok); return; }
216 : 3405971 : \. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodtok); return; }
217 : 7572172 : \, { updatepos(); M2LexBuf_AddTok(M2Reserved_commatok); return; }
218 : 12914846 : \; { updatepos(); M2LexBuf_AddTok(M2Reserved_semicolontok); return; }
219 : 15278326 : \( { updatepos(); M2LexBuf_AddTok(M2Reserved_lparatok); return; }
220 : 19300015 : \) { updatepos(); M2LexBuf_AddTok(M2Reserved_rparatok); return; }
221 : 8537137 : \[ { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
222 : 8537117 : \] { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
223 : 830983 : \(\! { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
224 : 830957 : \!\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
225 : 746425 : \^ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
226 : 0 : \@ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
227 : 768351 : \{ { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
228 : 21926 : \} { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
229 : 21926 : \(\: { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
230 : 21926 : \:\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
231 : 0 : \' { updatepos(); M2LexBuf_AddTok(M2Reserved_singlequotetok); return; }
232 : 942685 : \= { updatepos(); M2LexBuf_AddTok(M2Reserved_equaltok); return; }
233 : 363767 : \# { updatepos(); M2LexBuf_AddTok(M2Reserved_hashtok); return; }
234 : 1148284 : \< { updatepos(); M2LexBuf_AddTok(M2Reserved_lesstok); return; }
235 : 516415 : \> { updatepos(); M2LexBuf_AddTok(M2Reserved_greatertok); return; }
236 : 205683 : \<\> { updatepos(); M2LexBuf_AddTok(M2Reserved_lessgreatertok); return; }
237 : 302846 : \<\= { updatepos(); M2LexBuf_AddTok(M2Reserved_lessequaltok); return; }
238 : 55046 : \>\= { updatepos(); M2LexBuf_AddTok(M2Reserved_greaterequaltok); return; }
239 : 617590 : "<*" { updatepos(); M2LexBuf_AddTok(M2Reserved_ldirectivetok); return; }
240 : 522354 : "*>" { updatepos(); M2LexBuf_AddTok(M2Reserved_rdirectivetok); return; }
241 : 551839 : \.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodtok); return; }
242 : 478378 : \.\.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodperiodtok); return; }
243 : 7368222 : \: { updatepos(); M2LexBuf_AddTok(M2Reserved_colontok); return; }
244 : 10986 : \" { updatepos(); M2LexBuf_AddTok(M2Reserved_doublequotestok); return; }
245 : 7293517 : \| { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
246 : 0 : \! { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
247 : 9742 : \~ { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
248 : 254692 : AND { updatepos(); M2LexBuf_AddTok(M2Reserved_andtok); return; }
249 : 600870 : ARRAY { updatepos(); M2LexBuf_AddTok(M2Reserved_arraytok); return; }
250 : 1254541 : BEGIN { updatepos(); M2LexBuf_AddTok(M2Reserved_begintok); return; }
251 : 601242 : BY { updatepos(); M2LexBuf_AddTok(M2Reserved_bytok); return; }
252 : 1004636 : CASE { updatepos(); M2LexBuf_AddTok(M2Reserved_casetok); return; }
253 : 54850 : CONST { updatepos(); M2LexBuf_AddTok(M2Reserved_consttok); return; }
254 : 123752 : DEFINITION { updatepos(); isDefinitionModule = true;
255 : 173443 : M2LexBuf_AddTok(M2Reserved_definitiontok); return; }
256 : 160835 : DIV { updatepos(); M2LexBuf_AddTok(M2Reserved_divtok); return; }
257 : 335022 : DO { updatepos(); M2LexBuf_AddTok(M2Reserved_dotok); return; }
258 : 475984 : ELSE { updatepos(); M2LexBuf_AddTok(M2Reserved_elsetok); return; }
259 : 428138 : ELSIF { updatepos(); M2LexBuf_AddTok(M2Reserved_elsiftok); return; }
260 : 3034825 : END { updatepos(); seenEnd=true;
261 : 2693827 : M2LexBuf_AddTok(M2Reserved_endtok); return; }
262 : 2600939 : EXCEPT { updatepos(); M2LexBuf_AddTok(M2Reserved_excepttok); return; }
263 : 106 : EXIT { updatepos(); M2LexBuf_AddTok(M2Reserved_exittok); return; }
264 : 70155 : EXPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_exporttok); return; }
265 : 5828 : FINALLY { updatepos(); M2LexBuf_AddTok(M2Reserved_finallytok); return; }
266 : 90840 : FOR { updatepos(); M2LexBuf_AddTok(M2Reserved_fortok); return; }
267 : 5782 : FORWARD { updatepos(); M2LexBuf_AddTok(M2Reserved_forwardtok); return; }
268 : 273033 : FROM { updatepos(); M2LexBuf_AddTok(M2Reserved_fromtok); return; }
269 : 1052250 : IF { updatepos(); M2LexBuf_AddTok(M2Reserved_iftok); return; }
270 : 309044 : IMPLEMENTATION { updatepos(); M2LexBuf_AddTok(M2Reserved_implementationtok); return; }
271 : 1338685 : IMPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_importtok); return; }
272 : 68390 : IN { updatepos(); M2LexBuf_AddTok(M2Reserved_intok); return; }
273 : 294876 : LOOP { updatepos(); M2LexBuf_AddTok(M2Reserved_looptok); return; }
274 : 77490 : MOD { updatepos(); M2LexBuf_AddTok(M2Reserved_modtok); return; }
275 : 207588 : MODULE { updatepos(); seenModuleStart=true;
276 : 265231 : M2LexBuf_AddTok(M2Reserved_moduletok); return; }
277 : 272461 : NOT { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
278 : 607542 : OF { updatepos(); M2LexBuf_AddTok(M2Reserved_oftok); return; }
279 : 177230 : OR { updatepos(); M2LexBuf_AddTok(M2Reserved_ortok); return; }
280 : 607656 : PACKEDSET { updatepos(); M2LexBuf_AddTok(M2Reserved_packedsettok); return; }
281 : 181981 : POINTER { updatepos(); M2LexBuf_AddTok(M2Reserved_pointertok); return; }
282 : 3021235 : PROCEDURE { updatepos(); seenFunctionStart=true;
283 : 3099126 : M2LexBuf_AddTok(M2Reserved_proceduretok); return; }
284 : 3084229 : QUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_qualifiedtok); return; }
285 : 6525 : UNQUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_unqualifiedtok); return; }
286 : 112779 : RECORD { updatepos(); M2LexBuf_AddTok(M2Reserved_recordtok); return; }
287 : 6621 : REM { updatepos(); M2LexBuf_AddTok(M2Reserved_remtok); return; }
288 : 104400 : REPEAT { updatepos(); M2LexBuf_AddTok(M2Reserved_repeattok); return; }
289 : 270 : RETRY { updatepos(); M2LexBuf_AddTok(M2Reserved_retrytok); return; }
290 : 593626 : RETURN { updatepos(); M2LexBuf_AddTok(M2Reserved_returntok); return; }
291 : 1939 : SET { updatepos(); M2LexBuf_AddTok(M2Reserved_settok); return; }
292 : 1684203 : THEN { updatepos(); M2LexBuf_AddTok(M2Reserved_thentok); return; }
293 : 92738 : TO { updatepos(); M2LexBuf_AddTok(M2Reserved_totok); return; }
294 : 1238094 : TYPE { updatepos(); M2LexBuf_AddTok(M2Reserved_typetok); return; }
295 : 145702 : UNTIL { updatepos(); M2LexBuf_AddTok(M2Reserved_untiltok); return; }
296 : 1008360 : VAR { updatepos(); M2LexBuf_AddTok(M2Reserved_vartok); return; }
297 : 242636 : WHILE { updatepos(); M2LexBuf_AddTok(M2Reserved_whiletok); return; }
298 : 1049713 : WITH { updatepos(); M2LexBuf_AddTok(M2Reserved_withtok); return; }
299 : 187933 : ASM { updatepos(); M2LexBuf_AddTok(M2Reserved_asmtok); return; }
300 : 134155 : VOLATILE { updatepos(); M2LexBuf_AddTok(M2Reserved_volatiletok); return; }
301 : 26 : \_\_DATE\_\_ { updatepos(); handleDate(); return; }
302 : 81952 : \_\_LINE\_\_ { updatepos(); handleLine(); return; }
303 : 78566 : \_\_FILE\_\_ { updatepos(); handleFile(); return; }
304 : 158764 : \_\_FUNCTION\_\_ { updatepos(); handleFunction(); return; }
305 : 131178 : \_\_COLUMN\_\_ { updatepos(); handleColumn(); return; }
306 : 160440 : \_\_ATTRIBUTE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_attributetok); return; }
307 : 189890 : \_\_BUILTIN\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_builtintok); return; }
308 : 83614 : \_\_INLINE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_inlinetok); return; }
309 : 137278 :
310 : 0 :
311 : 9226 : (([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 : 40863666 : [a-zA-Z_][a-zA-Z0-9_]* { checkFunction(); updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_identtok, yytext); return; }
314 : 1161067 : [0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
315 : 40863690 : [0-1]+A { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
316 : 1163699 : [0-9]+B { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
317 : 128819 : [0-9]+C { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
318 : 13690 : [0-9A-F]+H { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
319 : 128795 : [\t\r ]+ { currentLine->tokenpos += yyleng; /* Ignore space. */; }
320 : 62672393 : . { updatepos(); m2flex_M2Error("unrecognised symbol"); skippos(); }
321 : 62661341 :
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 : 78566 : static void handleFile (void)
336 : : {
337 : 78566 : char *s = (char *)alloca(strlen(filename)+2+1);
338 : :
339 : 78566 : strcpy(s, "\"");
340 : 78566 : strcat(s, filename);
341 : 78566 : strcat(s, "\"");
342 : 78566 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
343 : 78566 : }
344 : :
345 : : /*
346 : : * handleLine - handles the __LINE__ construct by passing an integer to
347 : : * the token buffer.
348 : : */
349 : :
350 : 81938 : static void handleLine (void)
351 : : {
352 : 81938 : M2LexBuf_AddTokInteger(M2Reserved_integertok, lineno);
353 : 81938 : }
354 : :
355 : : /*
356 : : * handleColumn - handles the __COLUMN__ construct by passing an integer to
357 : : * the token buffer.
358 : : */
359 : :
360 : 52612 : static void handleColumn (void)
361 : : {
362 : 52612 : M2LexBuf_AddTokInteger(M2Reserved_integertok, m2flex_GetColumnNo());
363 : 52612 : }
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 : 76826 : static void handleFunction (void)
393 : : {
394 : 76826 : if (currentFunction == NULL)
395 : 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, const_cast<char *>("\"\""));
396 : 76826 : 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 : 76820 : char *function = currentFunction->name;
405 : 76820 : char *s = (char *)alloca(strlen(function)+2+1);
406 : 76820 : strcpy(s, "\"");
407 : 76820 : strcat(s, function);
408 : 76820 : strcat(s, "\"");
409 : 76820 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
410 : : }
411 : 76826 : }
412 : :
413 : : /*
414 : : * pushFunction - pushes the function name onto the stack.
415 : : */
416 : :
417 : 992446 : static void pushFunction (char *function, bool module)
418 : : {
419 : 992446 : if (currentFunction == NULL) {
420 : 79816 : currentFunction = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
421 : 79816 : currentFunction->name = xstrdup(function);
422 : 79816 : currentFunction->next = NULL;
423 : 79816 : currentFunction->module = module;
424 : : } else {
425 : 912630 : struct functionInfo *f = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
426 : 912630 : f->name = xstrdup(function);
427 : 912630 : f->next = currentFunction;
428 : 912630 : f->module = module;
429 : 912630 : currentFunction = f;
430 : : }
431 : 992446 : }
432 : :
433 : : /*
434 : : * popFunction - pops the current function.
435 : : */
436 : :
437 : 977507 : static void popFunction (void)
438 : : {
439 : 977507 : if (currentFunction != NULL && currentFunction->next != NULL) {
440 : 912552 : struct functionInfo *f = currentFunction;
441 : :
442 : 912552 : currentFunction = currentFunction->next;
443 : 912552 : if (f->name != NULL)
444 : 912552 : free(f->name);
445 : 912552 : free(f);
446 : : }
447 : 977507 : }
448 : :
449 : : /*
450 : : * endOfComment - handles the end of comment
451 : : */
452 : :
453 : 3064441 : static void endOfComment (void)
454 : : {
455 : 3064441 : commentLevel--;
456 : 3064441 : updatepos();
457 : 3064441 : skippos();
458 : 3064441 : if (commentLevel==0) {
459 : 2936235 : BEGIN INITIAL;
460 : 2936235 : finishedLine();
461 : : } else
462 : 128206 : popLine();
463 : 3064441 : }
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 : 42222757 : traceLine (void)
533 : : {
534 : 42222757 : 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 : 42222757 : }
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 : 42222757 : static void consumeLine (void)
550 : : {
551 : 42222757 : if (currentLine->linelen<yyleng) {
552 : 272784 : currentLine->linebuf = (char *)xrealloc (currentLine->linebuf, yyleng);
553 : 272784 : currentLine->linelen = yyleng;
554 : : }
555 : 42222757 : strcpy(currentLine->linebuf, yytext+1); /* copy all except the initial \n */
556 : 42222757 : lineno++;
557 : 42222757 : totalLines++;
558 : 42222757 : currentLine->lineno = lineno;
559 : 42222757 : currentLine->tokenpos=0;
560 : 42222757 : currentLine->nextpos=0;
561 : 42222757 : currentLine->column=0;
562 : 42222757 : START_LINE (lineno, yyleng);
563 : 42222757 : yyless(1); /* push back all but the \n */
564 : 42222757 : traceLine ();
565 : 42222757 : }
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 : 653288625 : static void updatepos (void)
618 : : {
619 : 653288625 : seenFunctionStart = false;
620 : 653288625 : seenEnd = false;
621 : 653288625 : seenModuleStart = false;
622 : 653288625 : currentLine->nextpos = currentLine->tokenpos+yyleng;
623 : 653288625 : currentLine->toklen = yyleng;
624 : : /* if (currentLine->column == 0) */
625 : 653288625 : currentLine->column = currentLine->tokenpos+1;
626 : 1959865875 : currentLine->location =
627 : 653288625 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
628 : : currentLine->column+currentLine->toklen-1));
629 : 653288625 : assert_location (GET_LOCATION (currentLine->column,
630 : : currentLine->column+currentLine->toklen-1));
631 : 653288625 : }
632 : :
633 : : /*
634 : : * checkFunction - checks to see whether we have seen the start
635 : : * or end of a function.
636 : : */
637 : :
638 : 40863666 : static void checkFunction (void)
639 : : {
640 : 40863666 : if (! isDefinitionModule) {
641 : 26066082 : if (seenModuleStart)
642 : 80242 : pushFunction(yytext, 1);
643 : 26066082 : if (seenFunctionStart)
644 : 912204 : pushFunction(yytext, 0);
645 : 26066082 : if (seenEnd && currentFunction != NULL &&
646 : 1031695 : (strcmp(currentFunction->name, yytext) == 0))
647 : 977507 : popFunction();
648 : : }
649 : 40863666 : seenFunctionStart = false;
650 : 40863666 : seenEnd = false;
651 : 40863666 : seenModuleStart = false;
652 : 40863666 : }
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 : 543508227 : static void skippos (void)
660 : : {
661 : 6015435 : currentLine->tokenpos = currentLine->nextpos;
662 : 537478045 : }
663 : :
664 : : /*
665 : : * initLine - initializes a currentLine
666 : : */
667 : :
668 : 14771 : static void initLine (void)
669 : : {
670 : 14771 : currentLine = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
671 : :
672 : 14771 : if (currentLine == NULL)
673 : : perror("xmalloc");
674 : 14771 : currentLine->linebuf = NULL;
675 : 14771 : currentLine->linelen = 0;
676 : 14771 : currentLine->tokenpos = 0;
677 : 14771 : currentLine->toklen = 0;
678 : 14771 : currentLine->nextpos = 0;
679 : 14771 : currentLine->lineno = lineno;
680 : 14771 : currentLine->column = 0;
681 : 14771 : currentLine->inuse = true;
682 : 14771 : currentLine->next = NULL;
683 : 14771 : }
684 : :
685 : : /*
686 : : * pushLine - pushes a new line structure.
687 : : */
688 : :
689 : 3093971 : static void pushLine (void)
690 : : {
691 : 3093971 : if (currentLine == NULL)
692 : 14771 : initLine();
693 : 3079200 : else if (currentLine->inuse) {
694 : 142977 : struct lineInfo *l = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
695 : :
696 : 142977 : if (currentLine->linebuf == NULL) {
697 : 14247 : l->linebuf = NULL;
698 : 14247 : l->linelen = 0;
699 : : } else {
700 : 128730 : l->linebuf = (char *)xstrdup (currentLine->linebuf);
701 : 128730 : l->linelen = strlen (l->linebuf)+1;
702 : : }
703 : 142977 : l->tokenpos = currentLine->tokenpos;
704 : 142977 : l->toklen = currentLine->toklen;
705 : 142977 : l->nextpos = currentLine->nextpos;
706 : 142977 : l->lineno = currentLine->lineno;
707 : 142977 : l->column = currentLine->column;
708 : 142977 : l->next = currentLine;
709 : 142977 : currentLine = l;
710 : : }
711 : 3093971 : currentLine->inuse = true;
712 : 3093971 : }
713 : :
714 : : /*
715 : : * popLine - pops a line structure.
716 : : */
717 : :
718 : 128218 : static void popLine (void)
719 : : {
720 : 128218 : if (currentLine != NULL) {
721 : 128218 : struct lineInfo *l = currentLine;
722 : :
723 : 128218 : if (currentLine->linebuf != NULL)
724 : 128218 : free(currentLine->linebuf);
725 : 128218 : currentLine = l->next;
726 : 128218 : free(l);
727 : : }
728 : 128218 : }
729 : :
730 : : /*
731 : : * resetpos - resets the position of the next token to the start of the line.
732 : : */
733 : :
734 : 198793 : static void resetpos (void)
735 : : {
736 : 6 : if (currentLine != NULL)
737 : 198793 : 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 : 2950982 : static void finishedLine (void)
746 : : {
747 : 14747 : currentLine->inuse = false;
748 : 2936235 : }
749 : :
750 : : /*
751 : : * m2flex_GetToken - returns a new token.
752 : : */
753 : :
754 : 109489830 : EXTERN char *m2flex_GetToken (void)
755 : : {
756 : 109489830 : TIMEVAR_PUSH_LEX;
757 : 109489830 : if (currentLine == NULL)
758 : 0 : initLine();
759 : 109489830 : currentLine->tokenpos = currentLine->nextpos;
760 : 109489830 : yylex();
761 : 109489830 : TIMEVAR_POP_LEX;
762 : 109489830 : 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 : 198788 : EXTERN bool m2flex_OpenSource (char *s)
780 : : {
781 : 198788 : FILE *f = fopen(s, "r");
782 : :
783 : 198788 : if (f == NULL)
784 : : return( false );
785 : : else {
786 : 198787 : isDefinitionModule = false;
787 : 271038 : while (currentFunction != NULL)
788 : : {
789 : 72251 : struct functionInfo *f = currentFunction;
790 : 72251 : currentFunction = f->next;
791 : 72251 : if (f->name != NULL)
792 : 72251 : free(f->name);
793 : 72251 : free(f);
794 : : }
795 : 198787 : yy_delete_buffer (YY_CURRENT_BUFFER);
796 : 198787 : yy_switch_to_buffer (yy_create_buffer(f, YY_BUF_SIZE));
797 : 198787 : filename = xstrdup (s);
798 : 198787 : lineno = 1;
799 : 198787 : if (currentLine == NULL)
800 : 14771 : pushLine ();
801 : : else
802 : 184016 : currentLine->lineno = lineno;
803 : 198787 : START_FILE (filename, lineno);
804 : 198787 : BEGIN INITIAL; resetpos ();
805 : 198787 : return true;
806 : : }
807 : : }
808 : :
809 : : /*
810 : : * m2flex_GetLineNo - returns the current line number.
811 : : */
812 : :
813 : 109715508 : EXTERN int m2flex_GetLineNo (void)
814 : : {
815 : 109715508 : if (currentLine != NULL)
816 : 109715508 : 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 : 109768120 : EXTERN int m2flex_GetColumnNo (void)
827 : : {
828 : 109768120 : if (currentLine != NULL)
829 : 109768120 : 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 : 109489830 : EXTERN location_t m2flex_GetLocation (void)
839 : : {
840 : 109489830 : if (currentLine != NULL)
841 : 109489830 : 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 : 184022 : int yywrap (void)
861 : : {
862 : 184022 : 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) {}
|