cleanup, add example output
[sv2nmigen.git] / lexor.lex
1 %{
2 /*
3  * Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
4  *
5  *    This source code is free software; you can redistribute it
6  *    and/or modify it in source code form under the terms of the GNU
7  *    General Public License as published by the Free Software
8  *    Foundation; either version 2 of the License, or (at your option)
9  *    any later version.
10  *
11  *    This program is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *    GNU General Public License for more details.
15  *
16  *    You should have received a copy of the GNU General Public License
17  *    along with this program; if not, write to the Free Software
18  *    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20
21 # include "config.h"
22
23       //# define YYSTYPE lexval
24
25 # include  <iostream>
26 # include  "compiler.h"
27 # include  "parse_misc.h"
28 # include  "parse_api.h"
29 # include  "parse.h"
30 # include  <cctype>
31 # include  <cstring>
32 # include  "lexor_keyword.h"
33 # include  "discipline.h"
34 # include  <list>
35
36 # define YY_USER_INIT reset_lexor();
37 # define yylval VLlval
38
39 # define YY_NO_INPUT
40
41 /*
42  * Lexical location information is passed in the yylloc variable to th
43  * parser. The file names, strings, are kept in a list so that I can
44  * re-use them. The set_file_name function will return a pointer to
45  * the name as it exists in the list (and delete the passed string.)
46  * If the name is new, it will be added to the list.
47  */
48 extern YYLTYPE yylloc;
49
50 char* strdupnew(char const *str)
51 {
52        return str ? strcpy(new char [strlen(str)+1], str) : 0;
53 }
54
55 static const char* set_file_name(char*text)
56 {
57       perm_string path = filename_strings.make(text);
58       delete[]text;
59
60         /* Check this file name with the list of library file
61            names. If there is a match, then turn on the
62            pform_library_flag. This is how the parser knows that
63            modules declared in this file are library modules. */
64       pform_library_flag = library_file_map[path];
65       return path;
66 }
67
68 void reset_lexor();
69 static void line_directive();
70 static void line_directive2();
71 static void reset_all();
72
73 verinum*make_unsized_binary(const char*txt);
74 verinum*make_undef_highz_dec(const char*txt);
75 verinum*make_unsized_dec(const char*txt);
76 verinum*make_unsized_octal(const char*txt);
77 verinum*make_unsized_hex(const char*txt);
78
79 static int dec_buf_div2(char *buf);
80
81 static void process_timescale(const char*txt);
82 static void process_ucdrive(const char*txt);
83
84 static list<int> keyword_mask_stack;
85
86 static int comment_enter;
87 static bool in_module = false;
88 static bool in_UDP = false;
89 bool in_celldefine = false;
90 UCDriveType uc_drive = UCD_NONE;
91
92 /*
93  * The parser sometimes needs to indicate to the lexor that the next
94  * identifier needs to be understood in the context of a package. The
95  * parser feeds back that left context with calls to the
96  * lex_in_package_scope.
97  */
98 static PPackage* in_package_scope = 0;
99 void lex_in_package_scope(PPackage*pkg)
100 {
101       in_package_scope = pkg;
102 }
103
104 %}
105
106 /*
107 %x CCOMMENT
108 %x PCOMMENT
109 %x LCOMMENT
110 %x CSTRING
111 %s UDPTABLE
112 %x PPTIMESCALE
113 %x PPUCDRIVE
114 %x PPDEFAULT_NETTYPE
115 %x PPBEGIN_KEYWORDS
116 %s EDGES
117 %x REAL_SCALE
118 */
119
120 W [ \t\b\f\r]+
121
122 S [afpnumkKMGT]
123
124 TU [munpf]
125
126 %%
127
128   /* Recognize the various line directives. */
129 ^"#line"[ \t]+.+ { line_directive(); }
130 ^[ \t]?"`line"[ \t]+.+ { line_directive2(); }
131
132 [ \t\b\f\r] { ; }
133 \n { yylloc.first_line += 1; }
134
135   /* C++ style comments start with / / and run to the end of the
136      current line. These are very easy to handle. The meta-comments
137      format is a little more tricky to handle, but do what we can. */
138
139   /* The lexor detects "// synthesis translate_on/off" meta-comments,
140      we handle them here by turning on/off a flag. The pform uses
141      that flag to attach implicit attributes to "initial" and
142      "always" statements. */
143
144 "//"{W}*"synthesis"{W}+"translate_on"{W}*\n { pform_mc_translate_on(true); }
145 "//"{W}*"synthesis"{W}+"translate_off"{W}*\n { pform_mc_translate_on(false); }
146 "//" { comment_enter = YY_START; BEGIN(LCOMMENT); }
147 <LCOMMENT>.    { yymore(); }
148 <LCOMMENT>\n   { yylloc.first_line += 1; BEGIN(comment_enter); }
149
150
151   /* The contents of C-style comments are ignored, like white space. */
152
153 "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
154 <CCOMMENT>.    { ; }
155 <CCOMMENT>\n   { yylloc.first_line += 1; }
156 <CCOMMENT>"*/" { BEGIN(comment_enter); }
157
158
159 "(*" { return K_PSTAR; }
160 "*)" { return K_STARP; }
161 ".*" { return K_DOTSTAR; }
162 "<<" { return K_LS; }
163 "<<<" { return K_LS; /* Note: Functionally, <<< is the same as <<. */}
164 ">>"  { return K_RS; }
165 ">>>" { return K_RSS; }
166 "**" { return K_POW; }
167 "<=" { return K_LE; }
168 ">=" { return K_GE; }
169 "=>" { return K_EG; }
170 "+=>"|"-=>"     {
171                         /*
172                          * Resolve the ambiguity between the += assignment
173                          * operator and +=> polarity edge path operator
174                          *
175                          * +=> should be treated as two separate tokens '+' and
176                          * '=>' (K_EG), therefore we only consume the first
177                          * character of the matched pattern i.e. either + or -
178                          * and push back the rest of the matches text (=>) in
179                          * the input stream.
180                          */
181                         yyless(1);
182                         return yytext[0];
183                 }
184 "*>" { return K_SG; }
185 "==" { return K_EQ; }
186 "!=" { return K_NE; }
187 "===" { return K_CEQ; }
188 "!==" { return K_CNE; }
189 "==?" { return K_WEQ; }
190 "!=?" { return K_WNE; }
191 "||" { return K_LOR; }
192 "&&" { return K_LAND; }
193 "&&&" { return K_TAND; }
194 "~|" { return K_NOR; }
195 "~^" { return K_NXOR; }
196 "^~" { return K_NXOR; }
197 "~&" { return K_NAND; }
198 "->" { return K_TRIGGER; }
199 "+:" { return K_PO_POS; }
200 "-:" { return K_PO_NEG; }
201 "<+" { return K_CONTRIBUTE; }
202 "+=" { return K_PLUS_EQ; }
203 "-=" { return K_MINUS_EQ; }
204 "*=" { return K_MUL_EQ; }
205 "/=" { return K_DIV_EQ; }
206 "%=" { return K_MOD_EQ; }
207 "&=" { return K_AND_EQ; }
208 "|=" { return K_OR_EQ; }
209 "^=" { return K_XOR_EQ; }
210 "<<=" { return K_LS_EQ; }
211 ">>=" { return K_RS_EQ; }
212 "<<<=" { return K_LS_EQ; }
213 ">>>=" { return K_RSS_EQ; }
214 "++" { return K_INCR; }
215 "--" {return K_DECR; }
216 "'{" { return K_LP; }
217 "::" { return K_SCOPE_RES; }
218
219   /* Watch out for the tricky case of (*). Cannot parse this as "(*"
220      and ")", but since I know that this is really ( * ), replace it
221      with "*" and return that. */
222 "("{W}*"*"{W}*")" { return '*'; }
223
224 <EDGES>"]" { BEGIN(0); return yytext[0]; }
225 [}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
226
227 \"            { BEGIN(CSTRING); }
228 <CSTRING>\\\\ { yymore(); /* Catch \\, which is a \ escaping itself */ }
229 <CSTRING>\\\" { yymore(); /* Catch \", which is an escaped quote */ }
230 <CSTRING>\n   { BEGIN(0);
231                 yylval.text = strdupnew(yytext);
232                 VLerror(yylloc, "Missing close quote of string.");
233                 yylloc.first_line += 1;
234                 return STRING; }
235 <CSTRING>\"   { BEGIN(0);
236                 yylval.text = strdupnew(yytext);
237                 yylval.text[strlen(yytext)-1] = 0;
238                 return STRING; }
239 <CSTRING>.    { yymore(); }
240
241   /* The UDP Table is a unique lexical environment. These are most
242      tokens that we can expect in a table. */
243 <UDPTABLE>\(\?0\)    { return '_'; }
244 <UDPTABLE>\(\?1\)    { return '+'; }
245 <UDPTABLE>\(\?[xX]\) { return '%'; }
246 <UDPTABLE>\(\?\?\)  { return '*'; }
247 <UDPTABLE>\(01\)    { return 'r'; }
248 <UDPTABLE>\(0[xX]\) { return 'Q'; }
249 <UDPTABLE>\(b[xX]\) { return 'q'; }
250 <UDPTABLE>\(b0\)    { return 'f'; /* b0 is 10|00, but only 10 is meaningful */}
251 <UDPTABLE>\(b1\)    { return 'r'; /* b1 is 11|01, but only 01 is meaningful */}
252 <UDPTABLE>\(0\?\)   { return 'P'; }
253 <UDPTABLE>\(10\)    { return 'f'; }
254 <UDPTABLE>\(1[xX]\) { return 'M'; }
255 <UDPTABLE>\(1\?\)   { return 'N'; }
256 <UDPTABLE>\([xX]0\) { return 'F'; }
257 <UDPTABLE>\([xX]1\) { return 'R'; }
258 <UDPTABLE>\([xX]\?\) { return 'B'; }
259 <UDPTABLE>[bB]     { return 'b'; }
260 <UDPTABLE>[lL]     { return 'l'; /* IVL extension */ }
261 <UDPTABLE>[hH]     { return 'h'; /* IVL extension */ }
262 <UDPTABLE>[fF]     { return 'f'; }
263 <UDPTABLE>[rR]     { return 'r'; }
264 <UDPTABLE>[xX]     { return 'x'; }
265 <UDPTABLE>[nN]     { return 'n'; }
266 <UDPTABLE>[pP]     { return 'p'; }
267 <UDPTABLE>[01\?\*\-:;] { return yytext[0]; }
268
269 <EDGES>"01" { return K_edge_descriptor; }
270 <EDGES>"0x" { return K_edge_descriptor; }
271 <EDGES>"0z" { return K_edge_descriptor; }
272 <EDGES>"10" { return K_edge_descriptor; }
273 <EDGES>"1x" { return K_edge_descriptor; }
274 <EDGES>"1z" { return K_edge_descriptor; }
275 <EDGES>"x0" { return K_edge_descriptor; }
276 <EDGES>"x1" { return K_edge_descriptor; }
277 <EDGES>"z0" { return K_edge_descriptor; }
278 <EDGES>"z1" { return K_edge_descriptor; }
279
280 [a-zA-Z_][a-zA-Z0-9$_]* {
281       int rc = lexor_keyword_code(yytext, yyleng);
282       switch (rc) {
283           case IDENTIFIER:
284             yylval.text = strdupnew(yytext);
285             if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
286                   rc = PATHPULSE_IDENTIFIER;
287             break;
288
289           case K_edge:
290             BEGIN(EDGES);
291             break;
292
293           case K_module:
294           case K_macromodule:
295             in_module = true;
296             break;
297
298           case K_endmodule:
299             in_module = false;
300             break;
301
302           case K_primitive:
303             in_UDP = true;
304             break;
305
306           case K_endprimitive:
307             in_UDP = false;
308             break;
309
310           case K_table:
311             BEGIN(UDPTABLE);
312             break;
313
314           default:
315             yylval.text = 0;
316             break;
317       }
318
319         /* Special case: If this is part of a scoped name, then check
320            the package for identifier details. For example, if the
321            source file is  foo::bar, the parse.y will note the
322            PACKAGE_IDENTIFIER and "::" token and mark the
323            "in_package_scope" variable. Then this lexor will see the
324            identifier here and interpret it in the package scope. */
325       if (in_package_scope) {
326             if (rc == IDENTIFIER) {
327                   if (data_type_t*type = pform_test_type_identifier(in_package_scope, yylval.text)) {
328                         yylval.type_identifier.text = yylval.text;
329                         yylval.type_identifier.type = type;
330                         rc = TYPE_IDENTIFIER;
331                   }
332             }
333             in_package_scope = 0;
334             return rc;
335       }
336
337         /* If this identifier names a discipline, then return this as
338            a DISCIPLINE_IDENTIFIER and return the discipline as the
339            value instead. */
340       if (rc == IDENTIFIER && gn_verilog_ams_flag) {
341             perm_string tmp = lex_strings.make(yylval.text);
342             map<perm_string,ivl_discipline_t>::iterator cur = disciplines.find(tmp);
343             if (cur != disciplines.end()) {
344                   delete[]yylval.text;
345                   yylval.discipline = (*cur).second;
346                   rc = DISCIPLINE_IDENTIFIER;
347             }
348       }
349
350         /* If this identifier names a previously declared package, then
351            return this as a PACKAGE_IDENTIFIER instead. */
352       if (rc == IDENTIFIER && gn_system_verilog()) {
353             if (PPackage*pkg = pform_test_package_identifier(yylval.text)) {
354                   delete[]yylval.text;
355                   yylval.package = pkg;
356                   rc = PACKAGE_IDENTIFIER;
357             }
358       }
359
360         /* If this identifier names a previously declared type, then
361            return this as a TYPE_IDENTIFIER instead. */
362       if (rc == IDENTIFIER && gn_system_verilog()) {
363             if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
364                   yylval.type_identifier.text = yylval.text;
365                   yylval.type_identifier.type = type;
366                   rc = TYPE_IDENTIFIER;
367             }
368       }
369
370       return rc;
371   }
372
373
374 \\[^ \t\b\f\r\n]+         {
375       yylval.text = strdupnew(yytext+1);
376       if (gn_system_verilog()) {
377             if (PPackage*pkg = pform_test_package_identifier(yylval.text)) {
378                   delete[]yylval.text;
379                   yylval.package = pkg;
380                   return PACKAGE_IDENTIFIER;
381             }
382       }
383       if (gn_system_verilog()) {
384             if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
385                   yylval.type_identifier.text = yylval.text;
386                   yylval.type_identifier.type = type;
387                   return TYPE_IDENTIFIER;
388             }
389       }
390       return IDENTIFIER;
391   }
392
393 \$([a-zA-Z0-9$_]+)        {
394         /* The 1364-1995 timing checks. */
395       if (strcmp(yytext,"$hold") == 0)
396             return K_Shold;
397       if (strcmp(yytext,"$nochange") == 0)
398             return K_Snochange;
399       if (strcmp(yytext,"$period") == 0)
400             return K_Speriod;
401       if (strcmp(yytext,"$recovery") == 0)
402             return K_Srecovery;
403       if (strcmp(yytext,"$setup") == 0)
404             return K_Ssetup;
405       if (strcmp(yytext,"$setuphold") == 0)
406             return K_Ssetuphold;
407       if (strcmp(yytext,"$skew") == 0)
408             return K_Sskew;
409       if (strcmp(yytext,"$width") == 0)
410             return K_Swidth;
411         /* The new 1364-2001 timing checks. */
412       if (strcmp(yytext,"$fullskew") == 0)
413             return K_Sfullskew;
414       if (strcmp(yytext,"$recrem") == 0)
415             return K_Srecrem;
416       if (strcmp(yytext,"$removal") == 0)
417             return K_Sremoval;
418       if (strcmp(yytext,"$timeskew") == 0)
419             return K_Stimeskew;
420
421       if (strcmp(yytext,"$attribute") == 0)
422             return KK_attribute;
423
424       if (gn_system_verilog() && strcmp(yytext,"$unit") == 0) {
425             yylval.package = pform_units.back();
426             return PACKAGE_IDENTIFIER;
427       }
428
429       yylval.text = strdupnew(yytext);
430       return SYSTEM_IDENTIFIER; }
431
432
433 \'[sS]?[dD][ \t]*[0-9][0-9_]* {
434       yylval.number = make_unsized_dec(yytext);
435       return BASED_NUMBER;
436 }
437 \'[sS]?[dD][ \t]*[xzXZ?]_* {
438       yylval.number = make_undef_highz_dec(yytext);
439       return BASED_NUMBER;
440 }
441 \'[sS]?[bB][ \t]*[0-1xzXZ?][0-1xzXZ?_]* {
442       yylval.number = make_unsized_binary(yytext);
443       return BASED_NUMBER;
444 }
445 \'[sS]?[oO][ \t]*[0-7xzXZ?][0-7xzXZ?_]* {
446       yylval.number = make_unsized_octal(yytext);
447       return BASED_NUMBER;
448 }
449 \'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ?][0-9a-fA-FxzXZ?_]* {
450       yylval.number = make_unsized_hex(yytext);
451       return BASED_NUMBER;
452 }
453 \'[01xzXZ] {
454       if (!gn_system_verilog()) {
455             cerr << yylloc.text << ":" << yylloc.first_line << ": warning: "
456                  << "Using SystemVerilog 'N bit vector.  Use at least "
457                  << "-g2005-sv to remove this warning." << endl;
458       }
459       generation_t generation_save = generation_flag;
460       generation_flag = GN_VER2005_SV;
461       yylval.number = make_unsized_binary(yytext);
462       generation_flag = generation_save;
463       return UNBASED_NUMBER; }
464
465   /* Decimal numbers are the usual. But watch out for the UDPTABLE
466      mode, where there are no decimal numbers. Reject the match if we
467      are in the UDPTABLE state. */
468 [0-9][0-9_]* {
469       if (YY_START==UDPTABLE) {
470             REJECT;
471       } else {
472             yylval.number = make_unsized_dec(yytext);
473             based_size = yylval.number->as_ulong();
474             return DEC_NUMBER;
475       }
476 }
477
478   /* This rule handles scaled time values for SystemVerilog. */
479 [0-9][0-9_]*(\.[0-9][0-9_]*)?{TU}?s {
480       if (gn_system_verilog()) {
481             yylval.text = strdupnew(yytext);
482             return TIME_LITERAL;
483       } else REJECT; }
484
485   /* These rules handle the scaled real literals from Verilog-AMS. The
486      value is a number with a single letter scale factor. If
487      verilog-ams is not enabled, then reject this rule. If it is
488      enabled, then collect the scale and use it to scale the value. */
489 [0-9][0-9_]*\.[0-9][0-9_]*/{S} {
490       if (!gn_verilog_ams_flag) REJECT;
491       BEGIN(REAL_SCALE);
492       yymore();  }
493
494 [0-9][0-9_]*/{S} {
495       if (!gn_verilog_ams_flag) REJECT;
496       BEGIN(REAL_SCALE);
497       yymore();  }
498
499 <REAL_SCALE>{S} {
500       size_t token_len = strlen(yytext);
501       char*tmp = new char[token_len + 5];
502       int scale = 0;
503       strcpy(tmp, yytext);
504       switch (tmp[token_len-1]) {
505           case 'a': scale = -18; break; /* atto- */
506           case 'f': scale = -15; break; /* femto- */
507           case 'p': scale = -12; break; /* pico- */
508           case 'n': scale = -9;  break; /* nano- */
509           case 'u': scale = -6;  break; /* micro- */
510           case 'm': scale = -3;  break; /* milli- */
511           case 'k': scale = 3;  break; /* kilo- */
512           case 'K': scale = 3;  break; /* kilo- */
513           case 'M': scale = 6;  break; /* mega- */
514           case 'G': scale = 9;  break; /* giga- */
515           case 'T': scale = 12; break; /* tera- */
516           default: assert(0); break;
517       }
518       snprintf(tmp+token_len-1, 5, "e%d", scale);
519       yylval.realtime = new verireal(tmp);
520       delete[]tmp;
521
522       BEGIN(0);
523       return REALTIME;  }
524
525 [0-9][0-9_]*\.[0-9][0-9_]*([Ee][+-]?[0-9][0-9_]*)? {
526       yylval.realtime = new verireal(yytext);
527       return REALTIME; }
528
529 [0-9][0-9_]*[Ee][+-]?[0-9][0-9_]* {
530       yylval.realtime = new verireal(yytext);
531       return REALTIME; }
532
533
534   /* Notice and handle the `timescale directive. */
535
536 ^{W}?`timescale { BEGIN(PPTIMESCALE); }
537 <PPTIMESCALE>.* { process_timescale(yytext); }
538 <PPTIMESCALE>\n {
539       if (in_module) {
540             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
541                     "`timescale directive can not be inside a module "
542                     "definition." << endl;
543             error_count += 1;
544       }
545       yylloc.first_line += 1;
546       BEGIN(0); }
547
548   /* Notice and handle the `celldefine and `endcelldefine directives. */
549
550 ^{W}?`celldefine{W}?    { in_celldefine = true; }
551 ^{W}?`endcelldefine{W}? { in_celldefine = false; }
552
553   /* Notice and handle the resetall directive. */
554
555 ^{W}?`resetall{W}? {
556       if (in_module) {
557             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
558                     "`resetall directive can not be inside a module "
559                     "definition." << endl;
560             error_count += 1;
561       } else if (in_UDP) {
562             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
563                     "`resetall directive can not be inside a UDP "
564                     "definition." << endl;
565             error_count += 1;
566       } else {
567             reset_all();
568       } }
569
570   /* Notice and handle the `unconnected_drive directive. */
571 ^{W}?`unconnected_drive { BEGIN(PPUCDRIVE); }
572 <PPUCDRIVE>.* { process_ucdrive(yytext); }
573 <PPUCDRIVE>\n {
574       if (in_module) {
575             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
576                     "`unconnected_drive directive can not be inside a "
577                     "module definition." << endl;
578             error_count += 1;
579       }
580       yylloc.first_line += 1;
581       BEGIN(0); }
582
583 ^{W}?`nounconnected_drive{W}? {
584       if (in_module) {
585             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
586                     "`nounconnected_drive directive can not be inside a "
587                     "module definition." << endl;
588             error_count += 1;
589       }
590       uc_drive = UCD_NONE; }
591
592   /* These are directives that I do not yet support. I think that IVL
593      should handle these, not an external preprocessor. */
594   /* From 1364-2005 Chapter 19. */
595 ^{W}?`pragme{W}?.*                  {  }
596
597   /* From 1364-2005 Annex D. */
598 ^{W}?`default_decay_time{W}?.*      {  }
599 ^{W}?`default_trireg_strength{W}?.* {  }
600 ^{W}?`delay_mode_distributed{W}?.*  {  }
601 ^{W}?`delay_mode_path{W}?.*         {  }
602 ^{W}?`delay_mode_unit{W}?.*         {  }
603 ^{W}?`delay_mode_zero{W}?.*         {  }
604
605   /* From other places. */
606 ^{W}?`disable_portfaults{W}?.*      {  }
607 ^{W}?`enable_portfaults{W}?.*       {  }
608 `endprotect                         {  }
609 ^{W}?`nosuppress_faults{W}?.*       {  }
610 `protect                            {  }
611 ^{W}?`suppress_faults{W}?.*         {  }
612 ^{W}?`uselib{W}?.*                  {  }
613
614 ^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); }
615
616 <PPBEGIN_KEYWORDS>\"[a-zA-Z0-9 -\.]*\".* {
617       keyword_mask_stack.push_front(lexor_keyword_mask);
618
619       char*word = yytext+1;
620       char*tail = strchr(word, '"');
621       tail[0] = 0;
622       if (strcmp(word,"1364-1995") == 0) {
623             lexor_keyword_mask = GN_KEYWORDS_1364_1995;
624       } else if (strcmp(word,"1364-2001") == 0) {
625             lexor_keyword_mask = GN_KEYWORDS_1364_1995
626                                 |GN_KEYWORDS_1364_2001
627                                 |GN_KEYWORDS_1364_2001_CONFIG;
628       } else if (strcmp(word,"1364-2001-noconfig") == 0) {
629             lexor_keyword_mask = GN_KEYWORDS_1364_1995
630                                 |GN_KEYWORDS_1364_2001;
631       } else if (strcmp(word,"1364-2005") == 0) {
632             lexor_keyword_mask = GN_KEYWORDS_1364_1995
633                                 |GN_KEYWORDS_1364_2001
634                                 |GN_KEYWORDS_1364_2001_CONFIG
635                                 |GN_KEYWORDS_1364_2005;
636       } else if (strcmp(word,"1800-2005") == 0) {
637             lexor_keyword_mask = GN_KEYWORDS_1364_1995
638                                 |GN_KEYWORDS_1364_2001
639                                 |GN_KEYWORDS_1364_2001_CONFIG
640                                 |GN_KEYWORDS_1364_2005
641                                 |GN_KEYWORDS_1800_2005;
642       } else if (strcmp(word,"1800-2009") == 0) {
643             lexor_keyword_mask = GN_KEYWORDS_1364_1995
644                                 |GN_KEYWORDS_1364_2001
645                                 |GN_KEYWORDS_1364_2001_CONFIG
646                                 |GN_KEYWORDS_1364_2005
647                                 |GN_KEYWORDS_1800_2005
648                                 |GN_KEYWORDS_1800_2009;
649       } else if (strcmp(word,"1800-2012") == 0) {
650             lexor_keyword_mask = GN_KEYWORDS_1364_1995
651                                 |GN_KEYWORDS_1364_2001
652                                 |GN_KEYWORDS_1364_2001_CONFIG
653                                 |GN_KEYWORDS_1364_2005
654                                 |GN_KEYWORDS_1800_2005
655                                 |GN_KEYWORDS_1800_2009
656                                 |GN_KEYWORDS_1800_2012;
657       } else if (strcmp(word,"VAMS-2.3") == 0) {
658             lexor_keyword_mask = GN_KEYWORDS_1364_1995
659                                 |GN_KEYWORDS_1364_2001
660                                 |GN_KEYWORDS_1364_2001_CONFIG
661                                 |GN_KEYWORDS_1364_2005
662                                 |GN_KEYWORDS_VAMS_2_3;
663       } else {
664             fprintf(stderr, "%s:%d: Ignoring unknown keywords string: %s\n",
665                     yylloc.text, yylloc.first_line, word);
666       }
667       BEGIN(0);
668  }
669
670 <PPBEGIN_KEYWORDS>.* {
671       fprintf(stderr, "%s:%d: Malformed keywords specification: %s\n",
672               yylloc.text, yylloc.first_line, yytext);
673       BEGIN(0);
674  }
675
676 ^{W}?`end_keywords{W}?.* {
677       if (!keyword_mask_stack.empty()) {
678             lexor_keyword_mask = keyword_mask_stack.front();
679             keyword_mask_stack.pop_front();
680       } else {
681             fprintf(stderr, "%s:%d: Mismatched end_keywords directive\n",
682                     yylloc.text, yylloc.first_line);
683       }
684  }
685
686   /* Notice and handle the default_nettype directive. The lexor
687      detects the default_nettype keyword, and the second part of the
688      rule collects the rest of the line and processes it. We only need
689      to look for the first work, and interpret it. */
690
691 `default_nettype{W}? { BEGIN(PPDEFAULT_NETTYPE); }
692 <PPDEFAULT_NETTYPE>.* {
693       NetNet::Type net_type;
694       size_t wordlen = strcspn(yytext, " \t\f\r\n");
695       yytext[wordlen] = 0;
696   /* Add support for other wire types and better error detection. */
697       if (strcmp(yytext,"wire") == 0) {
698             net_type = NetNet::WIRE;
699
700       } else if (strcmp(yytext,"tri") == 0) {
701             net_type = NetNet::TRI;
702
703       } else if (strcmp(yytext,"tri0") == 0) {
704             net_type = NetNet::TRI0;
705
706       } else if (strcmp(yytext,"tri1") == 0) {
707             net_type = NetNet::TRI1;
708
709       } else if (strcmp(yytext,"wand") == 0) {
710             net_type = NetNet::WAND;
711
712       } else if (strcmp(yytext,"triand") == 0) {
713             net_type = NetNet::TRIAND;
714
715       } else if (strcmp(yytext,"wor") == 0) {
716             net_type = NetNet::WOR;
717
718       } else if (strcmp(yytext,"trior") == 0) {
719             net_type = NetNet::TRIOR;
720
721       } else if (strcmp(yytext,"none") == 0) {
722             net_type = NetNet::NONE;
723
724       } else {
725             cerr << yylloc.text << ":" << yylloc.first_line
726                  << ": error: Net type " << yytext
727                  << " is not a valid (or supported)"
728                  << " default net type." << endl;
729             net_type = NetNet::WIRE;
730             error_count += 1;
731       }
732       pform_set_default_nettype(net_type, yylloc.text, yylloc.first_line);
733   }
734 <PPDEFAULT_NETTYPE>\n {
735       yylloc.first_line += 1;
736       BEGIN(0); }
737
738
739   /* These are directives that are not supported by me and should have
740      been handled by an external preprocessor such as ivlpp. */
741
742 ^{W}?`define{W}?.* {
743       cerr << yylloc.text << ":" << yylloc.first_line <<
744             ": warning: `define not supported. Use an external preprocessor."
745            << endl;
746   }
747
748 ^{W}?`else{W}?.* {
749       cerr << yylloc.text << ":" << yylloc.first_line <<
750             ": warning: `else not supported. Use an external preprocessor."
751            << endl;
752   }
753
754 ^{W}?`elsif{W}?.* {
755       cerr << yylloc.text << ":" << yylloc.first_line <<
756             ": warning: `elsif not supported. Use an external preprocessor."
757            << endl;
758   }
759
760 ^{W}?`endif{W}?.* {
761       cerr << yylloc.text << ":" << yylloc.first_line <<
762             ": warning: `endif not supported. Use an external preprocessor."
763            << endl;
764   }
765
766 ^{W}?`ifdef{W}?.* {
767       cerr << yylloc.text << ":" << yylloc.first_line <<
768             ": warning: `ifdef not supported. Use an external preprocessor."
769            << endl;
770   }
771
772 ^{W}?`ifndef{W}?.* {
773       cerr << yylloc.text << ":" << yylloc.first_line <<
774             ": warning: `ifndef not supported. Use an external preprocessor."
775            << endl;
776   }
777
778 ^`include{W}?.* {
779       cerr << yylloc.text << ":" << yylloc.first_line <<
780             ": warning: `include not supported. Use an external preprocessor."
781            << endl;
782   }
783
784 ^`undef{W}?.* {
785       cerr << yylloc.text << ":" << yylloc.first_line <<
786             ": warning: `undef not supported. Use an external preprocessor."
787            << endl;
788   }
789
790
791 `{W} { cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
792             << "Stray tic (`) here. Perhaps you put white space" << endl;
793        cerr << yylloc.text << ":" << yylloc.first_line << ":      : "
794             << "between the tic and preprocessor directive?"
795             << endl;
796        error_count += 1; }
797
798 . { return yytext[0]; }
799
800   /* Final catchall. something got lost or mishandled. */
801   /* XXX Should we tell the user something about the lexical state? */
802
803 <*>.|\n {   cerr << yylloc.text << ":" << yylloc.first_line
804            << ": error: unmatched character (";
805       if (isprint(yytext[0]))
806             cerr << yytext[0];
807       else
808             cerr << "hex " << hex << ((unsigned char) yytext[0]);
809
810       cerr << ")" << endl;
811       error_count += 1; }
812
813 %%
814
815 /*
816  * The UDP state table needs some slightly different treatment by the
817  * lexor. The level characters are normally accepted as other things,
818  * so the parser needs to switch my mode when it believes in needs to.
819  */
820 void lex_end_table()
821 {
822       BEGIN(INITIAL);
823 }
824
825 static unsigned truncate_to_integer_width(verinum::V*bits, unsigned size)
826 {
827       if (size <= integer_width) return size;
828
829       verinum::V pad = bits[size-1];
830       if (pad == verinum::V1) pad = verinum::V0;
831
832       for (unsigned idx = integer_width; idx < size; idx += 1) {
833             if (bits[idx] != pad) {
834                   yywarn(yylloc, "Unsized numeric constant truncated to integer width.");
835                   break;
836             }
837       }
838       return integer_width;
839 }
840
841 verinum*make_unsized_binary(const char*txt)
842 {
843       bool sign_flag = false;
844       bool single_flag = false;
845       const char*ptr = txt;
846       assert(*ptr == '\'');
847       ptr += 1;
848
849       if (tolower(*ptr) == 's') {
850             sign_flag = true;
851             ptr += 1;
852       }
853
854       assert((tolower(*ptr) == 'b') || gn_system_verilog());
855       if (tolower(*ptr) == 'b') {
856             ptr += 1;
857       } else {
858             assert(sign_flag == false);
859             single_flag = true;
860       }
861
862       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
863             ptr += 1;
864
865       unsigned size = 0;
866       for (const char*idx = ptr ;  *idx ;  idx += 1)
867             if (*idx != '_') size += 1;
868
869       if (size == 0) {
870             VLerror(yylloc, "Numeric literal has no digits in it.");
871             verinum*out = new verinum();
872             out->has_sign(sign_flag);
873             out->is_single(single_flag);
874             return out;
875       }
876
877       if ((based_size > 0) && (size > based_size)) yywarn(yylloc,
878           "extra digits given for sized binary constant.");
879
880       verinum::V*bits = new verinum::V[size];
881
882       unsigned idx = size;
883       while (*ptr) {
884             switch (ptr[0]) {
885                 case '0':
886                   bits[--idx] = verinum::V0;
887                   break;
888                 case '1':
889                   bits[--idx] = verinum::V1;
890                   break;
891                 case 'z': case 'Z': case '?':
892                   bits[--idx] = verinum::Vz;
893                   break;
894                 case 'x': case 'X':
895                   bits[--idx] = verinum::Vx;
896                   break;
897                   case '_':
898                   break;
899                 default:
900                   fprintf(stderr, "%c\n", ptr[0]);
901                   assert(0);
902             }
903             ptr += 1;
904       }
905
906       if (gn_strict_expr_width_flag && (based_size == 0))
907             size = truncate_to_integer_width(bits, size);
908
909       verinum*out = new verinum(bits, size, false);
910       out->has_sign(sign_flag);
911       out->is_single(single_flag);
912       delete[]bits;
913       return out;
914 }
915
916
917 verinum*make_unsized_octal(const char*txt)
918 {
919       bool sign_flag = false;
920       const char*ptr = txt;
921       assert(*ptr == '\'');
922       ptr += 1;
923
924       if (tolower(*ptr) == 's') {
925             sign_flag = true;
926             ptr += 1;
927       }
928
929       assert(tolower(*ptr) == 'o');
930       ptr += 1;
931
932       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
933             ptr += 1;
934
935       unsigned size = 0;
936       for (const char*idx = ptr ;  *idx ;  idx += 1)
937             if (*idx != '_') size += 3;
938
939       if (based_size > 0) {
940             int rem = based_size % 3;
941             if (rem != 0) based_size += 3 - rem;
942             if (size > based_size) yywarn(yylloc,
943                 "extra digits given for sized octal constant.");
944       }
945
946       verinum::V*bits = new verinum::V[size];
947
948       unsigned idx = size;
949       while (*ptr) {
950             unsigned val;
951             switch (ptr[0]) {
952                 case '0': case '1': case '2': case '3':
953                 case '4': case '5': case '6': case '7':
954                   val = *ptr - '0';
955                   bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
956                   bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
957                   bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
958                   break;
959                 case 'x': case 'X':
960                   bits[--idx] = verinum::Vx;
961                   bits[--idx] = verinum::Vx;
962                   bits[--idx] = verinum::Vx;
963                   break;
964                 case 'z': case 'Z': case '?':
965                   bits[--idx] = verinum::Vz;
966                   bits[--idx] = verinum::Vz;
967                   bits[--idx] = verinum::Vz;
968                   break;
969                 case '_':
970                   break;
971                 default:
972                   assert(0);
973             }
974             ptr += 1;
975       }
976
977       if (gn_strict_expr_width_flag && (based_size == 0))
978             size = truncate_to_integer_width(bits, size);
979
980       verinum*out = new verinum(bits, size, false);
981       out->has_sign(sign_flag);
982       delete[]bits;
983       return out;
984 }
985
986
987 verinum*make_unsized_hex(const char*txt)
988 {
989       bool sign_flag = false;
990       const char*ptr = txt;
991       assert(*ptr == '\'');
992       ptr += 1;
993
994       if (tolower(*ptr) == 's') {
995             sign_flag = true;
996             ptr += 1;
997       }
998       assert(tolower(*ptr) == 'h');
999
1000       ptr += 1;
1001       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1002             ptr += 1;
1003
1004       unsigned size = 0;
1005       for (const char*idx = ptr ;  *idx ;  idx += 1)
1006             if (*idx != '_') size += 4;
1007
1008       if (based_size > 0) {
1009             int rem = based_size % 4;
1010             if (rem != 0) based_size += 4 - rem;
1011             if (size > based_size) yywarn(yylloc,
1012                 "extra digits given for sized hex constant.");
1013       }
1014
1015       verinum::V*bits = new verinum::V[size];
1016
1017       unsigned idx = size;
1018       while (*ptr) {
1019             unsigned val;
1020             switch (ptr[0]) {
1021                 case '0': case '1': case '2': case '3': case '4':
1022                 case '5': case '6': case '7': case '8': case '9':
1023                   val = *ptr - '0';
1024                   bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
1025                   bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
1026                   bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
1027                   bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
1028                   break;
1029                 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1030                 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1031                   val = tolower(*ptr) - 'a' + 10;
1032                   bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
1033                   bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
1034                   bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
1035                   bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
1036                   break;
1037                 case 'x': case 'X':
1038                   bits[--idx] = verinum::Vx;
1039                   bits[--idx] = verinum::Vx;
1040                   bits[--idx] = verinum::Vx;
1041                   bits[--idx] = verinum::Vx;
1042                   break;
1043                 case 'z': case 'Z': case '?':
1044                   bits[--idx] = verinum::Vz;
1045                   bits[--idx] = verinum::Vz;
1046                   bits[--idx] = verinum::Vz;
1047                   bits[--idx] = verinum::Vz;
1048                   break;
1049                 case '_':
1050                   break;
1051                 default:
1052                   assert(0);
1053             }
1054             ptr += 1;
1055       }
1056
1057       if (gn_strict_expr_width_flag && (based_size == 0))
1058             size = truncate_to_integer_width(bits, size);
1059
1060       verinum*out = new verinum(bits, size, false);
1061       out->has_sign(sign_flag);
1062       delete[]bits;
1063       return out;
1064 }
1065
1066
1067 /* Divide the integer given by the string by 2. Return the remainder bit. */
1068 static int dec_buf_div2(char *buf)
1069 {
1070     int partial;
1071     int len = strlen(buf);
1072     char *dst_ptr;
1073     int pos;
1074
1075     partial = 0;
1076     pos = 0;
1077
1078     /* dst_ptr overwrites buf, but all characters that are overwritten
1079        were already used by the reader. */
1080     dst_ptr = buf;
1081
1082     while(buf[pos] == '0')
1083         ++pos;
1084
1085     for(; pos<len; ++pos){
1086         if (buf[pos]=='_')
1087             continue;
1088
1089         assert(isdigit(buf[pos]));
1090
1091         partial= partial*10 + (buf[pos]-'0');
1092
1093         if (partial >= 2){
1094             *dst_ptr = partial/2 + '0';
1095             partial = partial & 1;
1096
1097             ++dst_ptr;
1098         }
1099         else{
1100             *dst_ptr = '0';
1101             ++dst_ptr;
1102         }
1103     }
1104
1105     // If result of division was zero string, it should remain that way.
1106     // Don't eat the last zero...
1107     if (dst_ptr == buf){
1108         *dst_ptr = '0';
1109         ++dst_ptr;
1110     }
1111     *dst_ptr = 0;
1112
1113     return partial;
1114 }
1115
1116 /* Support a single x, z or ? as a decimal constant (from 1364-2005). */
1117 verinum* make_undef_highz_dec(const char* ptr)
1118 {
1119       bool signed_flag = false;
1120
1121       assert(*ptr == '\'');
1122       /* The number may have decorations of the form 'sd<code>,
1123          possibly with space between the d and the <code>.
1124          Also, the 's' is optional, and marks the number as signed. */
1125       ptr += 1;
1126
1127       if (tolower(*ptr) == 's') {
1128           signed_flag = true;
1129           ptr += 1;
1130       }
1131
1132       assert(tolower(*ptr) == 'd');
1133       ptr += 1;
1134
1135       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1136           ptr += 1;
1137
1138         /* Process the code. */
1139       verinum::V* bits = new verinum::V[1];
1140       switch (*ptr) {
1141           case 'x':
1142           case 'X':
1143             bits[0] = verinum::Vx;
1144             break;
1145           case 'z':
1146           case 'Z':
1147           case '?':
1148             bits[0] = verinum::Vz;
1149             break;
1150           default:
1151             assert(0);
1152       }
1153       ptr += 1;
1154       while (*ptr == '_') ptr += 1;
1155       assert(*ptr == 0);
1156
1157       verinum*out = new verinum(bits, 1, false);
1158       out->has_sign(signed_flag);
1159       delete[]bits;
1160       return out;
1161 }
1162
1163 /*
1164  * Making a decimal number is much easier than the other base numbers
1165  * because there are no z or x values to worry about. It is much
1166  * harder than other base numbers because the width needed in bits is
1167  * hard to calculate.
1168  */
1169
1170 verinum*make_unsized_dec(const char*ptr)
1171 {
1172       char buf[4096];
1173       bool signed_flag = false;
1174       unsigned idx;
1175
1176       if (ptr[0] == '\'') {
1177               /* The number has decorations of the form 'sd<digits>,
1178                  possibly with space between the d and the <digits>.
1179                  Also, the 's' is optional, and marks the number as
1180                  signed. */
1181             ptr += 1;
1182
1183             if (tolower(*ptr) == 's') {
1184                   signed_flag = true;
1185                   ptr += 1;
1186             }
1187
1188             assert(tolower(*ptr) == 'd');
1189             ptr += 1;
1190
1191             while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1192                   ptr += 1;
1193
1194       } else {
1195               /* ... or an undecorated decimal number is passed
1196                  it. These numbers are treated as signed decimal. */
1197             assert(isdigit(*ptr));
1198             signed_flag = true;
1199       }
1200
1201
1202         /* Copy the digits into a buffer that I can use to do in-place
1203            decimal divides. */
1204       idx = 0;
1205       while ((idx < sizeof buf) && (*ptr != 0)) {
1206             if (*ptr == '_') {
1207                   ptr += 1;
1208                   continue;
1209             }
1210
1211             buf[idx++] = *ptr++;
1212       }
1213
1214       if (idx == sizeof buf) {
1215             fprintf(stderr, "Ridiculously long"
1216                     " decimal constant will be truncated!\n");
1217             idx -= 1;
1218       }
1219
1220       buf[idx] = 0;
1221       unsigned tmp_size = idx * 4 + 1;
1222       verinum::V *bits = new verinum::V[tmp_size];
1223
1224       idx = 0;
1225       while (idx < tmp_size) {
1226             int rem = dec_buf_div2(buf);
1227             bits[idx++] = (rem == 1) ? verinum::V1 : verinum::V0;
1228       }
1229
1230       assert(strcmp(buf, "0") == 0);
1231
1232         /* Now calculate the minimum number of bits needed to
1233            represent this unsigned number. */
1234       unsigned size = tmp_size;
1235       while ((size > 1) && (bits[size-1] == verinum::V0))
1236             size -= 1;
1237
1238         /* Now account for the signedness. Don't leave a 1 in the high
1239            bit if this is a signed number. */
1240       if (signed_flag && (bits[size-1] == verinum::V1)) {
1241             size += 1;
1242             assert(size <= tmp_size);
1243       }
1244
1245         /* Since we never have the real number of bits that a decimal
1246            number represents we do not check for extra bits. */
1247 //      if (based_size > 0) { }
1248
1249       if (gn_strict_expr_width_flag && (based_size == 0))
1250             size = truncate_to_integer_width(bits, size);
1251
1252       verinum*res = new verinum(bits, size, false);
1253       res->has_sign(signed_flag);
1254
1255       delete[]bits;
1256       return res;
1257 }
1258
1259 /*
1260  * Convert the string to a time unit or precision.
1261  * Returns true on failure.
1262  */
1263 static bool get_timescale_const(const char *&cp, int &res, bool is_unit)
1264 {
1265         /* Check for the 1 digit. */
1266       if (*cp != '1') {
1267             if (is_unit) {
1268                   VLerror(yylloc, "Invalid `timescale unit constant "
1269                                   "(1st digit)");
1270             } else {
1271                   VLerror(yylloc, "Invalid `timescale precision constant "
1272                                   "(1st digit)");
1273             }
1274             return true;
1275       }
1276       cp += 1;
1277
1278         /* Check the number of zeros after the 1. */
1279       res = strspn(cp, "0");
1280       if (res > 2) {
1281             if (is_unit) {
1282                   VLerror(yylloc, "Invalid `timescale unit constant "
1283                                   "(number of zeros)");
1284             } else {
1285                   VLerror(yylloc, "Invalid `timescale precision constant "
1286                                   "(number of zeros)");
1287             }
1288             return true;
1289       }
1290       cp += res;
1291
1292         /* Skip any space between the digits and the scaling string. */
1293       cp += strspn(cp, " \t");
1294
1295         /* Now process the scaling string. */
1296       if (strncmp("s", cp, 1) == 0) {
1297             res -= 0;
1298             cp += 1;
1299             return false;
1300
1301       } else if (strncmp("ms", cp, 2) == 0) {
1302             res -= 3;
1303             cp += 2;
1304             return false;
1305
1306       } else if (strncmp("us", cp, 2) == 0) {
1307             res -= 6;
1308             cp += 2;
1309             return false;
1310
1311       } else if (strncmp("ns", cp, 2) == 0) {
1312             res -= 9;
1313             cp += 2;
1314             return false;
1315
1316       } else if (strncmp("ps", cp, 2) == 0) {
1317             res -= 12;
1318             cp += 2;
1319             return false;
1320
1321       } else if (strncmp("fs", cp, 2) == 0) {
1322             res -= 15;
1323             cp += 2;
1324             return false;
1325
1326       }
1327
1328       if (is_unit) {
1329             VLerror(yylloc, "Invalid `timescale unit scale");
1330       } else {
1331             VLerror(yylloc, "Invalid `timescale precision scale");
1332       }
1333       return true;
1334 }
1335
1336
1337 /*
1338  * process either a pull0 or a pull1.
1339  */
1340 static void process_ucdrive(const char*txt)
1341 {
1342       UCDriveType ucd = UCD_NONE;
1343       const char*cp = txt + strspn(txt, " \t");
1344
1345         /* Skip the space after the `unconnected_drive directive. */
1346       if (cp == txt) {
1347             VLerror(yylloc, "Space required after `unconnected_drive "
1348                             "directive.");
1349             return;
1350       }
1351
1352         /* Check for the pull keyword. */
1353       if (strncmp("pull", cp, 4) != 0) {
1354             VLerror(yylloc, "pull required for `unconnected_drive "
1355                             "directive.");
1356             return;
1357       }
1358       cp += 4;
1359       if (*cp == '0') ucd = UCD_PULL0;
1360       else if (*cp == '1') ucd = UCD_PULL1;
1361       else {
1362             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
1363                     "`unconnected_drive does not support 'pull" << *cp
1364                  << "'." << endl;
1365             error_count += 1;
1366             return;
1367       }
1368       cp += 1;
1369
1370         /* Verify that only space and/or a single line comment is left. */
1371       cp += strspn(cp, " \t");
1372       if (strncmp(cp, "//", 2) != 0 &&
1373           (size_t)(cp-yytext) != strlen(yytext)) {
1374             VLerror(yylloc, "Invalid `unconnected_drive directive (extra "
1375                             "garbage after precision).");
1376             return;
1377       }
1378
1379       uc_drive = ucd;
1380 }
1381
1382 /*
1383  * The timescale parameter has the form:
1384  *      " <num> xs / <num> xs"
1385  */
1386 static void process_timescale(const char*txt)
1387 {
1388       const char*cp = txt + strspn(txt, " \t");
1389
1390         /* Skip the space after the `timescale directive. */
1391       if (cp == txt) {
1392             VLerror(yylloc, "Space required after `timescale directive.");
1393             return;
1394       }
1395
1396       int unit = 0;
1397       int prec = 0;
1398
1399         /* Get the time units. */
1400       if (get_timescale_const(cp, unit, true)) return;
1401
1402         /* Skip any space after the time units, the '/' and any
1403          * space after the '/'. */
1404       cp += strspn(cp, " \t");
1405       if (*cp != '/') {
1406             VLerror(yylloc, "`timescale separator '/' appears to be missing.");
1407             return;
1408       }
1409       cp += 1;
1410       cp += strspn(cp, " \t");
1411
1412         /* Get the time precision. */
1413       if (get_timescale_const(cp, prec, false)) return;
1414
1415         /* Verify that only space and/or a single line comment is left. */
1416       cp += strspn(cp, " \t");
1417       if (strncmp(cp, "//", 2) != 0 &&
1418           (size_t)(cp-yytext) != strlen(yytext)) {
1419             VLerror(yylloc, "Invalid `timescale directive (extra garbage "
1420                             "after precision).");
1421             return;
1422       }
1423
1424         /* The time unit must be greater than or equal to the precision. */
1425       if (unit < prec) {
1426             VLerror(yylloc, "error: `timescale unit must not be less than "
1427                             "the precision.");
1428             return;
1429       }
1430
1431       pform_set_timescale(unit, prec, yylloc.text, yylloc.first_line);
1432 }
1433
1434 int yywrap()
1435 {
1436       return 1;
1437 }
1438
1439 /*
1440  * The line directive matches lines of the form #line "foo" N and
1441  * calls this function. Here I parse out the file name and line
1442  * number, and change the yylloc to suite.
1443  */
1444 static void line_directive()
1445 {
1446       char *cpr;
1447         /* Skip any leading space. */
1448       char *cp = strchr(yytext, '#');
1449         /* Skip the #line directive. */
1450       assert(strncmp(cp, "#line", 5) == 0);
1451       cp += 5;
1452         /* Skip the space after the #line directive. */
1453       cp += strspn(cp, " \t");
1454
1455         /* Find the starting " and skip it. */
1456       char*fn_start = strchr(cp, '"');
1457       if (cp != fn_start) {
1458             VLerror(yylloc, "Invalid #line directive (file name start).");
1459             return;
1460       }
1461       fn_start += 1;
1462
1463         /* Find the last ". */
1464       char*fn_end = strrchr(fn_start, '"');
1465       if (!fn_end) {
1466             VLerror(yylloc, "Invalid #line directive (file name end).");
1467             return;
1468       }
1469
1470         /* Copy the file name and assign it to yylloc. */
1471       char*buf = new char[fn_end-fn_start+1];
1472       strncpy(buf, fn_start, fn_end-fn_start);
1473       buf[fn_end-fn_start] = 0;
1474
1475         /* Skip the space after the file name. */
1476       cp = fn_end;
1477       cp += 1;
1478       cpr = cp;
1479       cpr += strspn(cp, " \t");
1480       if (cp == cpr) {
1481             VLerror(yylloc, "Invalid #line directive (missing space after "
1482                             "file name).");
1483             delete[] buf;
1484             return;
1485       }
1486       cp = cpr;
1487
1488         /* Get the line number and verify that it is correct. */
1489       unsigned long lineno = strtoul(cp, &cpr, 10);
1490       if (cp == cpr) {
1491             VLerror(yylloc, "Invalid line number for #line directive.");
1492             delete[] buf;
1493             return;
1494       }
1495       cp = cpr;
1496
1497         /* Verify that only space is left. */
1498       cpr += strspn(cp, " \t");
1499       if ((size_t)(cpr-yytext) != strlen(yytext)) {
1500             VLerror(yylloc, "Invalid #line directive (extra garbage after "
1501                             "line number).");
1502             delete[] buf;
1503             return;
1504       }
1505
1506         /* Now we can assign the new values to yyloc. */
1507       yylloc.text = set_file_name(buf);
1508       yylloc.first_line = lineno;
1509 }
1510
1511 /*
1512  * The line directive matches lines of the form `line N "foo" M and
1513  * calls this function. Here I parse out the file name and line
1514  * number, and change the yylloc to suite. M is ignored.
1515  */
1516 static void line_directive2()
1517 {
1518       char *cpr;
1519         /* Skip any leading space. */
1520       char *cp = strchr(yytext, '`');
1521         /* Skip the `line directive. */
1522       assert(strncmp(cp, "`line", 5) == 0);
1523       cp += 5;
1524
1525         /* strtoul skips leading space. */
1526       unsigned long lineno = strtoul(cp, &cpr, 10);
1527       if (cp == cpr) {
1528             VLerror(yylloc, "Invalid line number for `line directive.");
1529             return;
1530       }
1531       lineno -= 1;
1532       cp = cpr;
1533
1534         /* Skip the space between the line number and the file name. */
1535       cpr += strspn(cp, " \t");
1536       if (cp == cpr) {
1537             VLerror(yylloc, "Invalid `line directive (missing space after "
1538                             "line number).");
1539             return;
1540       }
1541       cp = cpr;
1542
1543         /* Find the starting " and skip it. */
1544       char*fn_start = strchr(cp, '"');
1545       if (cp != fn_start) {
1546             VLerror(yylloc, "Invalid `line directive (file name start).");
1547             return;
1548       }
1549       fn_start += 1;
1550
1551         /* Find the last ". */
1552       char*fn_end = strrchr(fn_start, '"');
1553       if (!fn_end) {
1554             VLerror(yylloc, "Invalid `line directive (file name end).");
1555             return;
1556       }
1557
1558         /* Skip the space after the file name. */
1559       cp = fn_end + 1;
1560       cpr = cp;
1561       cpr += strspn(cp, " \t");
1562       if (cp == cpr) {
1563             VLerror(yylloc, "Invalid `line directive (missing space after "
1564                             "file name).");
1565             return;
1566       }
1567       cp = cpr;
1568
1569         /* Check that the level is correct, we do not need the level. */
1570       if (strspn(cp, "012") != 1) {
1571             VLerror(yylloc, "Invalid level for `line directive.");
1572             return;
1573       }
1574       cp += 1;
1575
1576         /* Verify that only space and/or a single line comment is left. */
1577       cp += strspn(cp, " \t");
1578       if (strncmp(cp, "//", 2) != 0 &&
1579           (size_t)(cp-yytext) != strlen(yytext)) {
1580             VLerror(yylloc, "Invalid `line directive (extra garbage after "
1581                             "level).");
1582             return;
1583       }
1584
1585         /* Copy the file name and assign it and the line number to yylloc. */
1586       char*buf = new char[fn_end-fn_start+1];
1587       strncpy(buf, fn_start, fn_end-fn_start);
1588       buf[fn_end-fn_start] = 0;
1589
1590       yylloc.text = set_file_name(buf);
1591       yylloc.first_line = lineno;
1592 }
1593
1594 /*
1595  * Reset all compiler directives. This will be called when a `resetall
1596  * directive is encountered or when a new compilation unit is started.
1597  */
1598 static void reset_all()
1599 {
1600       pform_set_default_nettype(NetNet::WIRE, yylloc.text, yylloc.first_line);
1601       in_celldefine = false;
1602       uc_drive = UCD_NONE;
1603       pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
1604 }
1605
1606 extern FILE*vl_input;
1607 void reset_lexor()
1608 {
1609       yyrestart(vl_input);
1610       yylloc.first_line = 1;
1611
1612         /* Announce the first file name. */
1613       yylloc.text = set_file_name(strdupnew(vl_file.c_str()));
1614
1615       if (separate_compilation) {
1616             reset_all();
1617             if (!keyword_mask_stack.empty()) {
1618                   lexor_keyword_mask = keyword_mask_stack.back();
1619                   keyword_mask_stack.clear();
1620             }
1621       }
1622 }
1623
1624 /*
1625  * Modern version of flex (>=2.5.9) can clean up the scanner data.
1626  */
1627 void destroy_lexor()
1628 {
1629 # ifdef FLEX_SCANNER
1630 #   if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
1631 #     if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
1632     yylex_destroy();
1633 #     endif
1634 #   endif
1635 # endif
1636 }