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.
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 */
34 typedef enum eException
{ ExceptionNone
, ExceptionEOF
} exception_t
;
57 static int Lang_verilog
;
58 static jmp_buf Exception
;
60 static kindOption VerilogKinds
[] = {
61 { TRUE
, 'c', "constant", "constants (define, parameter, specparam)" },
62 { TRUE
, 'e', "event", "events" },
63 { TRUE
, 'f', "function", "functions" },
64 { TRUE
, 'm', "module", "modules" },
65 { TRUE
, 'n', "net", "net data types" },
66 { TRUE
, 'p', "port", "ports" },
67 { TRUE
, 'r', "register", "register data types" },
68 { TRUE
, 't', "task", "tasks" }
71 static keywordAssoc VerilogKeywordTable
[] = {
72 { "`define", K_CONSTANT
},
74 { "function", K_FUNCTION
},
77 { "integer", K_REGISTER
},
78 { "module", K_MODULE
},
80 { "parameter", K_CONSTANT
},
81 { "real", K_REGISTER
},
82 { "realtime", K_REGISTER
},
83 { "reg", K_REGISTER
},
84 { "specparam", K_CONSTANT
},
88 { "time", K_REGISTER
},
101 * FUNCTION DEFINITIONS
104 static void initialize (const langType language
)
108 sizeof (VerilogKeywordTable
) / sizeof (VerilogKeywordTable
[0]);
109 Lang_verilog
= language
;
110 for (i
= 0 ; i
< count
; ++i
)
112 const keywordAssoc
* const p
= &VerilogKeywordTable
[i
];
113 addKeyword (p
->keyword
, language
, (int) p
->kind
);
117 static void vUngetc (int c
)
119 Assert (Ungetc
== '\0');
123 static int vGetc (void)
135 int c2
= fileGetc ();
137 longjmp (Exception
, (int) ExceptionEOF
);
138 else if (c2
== '/') /* strip comment until end-of-line */
142 while (c
!= '\n' && c
!= EOF
);
144 else if (c2
== '*') /* strip block comment */
146 c
= skipOverCComment();
153 else if (c
== '"') /* strip string contents */
158 while (c2
!= '"' && c2
!= EOF
);
162 longjmp (Exception
, (int) ExceptionEOF
);
166 static boolean
isIdentifierCharacter (const int c
)
168 return (boolean
)(isalnum (c
) || c
== '_' || c
== '`');
171 static int skipWhite (int c
)
178 static int skipPastMatch (const char *const pair
)
180 const int begin
= pair
[0], end
= pair
[1];
191 while (matchLevel
> 0);
195 static boolean
readIdentifier (vString
*const name
, int c
)
198 if (isIdentifierCharacter (c
))
200 while (isIdentifierCharacter (c
))
202 vStringPut (name
, c
);
206 vStringTerminate (name
);
208 return (boolean
)(name
->length
> 0);
211 static void tagNameList (const verilogKind kind
, int c
)
213 vString
*name
= vStringNew ();
215 Assert (isIdentifierCharacter (c
));
219 if (isIdentifierCharacter (c
))
221 readIdentifier (name
, c
);
222 makeSimpleTag (name
, VerilogKinds
, kind
);
226 c
= skipWhite (vGetc ());
228 c
= skipPastMatch ("[]");
232 c
= skipWhite (vGetc ());
234 skipPastMatch ("{}");
239 while (c
!= ',' && c
!= ';');
244 c
= skipWhite (vGetc ());
250 vStringDelete (name
);
254 static void findTag (vString
*const name
)
256 const verilogKind kind
= (verilogKind
) lookupKeyword (vStringValue (name
), Lang_verilog
);
257 if (kind
== K_CONSTANT
&& vStringItem (name
, 0) == '`')
259 /* Bug #961001: Verilog compiler directives are line-based. */
260 int c
= skipWhite (vGetc ());
261 readIdentifier (name
, c
);
262 makeSimpleTag (name
, VerilogKinds
, kind
);
263 /* Skip the rest of the line. */
269 else if (kind
!= K_UNDEFINED
)
271 int c
= skipWhite (vGetc ());
273 /* Many keywords can have bit width.
274 * reg [3:0] net_name;
275 * inout [(`DBUSWIDTH-1):0] databus;
278 c
= skipPastMatch ("()");
281 c
= skipPastMatch ("[]");
287 c
= skipPastMatch ("()");
290 if (isIdentifierCharacter (c
))
291 tagNameList (kind
, c
);
295 static void findVerilogTags (void)
297 vString
*const name
= vStringNew ();
298 volatile boolean newStatement
= TRUE
;
299 volatile int c
= '\0';
300 exception_t exception
= (exception_t
) setjmp (Exception
);
302 if (exception
== ExceptionNone
) while (c
!= EOF
)
317 if (newStatement
&& readIdentifier (name
, c
))
319 newStatement
= FALSE
;
323 vStringDelete (name
);
326 extern parserDefinition
* VerilogParser (void)
328 static const char *const extensions
[] = { "v", NULL
};
329 parserDefinition
* def
= parserNew ("Verilog");
330 def
->kinds
= VerilogKinds
;
331 def
->kindCount
= KIND_COUNT (VerilogKinds
);
332 def
->extensions
= extensions
;
333 def
->parser
= findVerilogTags
;
334 def
->initialize
= initialize
;
338 /* vi:set tabstop=4 shiftwidth=4: */