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/1995-fall/verilog-manual.html
14 * http://www.sutherland-hdl.com/on-line_ref_guide/vlog_ref_top.html
15 * http://home.europa.com/~celiac/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', "constant", "constants (define, parameter, specparam)" },
64 { TRUE
, 'e', "event", "events" },
65 { TRUE
, 'f', "function", "functions" },
66 { TRUE
, 'm', "module", "modules" },
67 { TRUE
, 'n', "net", "net data types" },
68 { TRUE
, 'p', "port", "ports" },
69 { TRUE
, 'r', "register", "register data types" },
70 { TRUE
, 't', "task", "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 */
152 while (c
!= '*' && c
!= EOF
);
155 } while (c
!= '/' && c
!= EOF
);
157 c
= ' '; /* comment equivalent to white space */
162 else if (c
== '"') /* strip string contents */
167 while (c2
!= '"' && c2
!= EOF
);
171 longjmp (Exception
, (int) ExceptionEOF
);
175 static boolean
isIdentifierCharacter (const int c
)
177 return (boolean
)(isalnum (c
) || c
== '_' || c
== '`');
180 static int skipWhite (int c
)
187 static int skipPastMatch (const char *const pair
)
189 const int begin
= pair
[0], end
= pair
[1];
200 while (matchLevel
> 0);
204 static boolean
readIdentifier (vString
*const name
, int c
)
207 if (isIdentifierCharacter (c
))
209 while (isIdentifierCharacter (c
))
211 vStringPut (name
, c
);
215 vStringTerminate (name
);
217 return (boolean
)(name
->length
> 0);
220 static void tagNameList (const verilogKind kind
, int c
)
222 vString
*name
= vStringNew ();
224 Assert (isIdentifierCharacter (c
));
228 if (isIdentifierCharacter (c
))
230 readIdentifier (name
, c
);
231 makeSimpleTag (name
, VerilogKinds
, kind
);
235 c
= skipWhite (vGetc ());
237 c
= skipPastMatch ("[]");
242 skipPastMatch ("{}");
247 while (c
!= ',' && c
!= ';');
252 c
= skipWhite (vGetc ());
258 vStringDelete (name
);
262 static void findTag (vString
*const name
)
264 const verilogKind kind
= (verilogKind
)
265 lookupKeyword (vStringValue (name
), Lang_verilog
);
266 if (kind
!= K_UNDEFINED
)
268 int c
= skipWhite (vGetc ());
270 /* Many keywords can have bit width.
271 * reg [3:0] net_name;
272 * inout [(`DBUSWIDTH-1):0] databus;
275 c
= skipPastMatch ("()");
278 c
= skipPastMatch ("[]");
284 c
= skipPastMatch ("()");
287 if (isIdentifierCharacter (c
))
288 tagNameList (kind
, c
);
292 static void findVerilogTags (void)
294 vString
*const name
= vStringNew ();
295 volatile boolean newStatement
= TRUE
;
296 volatile int c
= '\0';
297 exception_t exception
= (exception_t
) setjmp (Exception
);
299 if (exception
== ExceptionNone
) while (c
!= EOF
)
314 if (newStatement
&& readIdentifier (name
, c
))
316 newStatement
= FALSE
;
320 vStringDelete (name
);
323 extern parserDefinition
* VerilogParser (void)
325 static const char *const extensions
[] = { "v", NULL
};
326 parserDefinition
* def
= parserNew ("Verilog");
327 def
->kinds
= VerilogKinds
;
328 def
->kindCount
= KIND_COUNT (VerilogKinds
);
329 def
->extensions
= extensions
;
330 def
->parser
= findVerilogTags
;
331 def
->initialize
= initialize
;
335 /* vi:set tabstop=4 shiftwidth=4: */