OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zasm/] [zpp.l] - Blame information for rev 26

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 dgisselq
/*******************************************************************************
2
**
3
** Filename:    zpp.l
4
**
5
** Project:     Zip CPU -- a small, lightweight, RISC CPU core
6
**
7
** Purpose:     The preprocessor for the Zip Assembler.
8
**
9
**      This routine strips comments, handles #define's, #ifdef's, and
10
**      #include statements in a C fashion.
11
**
12
**      #define macro's are also defined in the language and therefore
13
**      supposed to be supported, but the support isn't there yet.
14
**
15
** Creator:     Dan Gisselquist, Ph.D.
16
**              Gisselquist Tecnology, LLC
17
**
18
********************************************************************************
19
**
20
** Copyright (C) 2015, Gisselquist Technology, LLC
21
**
22
** This program is free software (firmware): you can redistribute it and/or
23
** modify it under the terms of  the GNU General Public License as published
24
** by the Free Software Foundation, either version 3 of the License, or (at
25
** your option) any later version.
26
**
27
** This program is distributed in the hope that it will be useful, but WITHOUT
28
** ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
29
** FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
30
** for more details.
31
**
32
** You should have received a copy of the GNU General Public License along
33
** with this program.  (It's in the $(ROOT)/doc directory, run make with no
34
** target there if the PDF file isn't present.)  If not, see
35
**  for a copy.
36
**
37
** License:     GPL, v3, as defined and found on www.gnu.org,
38
**              http://www.gnu.org/licenses/gpl.html
39
**
40
**
41
*******************************************************************************/
42
 
43
%{
44
// #include 
45
#include 
46
#include 
47
#include 
48
#include 
49
 
50
using namespace std;
51
 
52 16 dgisselq
int yylex();
53
void    mark_line(void);
54
int     end_of_file(void);
55
void    pushf(const char *fname);
56
 
57 13 dgisselq
// #include "zprepr.tab.h"
58 16 dgisselq
int     ndef = 0, structno = 0;
59
char    *structid = NULL;
60 13 dgisselq
void    stb_define(const char *str);
61
void    stb_args(const char *str);
62
void    stb_macro(const char *value);
63
void    stb_addmacro(const char *value);
64
bool    stb_isdefined(const char *str);
65
const char      *stb_getdefn(const char *str);
66
%}
67 16 dgisselq
%x DEF DFA DFV DFV_EOL INDEF IFDEFV INNOTDEF NODEF NVRDEF COMMENT INSTRUCT
68
%x INDEF_EOL INNOTDEF_EOL GETSTRUCTID
69 13 dgisselq
%option noyywrap
70
%option stack
71
ID [_:A-Za-z][_:A-Za-z0-9]*
72 16 dgisselq
IDDOT {ID}("."{ID})*
73 13 dgisselq
 
74
%%
75
"*/"            { yy_pop_state(); }
76
[^*]+           { /* Ignore comments */ }
77
"*"+[^/]        { /* Ignore comments */ }
78
^"#include"[ \t]+\"[^\"]+\"     {
79
                char *ptr = &yytext[9], *start, *end, *str;
80
                while(isspace(*ptr))
81
                        ptr++;
82 16 dgisselq
                start = ++ptr;
83 13 dgisselq
                ptr++;
84
                while((*ptr)&&(*ptr != '\"'))
85
                        ptr++;
86
                *ptr = '\0';
87 16 dgisselq
                pushf(start);
88 13 dgisselq
                // push_file_state(yylineno); // and filename ...
89 16 dgisselq
                mark_line();
90 13 dgisselq
        }
91
^"#define"[ \t]+        { yy_push_state(DEF); }
92
 /* <*>^"#line"[ \t]+(0-9)+[ \t]+["][^"]*["][ \t]*\n       { } */
