Make C style comments work in false/suppressed ifdef/etc. blocks.
[iverilog.git] / lexor.lex
blobce157f86315e773b39d7119c42a0944bd7bd5768
2 %option never-interactive
4 %{
5 /*
6  * Copyright (c) 1998-2000 Stephen Williams (steve@icarus.com)
7  *
8  *    This source code is free software; you can redistribute it
9  *    and/or modify it in source code form under the terms of the GNU
10  *    General Public License as published by the Free Software
11  *    Foundation; either version 2 of the License, or (at your option)
12  *    any later version.
13  *
14  *    This program is distributed in the hope that it will be useful,
15  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *    GNU General Public License for more details.
18  *
19  *    You should have received a copy of the GNU General Public License
20  *    along with this program; if not, write to the Free Software
21  *    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22  */
23 #ifdef HAVE_CVS_IDENT
24 #ident "$Id: lexor.lex,v 1.96 2007/06/14 03:50:00 steve Exp $"
25 #endif
27 # include "config.h"
29       //# define YYSTYPE lexval
31 # include  <iostream>
32 # include  "compiler.h"
33 # include  "parse_misc.h"
34 # include  "parse_api.h"
35 # include  "parse.h"
36 # include  <ctype.h>
37 # include  <string.h>
38 # include  "lexor_keyword.h"
41 # define YY_USER_INIT reset_lexor();
42 # define yylval VLlval
45  * Lexical location information is passed in the yylloc variable to th
46  * parser. The file names, strings, are kept in a list so that I can
47  * re-use them. The set_file_name function will return a pointer to
48  * the name as it exists in the list (and delete the passed string.)
49  * If the name is new, it will be added to the list.
50  */
51 extern YYLTYPE yylloc;
53 struct file_name_cell {
54       const char*text;
55       struct file_name_cell*next;
56       bool library_flag;
59 static struct file_name_cell*file_names = 0;
61 static const char* set_file_name(char*text)
63       struct file_name_cell*cur = file_names;
64       while (cur) {
65             if (strcmp(cur->text, text) == 0) {
66                   delete[]text;
67                   return cur->text;
68             }
70             cur = cur->next;
71       }
73       cur = new struct file_name_cell;
74       cur->text = text;
75       cur->next = file_names;
77         /* Check this file name with the list of library file
78            names. If there is a match, then turn on the
79            pform_library_flag. This is how the parser knows that
80            modules declared in this file are library modules. */
81       cur->library_flag = library_file_map[cur->text];
82       pform_library_flag = cur->library_flag;
83       return text;
87 extern void pform_set_timescale(int, int, const char*file, unsigned line);
89 void reset_lexor();
90 static void line_directive();
91 static void line_directive2();
93 static verinum*make_unsized_binary(const char*txt);
94 static verinum*make_unsized_dec(const char*txt);
95 static verinum*make_unsized_octal(const char*txt);
96 static verinum*make_unsized_hex(const char*txt);
98 static int dec_buf_div2(char *buf);
100 static void process_timescale(const char*txt);
102 static int comment_enter;
105 %x CCOMMENT
106 %x PCOMMENT
107 %x LCOMMENT
108 %x CSTRING
109 %s UDPTABLE
110 %x PPTIMESCALE
111 %x PPDEFAULT_NETTYPE
112 %s EDGES
114 W [ \t\b\f\r]+
118 ^"#line"[ ]+\"[^\"]*\"[ ]+[0-9]+.* { line_directive(); }
119 ^"`line"[ ]+[0-9]+[ ]+\"[^\"]*\".* { line_directive2(); }
121 [ \t\b\f\r] { ; }
122 \n { yylloc.first_line += 1; }
124   /* C++ style comments start with / / and run to the end of the
125      current line. These are very easy to handle. */
127 "//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
128 <LCOMMENT>.    { yymore(); }
129 <LCOMMENT>\n   { yylloc.first_line += 1; BEGIN(comment_enter); }
132   /* The contents of C-style comments are ignored, like white space. */
134 "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
135 <CCOMMENT>.    { yymore(); }
136 <CCOMMENT>\n   { yylloc.first_line += 1; yymore(); }
137 <CCOMMENT>"*/" { BEGIN(comment_enter); }
140 "(*" { return K_PSTAR; }
141 "*)" { return K_STARP; }
142 "<<" { return K_LS; }
143 "<<<" { return K_LS; /* Note: Functionally, <<< is the same as <<. */}
144 ">>"  { return K_RS; }
145 ">>>" { return K_RSS; }
146 "**" { return K_POW; }
147 "<=" { return K_LE; }
148 ">=" { return K_GE; }
149 "=>" { return K_EG; }
150 "*>" { return K_SG; }
151 "==" { return K_EQ; }
152 "!=" { return K_NE; }
153 "===" { return K_CEQ; }
154 "!==" { return K_CNE; }
155 "||" { return K_LOR; }
156 "&&" { return K_LAND; }
157 "&&&" { return K_TAND; }
158 "~|" { return K_NOR; }
159 "~^" { return K_NXOR; }
160 "^~" { return K_NXOR; }
161 "~&" { return K_NAND; }
162 "->" { return K_TRIGGER; }
163 "+:" { return K_PO_POS; }
164 "-:" { return K_PO_NEG; }
166   /* Watch out for the tricky case of (*). Cannot parse this as "(*"
167      and ")", but since I know that this is really ( * ), replace it
168      with "*" and return that. */
169 "("{W}*"*"{W}*")" { return '*'; }
171 <EDGES>"]" { BEGIN(0); return yytext[0]; }
172 [}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
174 \"            { BEGIN(CSTRING); }
175 <CSTRING>\\\\ { yymore(); /* Catch \\, which is a \ escaping itself */ }
176 <CSTRING>\\\" { yymore(); /* Catch \", which is an escaped quote */ }
177 <CSTRING>\n   { BEGIN(0);
178                 yylval.text = strdup(yytext);
179                 VLerror(yylloc, "Missing close quote of string.");
180                 yylloc.first_line += 1;
181                 return STRING; }
182 <CSTRING>\"   { BEGIN(0);
183                 yylval.text = strdup(yytext);
184                 yylval.text[strlen(yytext)-1] = 0;
185                 return STRING; }
186 <CSTRING>.    { yymore(); }
188 <UDPTABLE>\(\?0\)    { return '_'; }
189 <UDPTABLE>\(\?1\)    { return '+'; }
190 <UDPTABLE>\(\?[xX]\) { return '%'; }
191 <UDPTABLE>\(\?\?\)  { return '*'; }
192 <UDPTABLE>\(01\)    { return 'r'; }
193 <UDPTABLE>\(0[xX]\) { return 'Q'; }
194 <UDPTABLE>\(b[xX]\) { return 'q'; }
195 <UDPTABLE>\(b0\)    { return 'f'; /* b0 is 10|00, but only 10 is meaningful */}
196 <UDPTABLE>\(b1\)    { return 'r'; /* b1 is 11|01, but only 01 is meaningful */}
197 <UDPTABLE>\(0\?\)   { return 'P'; }
198 <UDPTABLE>\(10\)    { return 'f'; }
199 <UDPTABLE>\(1[xX]\) { return 'M'; }
200 <UDPTABLE>\(1\?\)   { return 'N'; }
201 <UDPTABLE>\([xX]0\) { return 'F'; }
202 <UDPTABLE>\([xX]1\) { return 'R'; }
203 <UDPTABLE>\([xX]\?\) { return 'B'; }
204 <UDPTABLE>[bB]     { return 'b'; }
205 <UDPTABLE>[lL]     { return 'l'; /* IVL extension */ }
206 <UDPTABLE>[hH]     { return 'h'; /* IVL extension */ }
207 <UDPTABLE>[fF]     { return 'f'; }
208 <UDPTABLE>[rR]     { return 'r'; }
209 <UDPTABLE>[xX]     { return 'x'; }
210 <UDPTABLE>[nN]     { return 'n'; }
211 <UDPTABLE>[pP]     { return 'p'; }
212 <UDPTABLE>[01\?\*\-] { return yytext[0]; }
214 <EDGES>"01" { return K_edge_descriptor; }
215 <EDGES>"0x" { return K_edge_descriptor; }
216 <EDGES>"0z" { return K_edge_descriptor; }
217 <EDGES>"10" { return K_edge_descriptor; }
218 <EDGES>"1x" { return K_edge_descriptor; }
219 <EDGES>"1z" { return K_edge_descriptor; }
220 <EDGES>"x0" { return K_edge_descriptor; }
221 <EDGES>"x1" { return K_edge_descriptor; }
222 <EDGES>"z0" { return K_edge_descriptor; }
223 <EDGES>"z1" { return K_edge_descriptor; }
225 [a-zA-Z_][a-zA-Z0-9$_]* {
226       int rc = lexor_keyword_code(yytext, yyleng);
227       switch (rc) {
228           case IDENTIFIER:
229             yylval.text = strdup(yytext);
230             if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
231                   rc = PATHPULSE_IDENTIFIER;
232             break;
234           case K_bool:
235           case K_logic:
236           case K_wone:
237             if (! gn_cadence_types_enabled()) {
238                   yylval.text = strdup(yytext);
239                   rc = IDENTIFIER;
240             } else {
241                   yylval.text = 0;
242             }
243             break;
245           case K_edge:
246             BEGIN(EDGES);
247             break;
249           default:
250             yylval.text = 0;
251             break;
252       }
254       return rc;
258 \\[^ \t\b\f\r\n]+         {
259       yylval.text = strdup(yytext+1);
260       return IDENTIFIER; }
262 \$([a-zA-Z0-9$_]+)        {
263       if (strcmp(yytext,"$setuphold") == 0)
264             return K_Ssetuphold;
265       if (strcmp(yytext,"$attribute") == 0)
266             return KK_attribute;
267       if (strcmp(yytext,"$hold") == 0)
268             return K_Shold;
269       if (strcmp(yytext,"$period") == 0)
270             return K_Speriod;
271       if (strcmp(yytext,"$recovery") == 0)
272             return K_Srecovery;
273       if (strcmp(yytext,"$recrem") == 0)
274             return K_Srecrem;
275       if (strcmp(yytext,"$setup") == 0)
276             return K_Ssetup;
277       if (strcmp(yytext,"$width") == 0)
278             return K_Swidth;
279       yylval.text = strdup(yytext);
280       return SYSTEM_IDENTIFIER; }
283 \'[sS]?[dD][ \t]*[0-9][0-9_]*  { yylval.number = make_unsized_dec(yytext);
284                             return BASED_NUMBER; }
285 \'[sS]?[bB][ \t]*[0-1xzXZ_\?]+ { yylval.number = make_unsized_binary(yytext);
286                         return BASED_NUMBER; }
287 \'[sS]?[oO][ \t]*[0-7xzXZ_\?]+ { yylval.number = make_unsized_octal(yytext);
288                         return BASED_NUMBER; }
289 \'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
290                               return BASED_NUMBER; }
292 [0-9][0-9_]* {
293       yylval.number = make_unsized_dec(yytext);
294       return DEC_NUMBER; }
296 [0-9][0-9_]*\.[0-9][0-9_]*([Ee][+-]?[0-9][0-9_]*)? {
297       yylval.realtime = new verireal(yytext);
298       return REALTIME; }
300 [0-9][0-9_]*[Ee][+-]?[0-9][0-9_]* {
301       yylval.realtime = new verireal(yytext);
302       return REALTIME; }
305   /* Notice and handle the timescale directive. */
307 ^{W}?`timescale { BEGIN(PPTIMESCALE); }
308 <PPTIMESCALE>.* { process_timescale(yytext); }
309 <PPTIMESCALE>\n {
310       yylloc.first_line += 1;
311       BEGIN(0); }
314   /* These are directives that I do not yet support. I think that IVL
315      should handle these, not an external preprocessor. */
317 ^{W}?`celldefine{W}?.*           {  }
318 ^{W}?`delay_mode_distributed{W}?.*  {  }
319 ^{W}?`delay_mode_unit{W}?.*      {  }
320 ^{W}?`delay_mode_path{W}?.*      {  }
321 ^{W}?`disable_portfaults{W}?.*   {  }
322 ^{W}?`enable_portfaults{W}?.*    {  }
323 ^{W}?`endcelldefine{W}?.*        {  }
324 `endprotect                      {  }
325 ^{W}?`nosuppress_faults{W}?.*    {  }
326 ^{W}?`nounconnected_drive{W}?.*  {  }
327 `protect                         {  }
328 ^{W}?`resetall{W}?.*             {  }
329 ^{W}?`suppress_faults{W}?.*      {  }
330 ^{W}?`unconnected_drive{W}?.*    {  }
331 ^{W}?`uselib{W}?.*               {  }
333   /* Notice and handle the default_nettype directive. The lexor
334      detects the default_nettype keyword, and the second part of the
335      rule collects the rest of the line and processes it. We only need
336      to look for the first work, and interpret it. */
338 `default_nettype{W}? { BEGIN(PPDEFAULT_NETTYPE); }
339 <PPDEFAULT_NETTYPE>.* {
340       NetNet::Type net_type;
341       size_t wordlen = strcspn(yytext, " \t\f\r\n");
342       yytext[wordlen] = 0;
343       if (strcmp(yytext,"wire") == 0) {
344             net_type = NetNet::WIRE;
346       } else if (strcmp(yytext,"none") == 0) {
347             net_type = NetNet::NONE;
349       } else {
350             cerr << yylloc.text << ":" << yylloc.first_line
351                  << " error: Net type " << yytext
352                  << " is not a valid (and supported)"
353                  << " default net type." << endl;
354             net_type = NetNet::WIRE;
355             error_count += 1;
356       }
357       pform_set_default_nettype(net_type, yylloc.text, yylloc.first_line);
359 <PPDEFAULT_NETTYPE>\n {
360       yylloc.first_line += 1;
361       BEGIN(0); }
364   /* These are directives that are not supported by me and should have
365      been handled by an external preprocessor such as ivlpp. */
367 ^{W}?`define{W}?.* {
368       cerr << yylloc.text << ":" << yylloc.first_line <<
369             ": `define not supported. Use an external preprocessor."
370            << endl;
371   }
373 ^{W}?`else{W}?.* {
374       cerr << yylloc.text << ":" << yylloc.first_line <<
375             ": `else not supported. Use an external preprocessor."
376            << endl;
377   }
379 ^{W}?`endif{W}?.* {
380       cerr << yylloc.text << ":" << yylloc.first_line <<
381             ": `endif not supported. Use an external preprocessor."
382            << endl;
383   }
385 ^{W}?`ifdef{W}?.* {
386       cerr << yylloc.text << ":" << yylloc.first_line <<
387             ": `ifdef not supported. Use an external preprocessor."
388            << endl;
389   }
391 ^`include{W}?.* {
392       cerr << yylloc.text << ":" << yylloc.first_line <<
393             ": `include not supported. Use an external preprocessor."
394            << endl;
395   }
397 ^`undef{W}?.* {
398       cerr << yylloc.text << ":" << yylloc.first_line <<
399             ": `undef not supported. Use an external preprocessor."
400            << endl;
401   }
404 `{W} { cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
405             << "Stray tic (`) here. Perhaps you put white space" << endl;
406        cerr << yylloc.text << ":" << yylloc.first_line << ":      : "
407             << "between the tic and preprocessor directive?"
408             << endl;
409        error_count += 1; }
411   /* Final catchall. something got lost or mishandled. */
413 . {   cerr << yylloc.text << ":" << yylloc.first_line
414            << ": error: unmatched character (";
415       if (isgraph(yytext[0]))
416             cerr << yytext[0];
417       else
418             cerr << "hex " << hex << (0xffU & ((unsigned) (yytext[0])));
420       cerr << ")" << endl;
421       error_count += 1; }
426  * The UDP state table needs some slightly different treatment by the
427  * lexor. The level characters are normally accepted as other things,
428  * so the parser needs to switch my mode when it believes in needs to.
429  */
430 void lex_start_table()
432       BEGIN(UDPTABLE);
435 void lex_end_table()
437       BEGIN(INITIAL);
440 static verinum*make_unsized_binary(const char*txt)
442       bool sign_flag = false;
443       const char*ptr = txt;
444       assert(*ptr == '\'');
445       ptr += 1;
447       if (tolower(*ptr) == 's') {
448             sign_flag = true;
449             ptr += 1;
450       }
452       assert(tolower(*ptr) == 'b');
453       ptr += 1;
455       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
456             ptr += 1;
458       unsigned size = 0;
459       for (const char*idx = ptr ;  *idx ;  idx += 1)
460             if (*idx != '_') size += 1;
462       verinum::V*bits = new verinum::V[size];
464       unsigned idx = size;
465       while (*ptr) {
466             switch (ptr[0]) {
467                 case '0':
468                   bits[--idx] = verinum::V0;
469                   break;
470                 case '1':
471                   bits[--idx] = verinum::V1;
472                   break;
473                 case 'z': case 'Z': case '?':
474                   bits[--idx] = verinum::Vz;
475                   break;
476                 case 'x': case 'X':
477                   bits[--idx] = verinum::Vx;
478                   break;
479                   case '_':
480                   break;
481                 default:
482                   fprintf(stderr, "%c\n", ptr[0]);
483                   assert(0);
484             }
485             ptr += 1;
486       }
488       verinum*out = new verinum(bits, size, false);
489       out->has_sign(sign_flag);
490       delete[]bits;
491       return out;
495 static verinum*make_unsized_octal(const char*txt)
497       bool sign_flag = false;
498       const char*ptr = txt;
499       assert(*ptr == '\'');
500       ptr += 1;
502       if (tolower(*ptr) == 's') {
503             sign_flag = true;
504             ptr += 1;
505       }
507       assert(tolower(*ptr) == 'o');
508       ptr += 1;
510       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
511             ptr += 1;
513       unsigned size = 0;
514       for (const char*idx = ptr ;  *idx ;  idx += 1)
515             if (*idx != '_') size += 3;
517       verinum::V*bits = new verinum::V[size];
519       unsigned idx = size;
520       while (*ptr) {
521             unsigned val;
522             switch (ptr[0]) {
523                 case '0': case '1': case '2': case '3':
524                 case '4': case '5': case '6': case '7':
525                   val = *ptr - '0';
526                   bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
527                   bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
528                   bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
529                   break;
530                 case 'x': case 'X':
531                   bits[--idx] = verinum::Vx;
532                   bits[--idx] = verinum::Vx;
533                   bits[--idx] = verinum::Vx;
534                   break;
535                 case 'z': case 'Z': case '?':
536                   bits[--idx] = verinum::Vz;
537                   bits[--idx] = verinum::Vz;
538                   bits[--idx] = verinum::Vz;
539                   break;
540                 case '_':
541                   break;
542                 default:
543                   assert(0);
544             }
545             ptr += 1;
546       }
548       verinum*out = new verinum(bits, size, false);
549       out->has_sign(sign_flag);
550       delete[]bits;
551       return out;
555 static verinum*make_unsized_hex(const char*txt)
557       bool sign_flag = false;
558       const char*ptr = txt;
559       assert(*ptr == '\'');
560       ptr += 1;
562       if (tolower(*ptr) == 's') {
563             sign_flag = true;
564             ptr += 1;
565       }
566       assert(tolower(*ptr) == 'h');
568       ptr += 1;
569       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
570             ptr += 1;
572       unsigned size = 0;
573       for (const char*idx = ptr ;  *idx ;  idx += 1)
574             if (*idx != '_') size += 4;
576       verinum::V*bits = new verinum::V[size];
578       unsigned idx = size;
579       while (*ptr) {
580             unsigned val;
581             switch (ptr[0]) {
582                 case '0': case '1': case '2': case '3': case '4':
583                 case '5': case '6': case '7': case '8': case '9':
584                   val = *ptr - '0';
585                   bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
586                   bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
587                   bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
588                   bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
589                   break;
590                 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
591                 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
592                   val = tolower(*ptr) - 'a' + 10;
593                   bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
594                   bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
595                   bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
596                   bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
597                   break;
598                 case 'x': case 'X':
599                   bits[--idx] = verinum::Vx;
600                   bits[--idx] = verinum::Vx;
601                   bits[--idx] = verinum::Vx;
602                   bits[--idx] = verinum::Vx;
603                   break;
604                 case 'z': case 'Z': case '?':
605                   bits[--idx] = verinum::Vz;
606                   bits[--idx] = verinum::Vz;
607                   bits[--idx] = verinum::Vz;
608                   bits[--idx] = verinum::Vz;
609                   break;
610                 case '_':
611                   break;
612                 default:
613                   assert(0);
614             }
615             ptr += 1;
616       }
618       verinum*out = new verinum(bits, size, false);
619       out->has_sign(sign_flag);
620       delete[]bits;
621       return out;
625 /* Divide the integer given by the string by 2. Return the remainder bit. */
626 static int dec_buf_div2(char *buf)
628     int partial;
629     int len = strlen(buf);
630     char *dst_ptr;
631     int pos;
633     partial = 0;
634     pos = 0;
636     /* dst_ptr overwrites buf, but all characters that are overwritten
637        were already used by the reader. */
638     dst_ptr = buf;
640     while(buf[pos] == '0')
641         ++pos;
643     for(; pos<len; ++pos){
644         if (buf[pos]=='_')
645             continue;
647         assert(isdigit(buf[pos]));
649         partial= partial*10 + (buf[pos]-'0');
651         if (partial >= 2){
652             *dst_ptr = partial/2 + '0';
653             partial = partial & 1;
655             ++dst_ptr;
656         }
657         else{
658             *dst_ptr = '0';
659             ++dst_ptr;
660         }
661     }
663     // If result of division was zero string, it should remain that way.
664     // Don't eat the last zero...
665     if (dst_ptr == buf){
666         *dst_ptr = '0';
667         ++dst_ptr;
668     }
669     *dst_ptr = 0;
671     return partial;
675  * Making a decimal number is much easier then the other base numbers
676  * because there are no z or x values to worry about. It is much
677  * harder then other base numbers because the width needed in bits is
678  * hard to calculate.
679  */
681 static verinum*make_unsized_dec(const char*ptr)
683       char buf[4096];
684       bool signed_flag = false;
685       unsigned idx;
687       if (ptr[0] == '\'') {
688               /* The number has decorations of the form 'sd<digits>,
689                  possibly with space between the d and the <digits>.
690                  Also, the 's' is optional, and markes the number as
691                  signed. */
692             ptr += 1;
694             if (tolower(*ptr) == 's') {
695                   signed_flag = true;
696                   ptr += 1;
697             }
699             assert(tolower(*ptr) == 'd');
700             ptr += 1;
702             while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
703                   ptr += 1;
705       } else {
706               /* ... or an undecorated decimal number is passed
707                  it. These numbers are treated as signed decimal. */
708             assert(isdigit(*ptr));
709             signed_flag = true;
710       }
713         /* Copy the digits into a buffer that I can use to do in-place
714            decimal divides. */
715       idx = 0;
716       while ((idx < sizeof buf) && (*ptr != 0)) {
717             if (*ptr == '_') {
718                   ptr += 1;
719                   continue;
720             }
722             buf[idx++] = *ptr++;
723       }
725       if (idx == sizeof buf) {
726             fprintf(stderr, "Ridiculously long"
727                     " decimal constant will be truncated!\n");
728             idx -= 1;
729       }
731       buf[idx] = 0;
732       unsigned tmp_size = idx * 4 + 1;
733       verinum::V *bits = new verinum::V[tmp_size];
735       idx = 0;
736       while (idx < tmp_size) {
737             int rem = dec_buf_div2(buf);
738             bits[idx++] = (rem == 1) ? verinum::V1 : verinum::V0;
739       }
741       assert(strcmp(buf, "0") == 0);
743         /* Now calculate the minimum number of bits needed to
744            represent this unsigned number. */
745       unsigned size = tmp_size;
746       while ((size > 1) && (bits[size-1] == verinum::V0))
747             size -= 1;
749         /* Now account for the signedness. Don't leave a 1 in the high
750            bit if this is a signed number. */
751       if (signed_flag && (bits[size-1] == verinum::V1)) {
752             size += 1;
753             assert(size <= tmp_size);
754       }
756       verinum*res = new verinum(bits, size, false);
757       res->has_sign(signed_flag);
759       delete[]bits;
760       return res;
765  * The timescale parameter has the form:
766  *      " <num> xs / <num> xs"
767  */
768 static void process_timescale(const char*txt)
770       unsigned num;
771       const char*cp = txt + strspn(txt, " \t");
772       char*tmp;
773       const char*ctmp;
775       int unit = 0;
776       int prec = 0;
778       num = strtoul(cp, &tmp, 10);
779       if (num == 0) {
780             VLerror(yylloc, "Invalid timescale string.");
781             return;
782       }
784       while (num >= 10) {
785             unit += 1;
786             num  /= 10;
787       }
788       if (num != 1) {
789             VLerror(yylloc, "Invalid timescale unit number.");
790             return;
791       }
793       cp = tmp;
794       cp += strspn(cp, " \t");
795       ctmp = cp + strcspn(cp, " \t/");
797       if (strncmp("s", cp, ctmp-cp) == 0) {
798             unit -= 0;
800       } else if (strncmp("ms", cp, ctmp-cp) == 0) {
801             unit -= 3;
803       } else if (strncmp("us", cp, ctmp-cp) == 0) {
804             unit -= 6;
806       } else if (strncmp("ns", cp, ctmp-cp) == 0) {
807             unit -= 9;
809       } else if (strncmp("ps", cp, ctmp-cp) == 0) {
810             unit -= 12;
812       } else if (strncmp("fs", cp, ctmp-cp) == 0) {
813             unit -= 15;
815       } else {
816             VLerror(yylloc, "Invalid timescale unit of measurement");
817             return;
818       }
820       cp = ctmp;
821       cp += strspn(cp, " \t/");
823       num = strtoul(cp, &tmp, 10);
824       if (num == 0) {
825             VLerror(yylloc, "Invalid timescale string.");
826             return;
827       }
828       assert(num);
829       while (num >= 10) {
830             prec += 1;
831             num  /= 10;
832       }
833       if (num != 1) {
834             VLerror(yylloc, "Invalid timescale precision number.");
835             return;
836       }
838       cp = tmp;
839       cp += strspn(cp, " \t");
840       ctmp = cp + strcspn(cp, " \t\r");
842       if (strncmp("s", cp, ctmp-cp) == 0) {
843             prec -= 0;
845       } else if (strncmp("ms", cp, ctmp-cp) == 0) {
846             prec -= 3;
848       } else if (strncmp("us", cp, ctmp-cp) == 0) {
849             prec -= 6;
851       } else if (strncmp("ns", cp, ctmp-cp) == 0) {
852             prec -= 9;
854       } else if (strncmp("ps", cp, ctmp-cp) == 0) {
855             prec -= 12;
857       } else if (strncmp("fs", cp, ctmp-cp) == 0) {
858             prec -= 15;
860       } else {
861             VLerror(yylloc, "Invalid timescale precision units of measurement");
862             return;
863       }
865       pform_set_timescale(unit, prec, yylloc.text, yylloc.first_line);
868 int yywrap()
870       return 1;
874  * The line directive matches lines of the form #line "foo" N and
875  * calls this function. Here I parse out the file name and line
876  * number, and change the yylloc to suite.
877  */
878 static void line_directive()
880       char*qt1 = strchr(yytext, '"');
881       assert(qt1);
882       qt1 += 1;
884       char*qt2 = strchr(qt1, '"');
885       assert(qt2);
887       char*buf = new char[qt2-qt1+1];
888       strncpy(buf, qt1, qt2-qt1);
889       buf[qt2-qt1] = 0;
891       yylloc.text = set_file_name(buf);
893       qt2 += 1;
894       yylloc.first_line = strtoul(qt2,0,0);
897 static void line_directive2()
899       assert(strncmp(yytext,"`line",5) == 0);
900       char*cp = yytext + strlen("`line");
901       cp += strspn(cp, " ");
902       yylloc.first_line = strtoul(cp,&cp,10);
904       yylloc.first_line -= 1;
906       cp += strspn(cp, " ");
907       if (*cp == 0) return;
909       char*qt1 = strchr(yytext, '"');
910       assert(qt1);
911       qt1 += 1;
913       char*qt2 = strchr(qt1, '"');
914       assert(qt2);
916       char*buf = new char[qt2-qt1+1];
917       strncpy(buf, qt1, qt2-qt1);
918       buf[qt2-qt1] = 0;
920       yylloc.text = set_file_name(buf);
923 extern FILE*vl_input;
924 void reset_lexor()
926       yyrestart(vl_input);
927       yylloc.first_line = 1;
929         /* Start the file_names list. From here on, as I get a file
930            name, I will add it to this list. Only add the name if it
931            is not already in the list. */
932       file_names = new struct file_name_cell;
933       file_names->text = strdup(vl_file.c_str());
934       file_names->next = 0;
935       yylloc.text = file_names->text;