2 /* m2.flex implements lexical analysis for Modula-2.
4 Copyright (C) 2004-2025 Free Software Foundation, Inc.
5 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
7 This file is part of GNU Modula-2.
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)
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.
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/>. */
23 #include "gm2-gcc/gcc-consolidation.h"
25 #include "GM2Reserved.h"
26 #include "GM2LexBuf.h"
28 #include "m2options.h"
29 #include "Gm2linemap.h"
31 static int cpreprocessor = 0; /* Replace this with correct getter. */
33 #if defined(GM2USEGGC)
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)
48 #define EXTERN extern "C"
51 /* m2.flex provides a lexical analyser for GNU Modula-2. */
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;
67 char *name; /* function name */
68 bool module; /* is it really a module? */
69 struct functionInfo *next; /* list of nested functions */
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;
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);
114 #define YY_DECL void yylex (void)
118 %x COMMENT COMMENT1 COMMENTC LINE0 LINE1 LINE2
123 commentLevel=1; pushLine(); skippos();
125 <COMMENT>"*)" { endOfComment(); }
126 <COMMENT>"(*" { commentLevel++; pushLine(); updatepos(); skippos(); }
127 <COMMENT>"<*" { if (commentLevel == 1) {
133 updatepos(); skippos();
136 <COMMENT>\n.* { consumeLine(); }
137 <COMMENT>. { updatepos(); skippos(); }
138 <COMMENT1>. { updatepos(); skippos(); }
139 <COMMENT1>"*>" { updatepos(); skippos(); finishedLine(); BEGIN COMMENT; }
140 <COMMENT1>\n.* { consumeLine(); }
141 <COMMENT1>"*)" { poperrorskip("unterminated source code directive, missing *>");
143 <COMMENT1><<EOF>> { poperrorskip("unterminated source code directive, missing *>"); BEGIN COMMENT; }
144 <COMMENT><<EOF>> { poperrorskip("unterminated comment found at the end of the file, missing *)"); BEGIN INITIAL; }
146 "/*" { /* Possibly handle C preprocessor comment. */
151 if (commentCLevel == 1)
161 <COMMENTC>. { updatepos(); skippos(); }
162 <COMMENTC>\n.* { consumeLine(); }
163 <COMMENTC>"*/" { endOfCComment(); }
164 ^\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
165 if (M2Options_GetLineDirectives ())
168 \n\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
169 if (M2Options_GetLineDirectives ())
172 <LINE0>\#[ \t]* { updatepos(); }
173 <LINE0>[0-9]+[ \t]*\" { updatepos(); lineno=atoi(yytext); BEGIN LINE1; }
174 <LINE0>\n { m2flex_M2Error("missing initial quote after #line directive"); resetpos(); BEGIN INITIAL; }
176 <LINE1>[^\"\n]+ { m2flex_M2Error("missing final quote after #line directive"); resetpos(); BEGIN INITIAL; }
177 <LINE1>.*\" { updatepos();
178 filename = (char *)xrealloc(filename, yyleng+1);
179 strcpy(filename, yytext);
180 filename[yyleng-1] = (char)0; /* remove trailing quote */
181 START_FILE (filename, lineno);
184 <LINE2>[ \t]* { updatepos(); }
185 <LINE2>\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
186 <LINE2>2[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
187 <LINE2>1[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
188 <LINE2>1[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
189 <LINE2>2[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
190 <LINE2>3[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
192 \n[^\#].* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
193 \n { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
195 \"[^\"\n]*\" { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
196 \"[^\"\n]*$ { updatepos();
197 m2flex_M2Error("missing terminating quote, \"");
198 M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext);
202 '[^'\n]*' { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
203 '[^'\n]*$ { updatepos();
204 m2flex_M2Error("missing terminating quote, '");
205 M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext);
209 <<EOF>> { updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return; }
210 \+ { updatepos(); M2LexBuf_AddTok(M2Reserved_plustok); return; }
211 - { updatepos(); M2LexBuf_AddTok(M2Reserved_minustok); return; }
212 "*" { updatepos(); M2LexBuf_AddTok(M2Reserved_timestok); return; }
213 \/ { updatepos(); M2LexBuf_AddTok(M2Reserved_dividetok); return; }
214 := { updatepos(); M2LexBuf_AddTok(M2Reserved_becomestok); return; }
215 \& { updatepos(); M2LexBuf_AddTok(M2Reserved_ambersandtok); return; }
216 \. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodtok); return; }
217 \, { updatepos(); M2LexBuf_AddTok(M2Reserved_commatok); return; }
218 \; { updatepos(); M2LexBuf_AddTok(M2Reserved_semicolontok); return; }
219 \( { updatepos(); M2LexBuf_AddTok(M2Reserved_lparatok); return; }
220 \) { updatepos(); M2LexBuf_AddTok(M2Reserved_rparatok); return; }
221 \[ { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
222 \] { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
223 \(\! { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
224 \!\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
225 \^ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
226 \@ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
227 \{ { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
228 \} { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
229 \(\: { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
230 \:\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
231 \' { updatepos(); M2LexBuf_AddTok(M2Reserved_singlequotetok); return; }
232 \= { updatepos(); M2LexBuf_AddTok(M2Reserved_equaltok); return; }
233 \# { updatepos(); M2LexBuf_AddTok(M2Reserved_hashtok); return; }
234 \< { updatepos(); M2LexBuf_AddTok(M2Reserved_lesstok); return; }
235 \> { updatepos(); M2LexBuf_AddTok(M2Reserved_greatertok); return; }
236 \<\> { updatepos(); M2LexBuf_AddTok(M2Reserved_lessgreatertok); return; }
237 \<\= { updatepos(); M2LexBuf_AddTok(M2Reserved_lessequaltok); return; }
238 \>\= { updatepos(); M2LexBuf_AddTok(M2Reserved_greaterequaltok); return; }
239 "<*" { updatepos(); M2LexBuf_AddTok(M2Reserved_ldirectivetok); return; }
240 "*>" { updatepos(); M2LexBuf_AddTok(M2Reserved_rdirectivetok); return; }
241 \.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodtok); return; }
242 \.\.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodperiodtok); return; }
243 \: { updatepos(); M2LexBuf_AddTok(M2Reserved_colontok); return; }
244 \" { updatepos(); M2LexBuf_AddTok(M2Reserved_doublequotestok); return; }
245 \| { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
246 \! { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
247 \~ { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
248 AND { updatepos(); M2LexBuf_AddTok(M2Reserved_andtok); return; }
249 ARRAY { updatepos(); M2LexBuf_AddTok(M2Reserved_arraytok); return; }
250 BEGIN { updatepos(); M2LexBuf_AddTok(M2Reserved_begintok); return; }
251 BY { updatepos(); M2LexBuf_AddTok(M2Reserved_bytok); return; }
252 CASE { updatepos(); M2LexBuf_AddTok(M2Reserved_casetok); return; }
253 CONST { updatepos(); M2LexBuf_AddTok(M2Reserved_consttok); return; }
254 DEFINITION { updatepos(); isDefinitionModule = true;
255 M2LexBuf_AddTok(M2Reserved_definitiontok); return; }
256 DIV { updatepos(); M2LexBuf_AddTok(M2Reserved_divtok); return; }
257 DO { updatepos(); M2LexBuf_AddTok(M2Reserved_dotok); return; }
258 ELSE { updatepos(); M2LexBuf_AddTok(M2Reserved_elsetok); return; }
259 ELSIF { updatepos(); M2LexBuf_AddTok(M2Reserved_elsiftok); return; }
260 END { updatepos(); seenEnd=true;
261 M2LexBuf_AddTok(M2Reserved_endtok); return; }
262 EXCEPT { updatepos(); M2LexBuf_AddTok(M2Reserved_excepttok); return; }
263 EXIT { updatepos(); M2LexBuf_AddTok(M2Reserved_exittok); return; }
264 EXPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_exporttok); return; }
265 FINALLY { updatepos(); M2LexBuf_AddTok(M2Reserved_finallytok); return; }
266 FOR { updatepos(); M2LexBuf_AddTok(M2Reserved_fortok); return; }
267 FORWARD { updatepos(); M2LexBuf_AddTok(M2Reserved_forwardtok); return; }
268 FROM { updatepos(); M2LexBuf_AddTok(M2Reserved_fromtok); return; }
269 IF { updatepos(); M2LexBuf_AddTok(M2Reserved_iftok); return; }
270 IMPLEMENTATION { updatepos(); M2LexBuf_AddTok(M2Reserved_implementationtok); return; }
271 IMPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_importtok); return; }
272 IN { updatepos(); M2LexBuf_AddTok(M2Reserved_intok); return; }
273 LOOP { updatepos(); M2LexBuf_AddTok(M2Reserved_looptok); return; }
274 MOD { updatepos(); M2LexBuf_AddTok(M2Reserved_modtok); return; }
275 MODULE { updatepos(); seenModuleStart=true;
276 M2LexBuf_AddTok(M2Reserved_moduletok); return; }
277 NOT { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
278 OF { updatepos(); M2LexBuf_AddTok(M2Reserved_oftok); return; }
279 OR { updatepos(); M2LexBuf_AddTok(M2Reserved_ortok); return; }
280 PACKEDSET { updatepos(); M2LexBuf_AddTok(M2Reserved_packedsettok); return; }
281 POINTER { updatepos(); M2LexBuf_AddTok(M2Reserved_pointertok); return; }
282 PROCEDURE { updatepos(); seenFunctionStart=true;
283 M2LexBuf_AddTok(M2Reserved_proceduretok); return; }
284 QUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_qualifiedtok); return; }
285 UNQUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_unqualifiedtok); return; }
286 RECORD { updatepos(); M2LexBuf_AddTok(M2Reserved_recordtok); return; }
287 REM { updatepos(); M2LexBuf_AddTok(M2Reserved_remtok); return; }
288 REPEAT { updatepos(); M2LexBuf_AddTok(M2Reserved_repeattok); return; }
289 RETRY { updatepos(); M2LexBuf_AddTok(M2Reserved_retrytok); return; }
290 RETURN { updatepos(); M2LexBuf_AddTok(M2Reserved_returntok); return; }
291 SET { updatepos(); M2LexBuf_AddTok(M2Reserved_settok); return; }
292 THEN { updatepos(); M2LexBuf_AddTok(M2Reserved_thentok); return; }
293 TO { updatepos(); M2LexBuf_AddTok(M2Reserved_totok); return; }
294 TYPE { updatepos(); M2LexBuf_AddTok(M2Reserved_typetok); return; }
295 UNTIL { updatepos(); M2LexBuf_AddTok(M2Reserved_untiltok); return; }
296 VAR { updatepos(); M2LexBuf_AddTok(M2Reserved_vartok); return; }
297 WHILE { updatepos(); M2LexBuf_AddTok(M2Reserved_whiletok); return; }
298 WITH { updatepos(); M2LexBuf_AddTok(M2Reserved_withtok); return; }
299 ASM { updatepos(); M2LexBuf_AddTok(M2Reserved_asmtok); return; }
300 VOLATILE { updatepos(); M2LexBuf_AddTok(M2Reserved_volatiletok); return; }
301 \_\_DATE\_\_ { updatepos(); handleDate(); return; }
302 \_\_LINE\_\_ { updatepos(); handleLine(); return; }
303 \_\_FILE\_\_ { updatepos(); handleFile(); return; }
304 \_\_FUNCTION\_\_ { updatepos(); handleFunction(); return; }
305 \_\_COLUMN\_\_ { updatepos(); handleColumn(); return; }
306 \_\_ATTRIBUTE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_attributetok); return; }
307 \_\_BUILTIN\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_builtintok); return; }
308 \_\_INLINE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_inlinetok); return; }
311 (([0-9]*\.[0-9]+)(E[+-]?[0-9]+)?) { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_realtok, yytext); return; }
312 [0-9]*\.E[+-]?[0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_realtok, yytext); return; }
313 [a-zA-Z_][a-zA-Z0-9_]* { checkFunction(); updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_identtok, yytext); return; }
314 [0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
315 [0-1]+A { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
316 [0-9]+B { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
317 [0-9]+C { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
318 [0-9A-F]+H { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
319 [\t\r ]+ { currentLine->tokenpos += yyleng; /* Ignore space. */; }
320 . { updatepos(); m2flex_M2Error("unrecognised symbol"); skippos(); }
324 /* have removed the -? from the beginning of the real/integer constant literal rules */
327 * hand built routines
331 * handleFile - handles the __FILE__ construct by wraping it in double quotes and putting
332 * it into the token buffer as a string.
335 static void handleFile (void)
337 char *s = (char *)alloca(strlen(filename)+2+1);
342 M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
346 * handleLine - handles the __LINE__ construct by passing an integer to
350 static void handleLine (void)
352 M2LexBuf_AddTokInteger(M2Reserved_integertok, lineno);
356 * handleColumn - handles the __COLUMN__ construct by passing an integer to
360 static void handleColumn (void)
362 M2LexBuf_AddTokInteger(M2Reserved_integertok, m2flex_GetColumnNo());
366 * handleDate - handles the __DATE__ construct by passing the date
367 * as a string to the token buffer.
370 static void handleDate (void)
372 time_t clock = time ((time_t *)0);
373 char *sdate = ctime (&clock);
374 char *s = (char *) alloca (strlen (sdate) + 2 + 1);
375 char *p = index (sdate, '\n');
383 M2LexBuf_AddTokCharStar (M2Reserved_stringtok, s);
387 * handleFunction - handles the __FUNCTION__ construct by wrapping
388 * it in double quotes and putting it into the token
389 * buffer as a string.
392 static void handleFunction (void)
394 if (currentFunction == NULL)
395 M2LexBuf_AddTokCharStar(M2Reserved_stringtok, const_cast<char *>("\"\""));
396 else if (currentFunction->module) {
397 char *s = (char *) alloca(strlen(yytext) +
398 strlen("\"module initialization\"") + 1);
399 strcpy(s, "\"module ");
400 strcat(s, currentFunction->name);
401 strcat(s, " initialization\"");
402 M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
404 char *function = currentFunction->name;
405 char *s = (char *)alloca(strlen(function)+2+1);
409 M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
414 * pushFunction - pushes the function name onto the stack.
417 static void pushFunction (char *function, bool module)
419 if (currentFunction == NULL) {
420 currentFunction = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
421 currentFunction->name = xstrdup(function);
422 currentFunction->next = NULL;
423 currentFunction->module = module;
425 struct functionInfo *f = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
426 f->name = xstrdup(function);
427 f->next = currentFunction;
434 * popFunction - pops the current function.
437 static void popFunction (void)
439 if (currentFunction != NULL && currentFunction->next != NULL) {
440 struct functionInfo *f = currentFunction;
442 currentFunction = currentFunction->next;
450 * endOfComment - handles the end of comment
453 static void endOfComment (void)
458 if (commentLevel==0) {
466 * endOfCComment - handles the end of C comment.
469 static void endOfCComment (void)
479 * m2flex_M2Error - displays the error message, s, after the code line and pointer
480 * to the erroneous token.
483 EXTERN void m2flex_M2Error (const char *s)
485 if (currentLine->linebuf != NULL) {
488 printf("%s:%d:%s\n", filename, currentLine->lineno, currentLine->linebuf);
489 printf("%s:%d:%*s", filename, currentLine->lineno, 1+currentLine->tokenpos, "^");
490 while (i<currentLine->toklen) {
497 printf("%s:%d\n", filename, currentLine->lineno);
499 printf("%s:%d:%s\n", filename, currentLine->lineno, s);
502 static void poperrorskip (const char *s)
504 int nextpos =currentLine->nextpos;
505 int tokenpos=currentLine->tokenpos;
509 if (currentLine != NULL) {
510 currentLine->nextpos = nextpos;
511 currentLine->tokenpos = tokenpos;
515 /* skipnewline skips all '\n' at the start of the line and returns
520 skipnewline (char *line)
522 while (((*line) != (char)0) && ((*line) == '\n'))
527 /* traceLine display the source line providing -fdebug-trace-line was
534 if (M2Options_GetDebugTraceLine ())
536 char *line = skipnewline (currentLine->linebuf);
537 if (filename == NULL)
538 printf("<stdin>:%d:%s\n", currentLine->lineno, line);
540 printf("%s:%d:%s\n", filename, currentLine->lineno, line);
545 * consumeLine - reads a line into a buffer, it then pushes back the whole
546 * line except the initial \n.
549 static void consumeLine (void)
551 if (currentLine->linelen<yyleng) {
552 currentLine->linebuf = (char *)xrealloc (currentLine->linebuf, yyleng);
553 currentLine->linelen = yyleng;
555 strcpy(currentLine->linebuf, yytext+1); /* copy all except the initial \n */
558 currentLine->lineno = lineno;
559 currentLine->tokenpos=0;
560 currentLine->nextpos=0;
561 currentLine->column=0;
562 START_LINE (lineno, yyleng);
563 yyless(1); /* push back all but the \n */
567 static void assert_location (location_t location ATTRIBUTE_UNUSED)
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");
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 *.
586 static void splitSlashStar (void)
588 seenFunctionStart = false;
590 seenModuleStart = false;
591 currentLine->nextpos = currentLine->tokenpos+1; /* "/". */
592 currentLine->toklen = 1;
593 currentLine->column = currentLine->tokenpos+1;
594 currentLine->location =
595 M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
596 currentLine->column+currentLine->toklen-1));
597 assert_location (GET_LOCATION (currentLine->column,
598 currentLine->column+currentLine->toklen-1));
599 M2LexBuf_AddTok (M2Reserved_dividetok);
600 currentLine->nextpos = currentLine->tokenpos+1; /* "*". */
601 currentLine->toklen = 1;
602 currentLine->column = currentLine->tokenpos+1;
603 currentLine->location =
604 M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
605 currentLine->column+currentLine->toklen-1));
606 assert_location (GET_LOCATION (currentLine->column,
607 currentLine->column+currentLine->toklen-1));
608 M2LexBuf_AddTok (M2Reserved_timestok);
613 * updatepos - updates the current token position.
614 * Should be used when a rule matches a token.
617 static void updatepos (void)
619 seenFunctionStart = false;
621 seenModuleStart = false;
622 currentLine->nextpos = currentLine->tokenpos+yyleng;
623 currentLine->toklen = yyleng;
624 /* if (currentLine->column == 0) */
625 currentLine->column = currentLine->tokenpos+1;
626 currentLine->location =
627 M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
628 currentLine->column+currentLine->toklen-1));
629 assert_location (GET_LOCATION (currentLine->column,
630 currentLine->column+currentLine->toklen-1));
634 * checkFunction - checks to see whether we have seen the start
635 * or end of a function.
638 static void checkFunction (void)
640 if (! isDefinitionModule) {
642 pushFunction(yytext, 1);
643 if (seenFunctionStart)
644 pushFunction(yytext, 0);
645 if (seenEnd && currentFunction != NULL &&
646 (strcmp(currentFunction->name, yytext) == 0))
649 seenFunctionStart = false;
651 seenModuleStart = false;
655 * skippos - skips over this token. This function should be called
656 * if we are not returning and thus not calling getToken.
659 static void skippos (void)
661 currentLine->tokenpos = currentLine->nextpos;
665 * initLine - initializes a currentLine
668 static void initLine (void)
670 currentLine = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
672 if (currentLine == NULL)
674 currentLine->linebuf = NULL;
675 currentLine->linelen = 0;
676 currentLine->tokenpos = 0;
677 currentLine->toklen = 0;
678 currentLine->nextpos = 0;
679 currentLine->lineno = lineno;
680 currentLine->column = 0;
681 currentLine->inuse = true;
682 currentLine->next = NULL;
686 * pushLine - pushes a new line structure.
689 static void pushLine (void)
691 if (currentLine == NULL)
693 else if (currentLine->inuse) {
694 struct lineInfo *l = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
696 if (currentLine->linebuf == NULL) {
700 l->linebuf = (char *)xstrdup (currentLine->linebuf);
701 l->linelen = strlen (l->linebuf)+1;
703 l->tokenpos = currentLine->tokenpos;
704 l->toklen = currentLine->toklen;
705 l->nextpos = currentLine->nextpos;
706 l->lineno = currentLine->lineno;
707 l->column = currentLine->column;
708 l->next = currentLine;
711 currentLine->inuse = true;
715 * popLine - pops a line structure.
718 static void popLine (void)
720 if (currentLine != NULL) {
721 struct lineInfo *l = currentLine;
723 if (currentLine->linebuf != NULL)
724 free(currentLine->linebuf);
725 currentLine = l->next;
731 * resetpos - resets the position of the next token to the start of the line.
734 static void resetpos (void)
736 if (currentLine != NULL)
737 currentLine->nextpos = 0;
741 * finishedLine - indicates that the current line does not need to be
742 * preserved when a pushLine occurs.
745 static void finishedLine (void)
747 currentLine->inuse = false;
751 * m2flex_GetToken - returns a new token.
754 EXTERN char *m2flex_GetToken (void)
757 if (currentLine == NULL)
759 currentLine->tokenpos = currentLine->nextpos;
766 * CloseSource - provided for semantic sugar
769 EXTERN void m2flex_CloseSource (void)
775 * OpenSource - returns true if file s can be opened and
776 * all tokens are taken from this file.
779 EXTERN bool m2flex_OpenSource (char *s)
781 FILE *f = fopen(s, "r");
786 isDefinitionModule = false;
787 while (currentFunction != NULL)
789 struct functionInfo *f = currentFunction;
790 currentFunction = f->next;
795 yy_delete_buffer (YY_CURRENT_BUFFER);
796 yy_switch_to_buffer (yy_create_buffer(f, YY_BUF_SIZE));
797 filename = xstrdup (s);
799 if (currentLine == NULL)
802 currentLine->lineno = lineno;
803 START_FILE (filename, lineno);
804 BEGIN INITIAL; resetpos ();
810 * m2flex_GetLineNo - returns the current line number.
813 EXTERN int m2flex_GetLineNo (void)
815 if (currentLine != NULL)
816 return currentLine->lineno;
822 * m2flex_GetColumnNo - returns the column where the current
826 EXTERN int m2flex_GetColumnNo (void)
828 if (currentLine != NULL)
829 return currentLine->column;
835 * m2flex_GetLocation - returns the gcc location_t of the current token.
838 EXTERN location_t m2flex_GetLocation (void)
840 if (currentLine != NULL)
841 return currentLine->location;
847 * GetTotalLines - returns the total number of lines parsed.
850 EXTERN int m2flex_GetTotalLines (void)
856 * yywrap is called when end of file is seen. We push an eof token
857 * and tell the lexical analysis to stop.
862 updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return 1;
865 EXTERN void _M2_m2flex_init (void) {}
866 EXTERN void _M2_m2flex_fini (void) {}