4 * Copyright (c) 2003, Darren Hiebert
6 * This source code is released for free distribution under the terms of the
7 * GNU General Public License.
9 * This module contains functions for generating tags for the Verilog HDL
10 * (Hardware Description Language).
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
22 #include "general.h" /* must always come first */
36 typedef enum eException
{ ExceptionNone
, ExceptionEOF
} exception_t
;
59 static int Lang_verilog
;
60 static jmp_buf Exception
;
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" }
73 static keywordAssoc VerilogKeywordTable
[] = {
74 { "`define", K_CONSTANT
},
76 { "function", K_FUNCTION
},
79 { "integer", K_REGISTER
},
80 { "module", K_MODULE
},
82 { "parameter", K_CONSTANT
},
83 { "real", K_REGISTER
},
84 { "realtime", K_REGISTER
},
85 { "reg", K_REGISTER
},
86 { "specparam", K_CONSTANT
},
90 { "time", K_REGISTER
},
103 * FUNCTION DEFINITIONS
106 static void initialize (const langType language
)
110 sizeof (VerilogKeywordTable
) / sizeof (VerilogKeywordTable
[0]);
111 Lang_verilog
= language
;
112 for (i
= 0 ; i
< count
; ++i
)
114 const keywordAssoc
* const p
= &VerilogKeywordTable
[i
];
115 addKeyword (p
->keyword
, language
, (int) p
->kind
);
119 static void vUngetc (int c
)
121 Assert (Ungetc
== '\0');
125 static int vGetc (void)
137 int c2
= fileGetc ();
139 longjmp (Exception
, (int) ExceptionEOF
);
140 else if (c2
== '/') /* strip comment until end-of-line */
144 while (c
!= '\n' && c
!= EOF
);
146 else if (c2
== '*') /* strip block comment */
148 c
= skipOverCComment();
155 else if (c
== '"') /* strip string contents */
160 while (c2
!= '"' && c2
!= EOF
);
164 longjmp (Exception
, (int) ExceptionEOF
);
168 static boolean
isIdentifierCharacter (const int c
)
170 return (boolean
)(isalnum (c
) || c
== '_' || c
== '`');
173 static int skipWhite (int c
)
180 static int skipPastMatch (const char *const pair
)
182 const int begin
= pair
[0], end
= pair
[1];
193 while (matchLevel
> 0);
197 static boolean
readIdentifier (vString
*const name
, int c
)
200 if (isIdentifierCharacter (c
))
202 while (isIdentifierCharacter (c
))
204 vStringPut (name
, c
);
208 vStringTerminate (name
);
210 return (boolean
)(name
->length
> 0);
213 static void tagNameList (const verilogKind kind
, int c
)
215 vString
*name
= vStringNew ();
217 Assert (isIdentifierCharacter (c
));
221 if (isIdentifierCharacter (c
))
223 readIdentifier (name
, c
);
224 makeSimpleTag (name
, VerilogKinds
, kind
);
228 c
= skipWhite (vGetc ());
230 c
= skipPastMatch ("[]");
235 skipPastMatch ("{}");
240 while (c
!= ',' && c
!= ';');
245 c
= skipWhite (vGetc ());
251 vStringDelete (name
);
255 static void findTag (vString
*const name
)
257 const verilogKind kind
= (verilogKind
) lookupKeyword (vStringValue (name
), Lang_verilog
);
258 if (kind
== K_CONSTANT
&& vStringItem (name
, 0) == '`')
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. */
270 else if (kind
!= K_UNDEFINED
)
272 int c
= skipWhite (vGetc ());
274 /* Many keywords can have bit width.
275 * reg [3:0] net_name;
276 * inout [(`DBUSWIDTH-1):0] databus;
279 c
= skipPastMatch ("()");
282 c
= skipPastMatch ("[]");
288 c
= skipPastMatch ("()");
291 if (isIdentifierCharacter (c
))
292 tagNameList (kind
, c
);
296 static void findVerilogTags (void)
298 vString
*const name
= vStringNew ();
299 volatile boolean newStatement
= TRUE
;
300 volatile int c
= '\0';
301 exception_t exception
= (exception_t
) setjmp (Exception
);
303 if (exception
== ExceptionNone
) while (c
!= EOF
)
318 if (newStatement
&& readIdentifier (name
, c
))
320 newStatement
= FALSE
;
324 vStringDelete (name
);
327 extern parserDefinition
* VerilogParser (void)
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
;
339 /* vi:set tabstop=4 shiftwidth=4: */