2 * Copyright (c) 2003, Darren Hiebert
4 * This source code is released for free distribution under the terms of the
5 * GNU General Public License version 2 or (at your option) any later version.
7 * This module contains functions for generating tags for the Verilog HDL
8 * (Hardware Description Language).
10 * Language definition documents:
11 * http://www.eg.bucknell.edu/~cs320/verilog/verilog-manual.html
12 * http://www.sutherland-hdl.com/on-line_ref_guide/vlog_ref_top.html
13 * http://www.verilog.com/VerilogBNF.html
14 * http://eesun.free.fr/DOC/VERILOG/verilog_manual1.html
20 #include "general.h" /* must always come first */
37 typedef enum eException
{ ExceptionNone
, ExceptionEOF
} exception_t
;
55 static int Lang_verilog
;
56 static jmp_buf Exception
;
58 static kindOption VerilogKinds
[] = {
59 { true, 'c', "constant", "constants (define, parameter, specparam)" },
60 { true, 'e', "event", "events" },
61 { true, 'f', "function", "functions" },
62 { true, 'm', "module", "modules" },
63 { true, 'n', "net", "net data types" },
64 { true, 'p', "port", "ports" },
65 { true, 'r', "register", "register data types" },
66 { true, 't', "task", "tasks" }
69 static keywordTable VerilogKeywordTable
[] = {
70 { "`define", K_CONSTANT
},
72 { "function", K_FUNCTION
},
75 { "integer", K_REGISTER
},
76 { "module", K_MODULE
},
78 { "parameter", K_CONSTANT
},
79 { "real", K_REGISTER
},
80 { "realtime", K_REGISTER
},
81 { "reg", K_REGISTER
},
82 { "specparam", K_CONSTANT
},
86 { "time", K_REGISTER
},
99 * FUNCTION DEFINITIONS
102 static void initialize (const langType language
)
105 const size_t count
= ARRAY_SIZE (VerilogKeywordTable
);
106 Lang_verilog
= language
;
107 for (i
= 0 ; i
< count
; ++i
)
109 const keywordTable
* const p
= &VerilogKeywordTable
[i
];
110 addKeyword (p
->name
, language
, (int) p
->id
);
114 static void vUngetc (int c
)
116 Assert (Ungetc
== '\0');
120 static int vGetc (void)
124 c
= getcFromInputFile ();
132 int c2
= getcFromInputFile ();
134 longjmp (Exception
, (int) ExceptionEOF
);
135 else if (c2
== '/') /* strip comment until end-of-line */
138 c
= getcFromInputFile ();
139 while (c
!= '\n' && c
!= EOF
);
141 else if (c2
== '*') /* strip block comment */
143 c
= cppSkipOverCComment();
147 ungetcToInputFile (c2
);
150 else if (c
== '"') /* strip string contents */
154 c2
= getcFromInputFile ();
155 while (c2
!= '"' && c2
!= EOF
);
159 longjmp (Exception
, (int) ExceptionEOF
);
163 static bool isIdentifierCharacter (const int c
)
165 return (bool)(isalnum (c
) || c
== '_' || c
== '`');
168 static int skipWhite (int c
)
175 static int skipPastMatch (const char *const pair
)
177 const int begin
= pair
[0], end
= pair
[1];
188 while (matchLevel
> 0);
192 static bool readIdentifier (vString
*const name
, int c
)
195 if (isIdentifierCharacter (c
))
197 while (isIdentifierCharacter (c
))
199 vStringPut (name
, c
);
204 return (bool)(name
->length
> 0);
207 static void tagNameList (const verilogKind kind
, int c
)
209 vString
*name
= vStringNew ();
211 Assert (isIdentifierCharacter (c
));
215 if (isIdentifierCharacter (c
))
217 readIdentifier (name
, c
);
218 makeSimpleTag (name
, VerilogKinds
, kind
);
222 c
= skipWhite (vGetc ());
224 c
= skipPastMatch ("[]");
228 c
= skipWhite (vGetc ());
230 skipPastMatch ("{}");
235 while (c
!= ',' && c
!= ';');
240 c
= skipWhite (vGetc ());
246 vStringDelete (name
);
250 static void findTag (vString
*const name
)
252 const verilogKind kind
= (verilogKind
) lookupKeyword (vStringValue (name
), Lang_verilog
);
253 if (kind
== K_CONSTANT
&& vStringItem (name
, 0) == '`')
255 /* Bug #961001: Verilog compiler directives are line-based. */
256 int c
= skipWhite (vGetc ());
257 readIdentifier (name
, c
);
258 makeSimpleTag (name
, VerilogKinds
, kind
);
259 /* Skip the rest of the line. */
265 else if (kind
!= K_UNDEFINED
)
267 int c
= skipWhite (vGetc ());
269 /* Many keywords can have bit width.
270 * reg [3:0] net_name;
271 * inout [(`DBUSWIDTH-1):0] databus;
274 c
= skipPastMatch ("()");
277 c
= skipPastMatch ("[]");
283 c
= skipPastMatch ("()");
286 if (isIdentifierCharacter (c
))
287 tagNameList (kind
, c
);
291 static void findVerilogTags (void)
293 vString
*const name
= vStringNew ();
294 volatile bool newStatement
= true;
295 volatile int c
= '\0';
296 exception_t exception
= (exception_t
) setjmp (Exception
);
298 if (exception
== ExceptionNone
) while (c
!= EOF
)
313 if (newStatement
&& readIdentifier (name
, c
))
315 newStatement
= false;
319 vStringDelete (name
);
322 extern parserDefinition
* VerilogParser (void)
324 static const char *const extensions
[] = { "v", NULL
};
325 parserDefinition
* def
= parserNew ("Verilog");
326 def
->kinds
= VerilogKinds
;
327 def
->kindCount
= ARRAY_SIZE (VerilogKinds
);
328 def
->extensions
= extensions
;
329 def
->parser
= findVerilogTags
;
330 def
->initialize
= initialize
;