forked from mbbill/flexbison
-
Notifications
You must be signed in to change notification settings - Fork 10
/
fb2-3.l
107 lines (88 loc) · 2.51 KB
/
fb2-3.l
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* Companion source code for "flex & bison", published by O'Reilly
* Media, ISBN 978-0-596-15597-1
* Copyright (c) 2009, Taughannock Networks. All rights reserved.
* See the README file for license conditions and contact info.
* $Header: /home/johnl/flnb/code/RCS/fb2-3.l,v 2.3 2010/01/04 02:43:58 johnl Exp $
*/
/* fb2-3 skeleton for include files */
%option noyywrap warn nodefault
%x IFILE
struct bufstack {
struct bufstack *prev; /* previous entry */
YY_BUFFER_STATE bs; /* saved buffer */
int lineno; /* saved line number */
char *filename; /* name of this file */
FILE *f; /* current file */
} *curbs = 0;
char *curfilename; /* name of current input file */
int newfile(char *fn);
int popfile(void);
%%
^"#"[ \t]*include[ \t]*[\"<] { BEGIN IFILE; }
<IFILE>[^ \t\n\">]+ {
{ int c;
while((c = input()) && c != '\n') ;
}
yylineno++;
if(!newfile(yytext))
yyterminate(); /* no such file */
BEGIN INITIAL;
}
<IFILE>.|\n { fprintf(stderr, "%4d bad include line\n", yylineno);
yyterminate();
}
^. { fprintf(yyout, "%4d %s", yylineno, yytext); }
^\n { fprintf(yyout, "%4d %s", yylineno++, yytext); }
\n { ECHO; yylineno++; }
. { ECHO; }
<<EOF>> { if(!popfile()) yyterminate(); }
%%
main(int argc, char **argv)
{
if(argc < 2) {
fprintf(stderr, "need filename\n");
return 1;
}
if(newfile(argv[1]))
yylex();
}
int
newfile(char *fn)
{
FILE *f = fopen(fn, "r");
struct bufstack *bs = malloc(sizeof(struct bufstack));
/* die if no file or no room */
if(!f) { perror(fn); return 0; }
if(!bs) { perror("malloc"); exit(1); }
/* remember state */
if(curbs)curbs->lineno = yylineno;
bs->prev = curbs;
/* set up current entry */
bs->bs = yy_create_buffer(f, YY_BUF_SIZE);
bs->f = f;
bs->filename = fn;
yy_switch_to_buffer(bs->bs);
curbs = bs;
yylineno = 1;
curfilename = fn;
return 1;
}
int
popfile(void)
{
struct bufstack *bs = curbs;
struct bufstack *prevbs;
if(!bs) return 0;
/* get rid of current entry */
fclose(bs->f);
yy_delete_buffer(bs->bs);
/* switch back to previous */
prevbs = bs->prev;
free(bs);
if(!prevbs) return 0;
yy_switch_to_buffer(prevbs->bs);
curbs = prevbs;
yylineno = curbs->lineno;
curfilename = curbs->filename;
return 1;
}