93 16 dgisselq
{IDDOT}/[^(]    {
94 13 dgisselq
                stb_define(yytext);
95
                BEGIN DFV;
96
        }
97 16 dgisselq
{IDDOT}/[(]     { stb_define(yytext); BEGIN DFA; }
98
"("[^)]+")"                             {
99
                /* Process macro arguments */
100 13 dgisselq
                stb_args(yytext);
101
                BEGIN DFV;
102
        }
103
[ \t]+  { /* Ignore initial spaces */ }
104 16 dgisselq
[^ \t\n]*       {/* Parse to end of line, get value for our define */
105 13 dgisselq
                stb_macro(yytext);
106 16 dgisselq
        }
107
[ \t]*((;|"//").*)?$    {/* Parse to end of line, get value for our define */
108 13 dgisselq
                yy_pop_state();
109
        }
110 16 dgisselq
[ \t]*"\\"[ \t]*((;|"//").*)?\n {/* Continue onto next line */
111
                fprintf(yyout, "\n"); mark_line(); yylineno++;
112
                stb_macro("\n");
113
        }
114 13 dgisselq
^[ \t]+.[dD][aA][tT][aA]?       { fprintf(yyout, "\tWORD"); }
115
^"#defcont"[ \t]+       { yy_push_state(DFV); }
116
^"#ifdef"[ \t]* { ndef = 0; yy_push_state(IFDEFV); }
117
^"#ifndef"[ \t]*        { ndef = 1; yy_push_state(IFDEFV); }
118 16 dgisselq
{IDDOT} {
119 13 dgisselq
                bool    known = stb_isdefined(yytext);
120
                if ( ((known)&&(ndef==0)) || ((!known)&&(ndef!=0)) ) {
121
                        BEGIN INDEF_EOL;
122
                } else {
123
                        BEGIN INNOTDEF_EOL;
124
                }
125
        }
126
        /* Not yet: ^"#if"[ \t]*                { yy_push_state(IFDEFE); }
127
        /* Not yet: ^"#if"[ \t]*                { yy_push_state(IFDEFE); }
128
        /* Not yet:  { yy_push_state(IFDEFE); } */
129
        /* ^"#elsif"[ \t]*      { yy_pop_state(); yy_push_state(IFDEFE); } */
130
[ \t]*$         { BEGIN INDEF; }
131
(;|"//").*$             { BEGIN INDEF; }
132
[ \t]*$         { BEGIN INNOTDEF; }
133
(;|"//").*$     { BEGIN INNOTDEF; }
134 16 dgisselq
[^ \t\n].*$             { BEGIN INDEF; fprintf(stderr, "WARNING! Unexpected characters on IFDEF line, \'%s\'\n", yytext); mark_line(); }
135
[^ \t\n].*$     { BEGIN INNOTDEF; fprintf(stderr, "WARNING! Unexpected characters on IFNDEF line, %s\n", yytext); mark_line(); }
136 13 dgisselq
^"#else"[ \t]*((;|"//").*)?$    { BEGIN NODEF; }
137
^"#else"[ \t]*((;|"//").*)?$            { BEGIN INDEF; }
138
(.*)                    { }
139
^"#elsif"[ \t]*         { BEGIN NVRDEF; }
140 26 dgisselq
^"#endif"[ \t]*((;|"//").*)?$   { yy_pop_state(); }
141
^"#endif"[ \t]*"/*"     { BEGIN COMMENT; }
142 13 dgisselq
<*>^"#endif"[ \t]*         { fprintf(stderr, "ERR: Unknown endif!!\n");}
143 16 dgisselq
^"#struct"[ \t]*        {
144
                yy_push_state(GETSTRUCTID); structno  = 0; }
145 26 dgisselq
<*>^"#"{ID}[ \t]*          { fprintf(stderr, "ERR: Unrecognized preprocessor instruction, %s\n", yytext);}
146 16 dgisselq
{ID}/[ \t\n;/]  { BEGIN INSTRUCT;
147
                structid = strdup(yytext);
148
                }
149
{ID}("."{ID})*  {
150
                fprintf(yyout, "\t%s.%s\tequ\t%d", structid, yytext, structno++); }
151
^"#endstruct".*$        { yy_pop_state(); }
152 13 dgisselq
        /* Not yet: ^"#struct"[ \t]*    {}      */
153
        /* Not yet: ^"#endstruct"[ \t]* {}      */
154
        /* Not yet: ^"#seg"[ \t]*       {}      */
155
.*              { /* Ignore everything in these states*/ }
156
{ID}/[^(]       {
157
                if (stb_isdefined(yytext))
158
                        fprintf(yyout, "%s", stb_getdefn(yytext));
159
                else
160
                        fprintf(yyout, "%s", yytext);
161
        }
162 16 dgisselq
<*>[ \t]*"//".*$   { /* Ignore (trailing) comment only lines */ }
163
<*>[ \t]*";".*$            { /* Ignore (trailing) comment only lines */ }
164 26 dgisselq
<*>"#warning".*$   { fprintf(stderr, "WARNING: %s\n", &yytext[8]); }
165
<*>"#error".*$             { fprintf(stderr, "ERROR: %s\n", &yytext[8]); exit(-1); }
166 13 dgisselq
<*>"/*"                    { yy_push_state(COMMENT); }
167
<*>[ \t]+          { ECHO; }
168 16 dgisselq
<*>\n                      { ECHO; yylineno++; mark_line(); }
169 13 dgisselq
        /* <*>.                    { printf("Unmatched \'%c\'\n", yytext[0]); } */
170 26 dgisselq
<>       { fprintf(stderr, "Unexpected EOF!  Expecting #endif\n"); }
171
<>               { fprintf(stderr, "Unexpected EOF!  Expecting #endif\n"); }
172
<>       { fprintf(stderr, "Unexpected EOF!  Expecting */\n"); }
173
<>       { fprintf(stderr, "Unexpected EOF!  Expecting #endstruct\n"); }
174
<>       { fprintf(stderr, "Unexpected EOF!  Expecting #struct ID, then #endstruct\n"); }
175
<> { fprintf(stderr, "Unexpected EOF!  Expecting end of line\n"); }
176
<        { fprintf(stderr, "Unexpected EOF  Expecting end of line, then #endif\n"); }
177
<>       { if (end_of_file()) yyterminate(); }
178 13 dgisselq
 
179
%%
180
 
181
class   SYMTABLE_ENTRY {
182
private:
183
        std::string     &trim(std::string &s) {
184
                std::string::iterator   ptr = s.end();
185
 
186
                while((ptr >= s.begin())&&(isspace(*ptr)))
187
                        *ptr-- = '\0';
188
 
189
                return s;
190
        }
191
 
192
public:
193
        std::string     m_name, m_value, m_args;
194
        SYMTABLE_ENTRY(const char *str) : m_name(str) {
195
                trim(m_name);
196
        }
197
        SYMTABLE_ENTRY &operator+=(const char *str) {
198
                const char      *start = str;
199
 
200
                while(isspace(*start))
201
                        start++;
202
                if (m_value.length()!=0)
203
                        m_value += " ";
204
 
205
                std::string     trimd(start);
206
                trim(trimd);
207
                m_value += trimd;
208
 
209
                /*
210
                printf("ENTRY::SYMBOL \'%s\' NOW = \'%s\'\n",
211
                        m_name.c_str(), m_value.c_str());
212
                */
213
                return *this;
214
        }
215
        SYMTABLE_ENTRY &setargs(const char *str) {
216
                m_args += str;
217
                return *this;
218
        }
219
 
220 16 dgisselq
        const std::string &getdefn(void) {
221 13 dgisselq
                return m_value;
222
        }
223
};
224
 
225
class   SYMBOL_TABLE {
226
private:
227
        typedef SYMTABLE_ENTRY  *TBLV;
228
        typedef std::list       TBLT;
229
 
230
        TBLT    m_tbl;
231
        TBLT::iterator  lookup(const char *str) {
232
                TBLT::iterator  i = m_tbl.begin();
233
                for(; (i!= m_tbl.end())&&(strcmp(str, (*i)->m_name.c_str())>0); i++)
234
                        ;
235
                if ((i != m_tbl.end())&&(strcmp(str, (*i)->m_name.c_str())==0))
236
                        return i;
237
                return m_tbl.end();
238
        }
239
 
240
public:
241
        SYMBOL_TABLE(void) {}
242
 
243
        void define(const char *str) {
244
                SYMTABLE_ENTRY  *v = new SYMTABLE_ENTRY(str);
245
                TBLT::iterator  i = m_tbl.begin();
246
                for(; (i!= m_tbl.end())&&(strcmp(str, (*i)->m_name.c_str())>0); i++)
247
                        ;
248
                m_tbl.insert(i, v);
249
 
250
                // printf("SYMS::Defining SYMBOL: \'%s\'\n", str);
251
        }
252
 
253
        bool defined(const char *str) {
254
                TBLT::iterator  i = lookup(str);
255
                if (i==m_tbl.end())
256
                        return false;
257
                else
258
                        return true;
259
        }
260
 
261
 
262
        void    undefine(const char *str) {
263
                TBLT::iterator  i = lookup(str);
264
                if (i == m_tbl.end())
265
                        return;
266
                TBLV    v = (*i);
267
                m_tbl.erase(i);
268
                delete  v;
269
        }
270
 
271
        void    addmacro(const char *name, const char *str) {
272
                TBLT::iterator i = lookup(name);
273
                if (i == m_tbl.end()) {
274
                        fprintf(stderr, "INTERNAL ERR, %s NOT DEFINED!\n", name);
275
                } *(*i) += str;
276
        }
277
 
278
        void    addargs(const char *name, const char *str) {
279
                TBLT::iterator i = lookup(name);
280
                if (i == m_tbl.end()) {
281
                        fprintf(stderr, "INTERNAL ERR, %s NOT DEFINED!\n", name);
282
                } (*i)->setargs(str);
283
        }
284
        const   char *getdefn(const char *name) {
285
                TBLT::iterator i = lookup(name);
286
                if (i == m_tbl.end()) {
287
                        fprintf(stderr, "INTERNAL ERR, %s NOT DEFINED!\n", name);
288
                        return NULL;
289
                } (*i)->getdefn().c_str();
290
        }
291
 
292
};
293
 
294
SYMTABLE_ENTRY  *last = NULL;
295
SYMBOL_TABLE    syms;
296
std::string     last_define;
297
 
298
void    stb_define(const char *str) {
299
        if (syms.defined(str)) {
300
                fprintf(stderr, "WARNING!  Symbol \'%s\' is already defined!\n", str);
301
                syms.undefine(str);
302
        }
303
 
304
        syms.define(str);
305
        last_define = str;
306
}
307
 
308
void    stb_args(const char *args) {
309
        syms.addargs(last_define.c_str(), args);
310
}
311
 
312
void    stb_macro(const char *value) {
313
        syms.addmacro(last_define.c_str(), value);
314
}
315
 
316
void    stb_addmacro(const char *value) {
317
        syms.addmacro(last_define.c_str(),value);
318
}
319
 
320
bool    stb_isdefined(const char *str) {
321
        return syms.defined(str);
322
}
323
 
324
const char *stb_getdefn(const char *str) {
325
        return syms.getdefn(str);
326
}
327
 
328 16 dgisselq
class   BUFSTACK {
329
public:
330
        FILE            *m_fp;
331
        char            *m_fname;
332
        int             m_lineno;
333
        BUFSTACK        *m_prev;
334
        YY_BUFFER_STATE m_bs;
335
 
336
        static  BUFSTACK        *curbs;
337
        static  const char      *curfilename;
338
 
339
        BUFSTACK(void) {
340
                m_fp = stdin;
341
 
342
                if (curbs)
343
                        curbs->m_lineno = yylineno;
344
                m_prev = curbs;
345
                // m_bs = yy_create_buffer(fp, YY_BUF_SIZE);
346
                m_fname = strdup("(stdin)");
347
                // yy_switch_to_buffer(m_bs);
348
                m_bs = NULL;
349
                curbs = this;
350
                m_lineno = 1;
351
                curfilename = m_fname;
352
 
353
                yyrestart(m_fp);
354
                yylineno = 1;
355
        }
356
 
357
        BUFSTACK(const char *fname) {
358
                m_fp = fopen(fname, "r");
359
                if (!m_fp) {
360
                        fprintf(stderr, "Cannot open %s\n", fname);
361
                        perror("O/S Err:");
362
                        exit(-1);
363
                }
364
 
365
                if (curbs)
366
                        curbs->m_lineno = yylineno;
367
                m_prev = curbs;
368
                m_bs = yy_create_buffer(m_fp, YY_BUF_SIZE);
369
                m_fname = strdup(fname);
370
                yy_switch_to_buffer(m_bs);
371
                curbs = this;
372
                m_lineno = 1;
373
                curfilename = m_fname;
374
 
375
                yyrestart(m_fp);
376
                yylineno = 1;
377
        }
378
 
379
        ~BUFSTACK(void) {
380
                // fprintf(stderr, "DELETING(%s)\n", m_fname);
381
                fclose(m_fp);
382
                free(m_fname);
383
                if (m_bs)
384
                        yy_delete_buffer(m_bs);
385
                curbs = m_prev;
386
 
387
                if (curbs) {
388
                        yy_switch_to_buffer(curbs->m_bs);
389
                        yylineno = curbs->m_lineno;
390
                        curfilename = curbs->m_fname;
391
                }
392
        }
393
 
394
        void    mark(void) {
395
                FILE    *fp = yyout;
396
                if (!fp) fp = stdout;
397
                fprintf(fp, "#line %d \"%s\"\n", yylineno, m_fname);
398
        }
399
 
400 26 dgisselq
        void    markline(void) {
401
                FILE    *fp = yyout;
402
                if (!fp) fp = stdout;
403
                fprintf(fp, "#line %d\n", yylineno);
404
        }
405
 
406 16 dgisselq
        static  void pop(void) {
407
                // fprintf(stderr, "POP! (%s)\n", curbs->m_fname);
408
                if (curbs)
409
                        delete curbs;
410
        }
411
};
412
 
413
BUFSTACK *BUFSTACK::curbs = NULL;
414
const char *BUFSTACK::curfilename = NULL;
415
 
416
int             last_marked_line = -1;
417
const char      *last_marked_file = NULL;
418
void    mark_line(void) {
419
        if ((yylineno != last_marked_line+1)||(BUFSTACK::curfilename != last_marked_file))
420 26 dgisselq
                if (BUFSTACK::curfilename == last_marked_file)
421
                        BUFSTACK::curbs->markline();
422
                else BUFSTACK::curbs->mark();
423 16 dgisselq
        last_marked_line = yylineno;
424
        last_marked_file = BUFSTACK::curfilename;
425
}
426
 
427
int     end_of_file(void) {
428
        BUFSTACK::pop();
429
        return (BUFSTACK::curbs == NULL);
430
}
431
 
432
void    pushf(const char *fname) {
433
        BUFSTACK        *bs = new BUFSTACK(fname);
434
}
435
 
436 13 dgisselq
int main(int argc, char **argv) {
437 16 dgisselq
        yylineno = 1;
438
        if (argc < 2) { // Stdin only
439
                BUFSTACK::curbs = new BUFSTACK();
440
                yylex();
441
        } else {
442
                for(int argn=1; argn
443
                        BUFSTACK        *bs = new BUFSTACK(argv[argn]);
444
                        mark_line();
445
                        yylex();
446
                        // delete       bs;
447
                }
448
        }
449 26 dgisselq
 
450
        return 0;
451 13 dgisselq
}
452
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.