~ubuntu-branches/ubuntu/natty/geany/natty

« back to all changes in this revision

Viewing changes to tagmanager/verilog.c

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2010-08-07 03:23:12 UTC
  • mfrom: (1.4.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20100807032312-ot70ac9d50cn79we
Tags: upstream-0.19
ImportĀ upstreamĀ versionĀ 0.19

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
*   $Id: verilog.c 4474 2009-12-07 17:51:37Z ntrel $
 
3
*
 
4
*   Copyright (c) 2003, Darren Hiebert
 
5
*
 
6
*   This source code is released for free distribution under the terms of the
 
7
*   GNU General Public License.
 
8
*
 
9
*   This module contains functions for generating tags for the Verilog HDL
 
10
*   (Hardware Description Language).
 
11
*
 
12
*   Language definition documents:
 
13
*       http://www.eg.bucknell.edu/~cs320/verilog/verilog-manual.html
 
14
*       http://www.sutherland-hdl.com/on-line_ref_guide/vlog_ref_top.html
 
15
*       http://www.verilog.com/VerilogBNF.html
 
16
*       http://eesun.free.fr/DOC/VERILOG/verilog_manual1.html
 
17
*/
 
18
 
 
19
/*
 
20
 *   INCLUDE FILES
 
21
 */
 
22
#include "general.h"  /* must always come first */
 
23
 
 
24
#include <string.h>
 
25
#include <setjmp.h>
 
26
 
 
27
#include "keyword.h"
 
28
#include "parse.h"
 
29
#include "read.h"
 
30
#include "vstring.h"
 
31
#include "get.h"
 
32
 
 
33
/*
 
34
 *   DATA DECLARATIONS
 
35
 */
 
36
typedef enum eException { ExceptionNone, ExceptionEOF } exception_t;
 
37
 
 
38
typedef enum {
 
39
        K_UNDEFINED = -1,
 
40
        K_CONSTANT,
 
41
        K_EVENT,
 
42
        K_FUNCTION,
 
43
        K_MODULE,
 
44
        K_NET,
 
45
        K_PORT,
 
46
        K_REGISTER,
 
47
        K_TASK
 
48
} verilogKind;
 
49
 
 
50
typedef struct {
 
51
        const char *keyword;
 
52
        verilogKind kind;
 
53
} keywordAssoc;
 
54
 
 
55
/*
 
56
 *   DATA DEFINITIONS
 
57
 */
 
58
static int Ungetc;
 
59
static int Lang_verilog;
 
60
static jmp_buf Exception;
 
61
 
 
62
static kindOption VerilogKinds [] = {
 
63
 { TRUE, 'c', "variable",  "constants (define, parameter, specparam)" },
 
64
 { TRUE, 'e', "typedef",     "events" },
 
65
 { TRUE, 'f', "function",  "functions" },
 
66
 { TRUE, 'm', "class",    "modules" },
 
67
 { TRUE, 'n', "variable",  "net data types" },
 
68
 { TRUE, 'p', "variable",  "ports" },
 
69
 { TRUE, 'r', "variable",  "register data types" },
 
70
 { TRUE, 't', "function",  "tasks" }
 
71
};
 
72
 
 
73
static keywordAssoc VerilogKeywordTable [] = {
 
74
        { "`define",   K_CONSTANT },
 
75
        { "event",     K_EVENT },
 
76
        { "function",  K_FUNCTION },
 
77
        { "inout",     K_PORT },
 
78
        { "input",     K_PORT },
 
79
        { "integer",   K_REGISTER },
 
80
        { "module",    K_MODULE },
 
81
        { "output",    K_PORT },
 
82
        { "parameter", K_CONSTANT },
 
83
        { "real",      K_REGISTER },
 
84
        { "realtime",  K_REGISTER },
 
85
        { "reg",       K_REGISTER },
 
86
        { "specparam", K_CONSTANT },
 
87
        { "supply0",   K_NET },
 
88
        { "supply1",   K_NET },
 
89
        { "task",      K_TASK },
 
90
        { "time",      K_REGISTER },
 
91
        { "tri0",      K_NET },
 
92
        { "tri1",      K_NET },
 
93
        { "triand",    K_NET },
 
94
        { "tri",       K_NET },
 
95
        { "trior",     K_NET },
 
96
        { "trireg",    K_NET },
 
97
        { "wand",      K_NET },
 
98
        { "wire",      K_NET },
 
99
        { "wor",       K_NET }
 
100
};
 
101
 
 
102
/*
 
103
 *   FUNCTION DEFINITIONS
 
104
 */
 
105
 
 
106
static void initialize (const langType language)
 
107
{
 
108
        size_t i;
 
109
        const size_t count =
 
110
                        sizeof (VerilogKeywordTable) / sizeof (VerilogKeywordTable [0]);
 
111
        Lang_verilog = language;
 
112
        for (i = 0  ;  i < count  ;  ++i)
 
113
        {
 
114
                const keywordAssoc* const p = &VerilogKeywordTable [i];
 
115
                addKeyword (p->keyword, language, (int) p->kind);
 
116
        }
 
117
}
 
118
 
 
119
static void vUngetc (int c)
 
120
{
 
121
        Assert (Ungetc == '\0');
 
122
        Ungetc = c;
 
123
}
 
124
 
 
125
static int vGetc (void)
 
126
{
 
127
        int c;
 
128
        if (Ungetc == '\0')
 
129
                c = fileGetc ();
 
130
        else
 
131
        {
 
132
                c = Ungetc;
 
133
                Ungetc = '\0';
 
134
        }
 
135
        if (c == '/')
 
136
        {
 
137
                int c2 = fileGetc ();
 
138
                if (c2 == EOF)
 
139
                        longjmp (Exception, (int) ExceptionEOF);
 
140
                else if (c2 == '/')  /* strip comment until end-of-line */
 
141
                {
 
142
                        do
 
143
                                c = fileGetc ();
 
144
                        while (c != '\n'  &&  c != EOF);
 
145
                }
 
146
                else if (c2 == '*')  /* strip block comment */
 
147
                {
 
148
                        c = skipOverCComment();
 
149
                }
 
150
                else
 
151
                {
 
152
                        fileUngetc (c2);
 
153
                }
 
154
        }
 
155
        else if (c == '"')  /* strip string contents */
 
156
        {
 
157
                int c2;
 
158
                do
 
159
                        c2 = fileGetc ();
 
160
                while (c2 != '"'  &&  c2 != EOF);
 
161
                c = '@';
 
162
        }
 
163
        if (c == EOF)
 
164
                longjmp (Exception, (int) ExceptionEOF);
 
165
        return c;
 
166
}
 
167
 
 
168
static boolean isIdentifierCharacter (const int c)
 
169
{
 
170
        return (boolean)(isalnum (c)  ||  c == '_'  ||  c == '`');
 
171
}
 
172
 
 
173
static int skipWhite (int c)
 
174
{
 
175
        while (isspace (c))
 
176
                c = vGetc ();
 
177
        return c;
 
178
}
 
179
 
 
180
static int skipPastMatch (const char *const pair)
 
181
{
 
182
        const int begin = pair [0], end = pair [1];
 
183
        int matchLevel = 1;
 
184
        int c;
 
185
        do
 
186
        {
 
187
                c = vGetc ();
 
188
                if (c == begin)
 
189
                        ++matchLevel;
 
190
                else if (c == end)
 
191
                        --matchLevel;
 
192
        }
 
193
        while (matchLevel > 0);
 
194
        return vGetc ();
 
195
}
 
196
 
 
197
static boolean readIdentifier (vString *const name, int c)
 
198
{
 
199
        vStringClear (name);
 
200
        if (isIdentifierCharacter (c))
 
201
        {
 
202
                while (isIdentifierCharacter (c))
 
203
                {
 
204
                        vStringPut (name, c);
 
205
                        c = vGetc ();
 
206
                }
 
207
                vUngetc (c);
 
208
                vStringTerminate (name);
 
209
        }
 
210
        return (boolean)(name->length > 0);
 
211
}
 
212
 
 
213
static void tagNameList (const verilogKind kind, int c)
 
214
{
 
215
        vString *name = vStringNew ();
 
216
        boolean repeat;
 
217
        Assert (isIdentifierCharacter (c));
 
218
        do
 
219
        {
 
220
                repeat = FALSE;
 
221
                if (isIdentifierCharacter (c))
 
222
                {
 
223
                        readIdentifier (name, c);
 
224
                        makeSimpleTag (name, VerilogKinds, kind);
 
225
                }
 
226
                else
 
227
                        break;
 
228
                c = skipWhite (vGetc ());
 
229
                if (c == '[')
 
230
                        c = skipPastMatch ("[]");
 
231
                c = skipWhite (c);
 
232
                if (c == '=')
 
233
                {
 
234
                        if (c == '{')
 
235
                                skipPastMatch ("{}");
 
236
                        else
 
237
                        {
 
238
                                do
 
239
                                        c = vGetc ();
 
240
                                while (c != ','  &&  c != ';');
 
241
                        }
 
242
                }
 
243
                if (c == ',')
 
244
                {
 
245
                        c = skipWhite (vGetc ());
 
246
                        repeat = TRUE;
 
247
                }
 
248
                else
 
249
                        repeat = FALSE;
 
250
        } while (repeat);
 
251
        vStringDelete (name);
 
252
        vUngetc (c);
 
253
}
 
254
 
 
255
static void findTag (vString *const name)
 
256
{
 
257
        const verilogKind kind = (verilogKind) lookupKeyword (vStringValue (name), Lang_verilog);
 
258
        if (kind == K_CONSTANT && vStringItem (name, 0) == '`')
 
259
        {
 
260
                /* Bug #961001: Verilog compiler directives are line-based. */
 
261
                int c = skipWhite (vGetc ());
 
262
                readIdentifier (name, c);
 
263
                makeSimpleTag (name, VerilogKinds, kind);
 
264
                /* Skip the rest of the line. */
 
265
                do {
 
266
                        c = vGetc();
 
267
                } while (c != '\n');
 
268
                vUngetc (c);
 
269
        }
 
270
        else if (kind != K_UNDEFINED)
 
271
        {
 
272
                int c = skipWhite (vGetc ());
 
273
 
 
274
                /* Many keywords can have bit width.
 
275
                *   reg [3:0] net_name;
 
276
                *   inout [(`DBUSWIDTH-1):0] databus;
 
277
                */
 
278
                if (c == '(')
 
279
                        c = skipPastMatch ("()");
 
280
                c = skipWhite (c);
 
281
                if (c == '[')
 
282
                        c = skipPastMatch ("[]");
 
283
                c = skipWhite (c);
 
284
                if (c == '#')
 
285
                {
 
286
                        c = vGetc ();
 
287
                        if (c == '(')
 
288
                                c = skipPastMatch ("()");
 
289
                }
 
290
                c = skipWhite (c);
 
291
                if (isIdentifierCharacter (c))
 
292
                        tagNameList (kind, c);
 
293
        }
 
294
}
 
295
 
 
296
static void findVerilogTags (void)
 
297
{
 
298
        vString *const name = vStringNew ();
 
299
        volatile boolean newStatement = TRUE;
 
300
        volatile int c = '\0';
 
301
        exception_t exception = (exception_t) setjmp (Exception);
 
302
 
 
303
        if (exception == ExceptionNone) while (c != EOF)
 
304
        {
 
305
                c = vGetc ();
 
306
                switch (c)
 
307
                {
 
308
                        case ';':
 
309
                        case '\n':
 
310
                                newStatement = TRUE;
 
311
                                break;
 
312
 
 
313
                        case ' ':
 
314
                        case '\t':
 
315
                                break;
 
316
 
 
317
                        default:
 
318
                                if (newStatement && readIdentifier (name, c))
 
319
                                        findTag (name);
 
320
                                newStatement = FALSE;
 
321
                                break;
 
322
                }
 
323
        }
 
324
        vStringDelete (name);
 
325
}
 
326
 
 
327
extern parserDefinition* VerilogParser (void)
 
328
{
 
329
        static const char *const extensions [] = { "v", NULL };
 
330
        parserDefinition* def = parserNew ("Verilog");
 
331
        def->kinds      = VerilogKinds;
 
332
        def->kindCount  = KIND_COUNT (VerilogKinds);
 
333
        def->extensions = extensions;
 
334
        def->parser     = findVerilogTags;
 
335
        def->initialize = initialize;
 
336
        return def;
 
337
}
 
338
 
 
339
/* vi:set tabstop=4 shiftwidth=4: */