2 %option never-interactive
7 * Copyright (c) 1998-2008 Stephen Williams (steve@icarus.com)
9 * This source code is free software; you can redistribute it
10 * and/or modify it in source code form under the terms of the GNU
11 * General Public License as published by the Free Software
12 * Foundation; either version 2 of the License, or (at your option)
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27 //# define YYSTYPE lexval
30 # include "compiler.h"
31 # include "parse_misc.h"
32 # include "parse_api.h"
36 # include "lexor_keyword.h"
37 # include "discipline.h"
40 # define YY_USER_INIT reset_lexor();
41 # define yylval VLlval
44 * Lexical location information is passed in the yylloc variable to th
45 * parser. The file names, strings, are kept in a list so that I can
46 * re-use them. The set_file_name function will return a pointer to
47 * the name as it exists in the list (and delete the passed string.)
48 * If the name is new, it will be added to the list.
50 extern YYLTYPE yylloc;
52 static char* strdupnew(char const *str)
54 return str ? strcpy(new char [strlen(str)+1], str) : 0;
57 static const char* set_file_name(char*text)
59 perm_string path = filename_strings.make(text);
62 /* Check this file name with the list of library file
63 names. If there is a match, then turn on the
64 pform_library_flag. This is how the parser knows that
65 modules declared in this file are library modules. */
66 pform_library_flag = library_file_map[path];
71 extern void pform_set_timescale(int, int, const char*file, unsigned line);
74 static void line_directive();
75 static void line_directive2();
77 static verinum*make_unsized_binary(const char*txt);
78 static verinum*make_undef_highz_dec(const char*txt);
79 static verinum*make_unsized_dec(const char*txt);
80 static verinum*make_unsized_octal(const char*txt);
81 static verinum*make_unsized_hex(const char*txt);
83 static int dec_buf_div2(char *buf);
85 static void process_timescale(const char*txt);
87 static list<int> keyword_mask_stack;
89 static int comment_enter;
109 ^"#line"[ ]+\"[^\"]*\"[ ]+[0-9]+.* { line_directive(); }
110 ^"`line"[ ]+[0-9]+[ ]+\"[^\"]*\".* { line_directive2(); }
113 \n { yylloc.first_line += 1; }
115 /* C++ style comments start with / / and run to the end of the
116 current line. These are very easy to handle. */
118 "//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
119 <LCOMMENT>. { yymore(); }
120 <LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
123 /* The contents of C-style comments are ignored, like white space. */
125 "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
126 <CCOMMENT>. { yymore(); }
127 <CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
128 <CCOMMENT>"*/" { BEGIN(comment_enter); }
131 "(*" { return K_PSTAR; }
132 "*)" { return K_STARP; }
133 "<<" { return K_LS; }
134 "<<<" { return K_LS; /* Note: Functionally, <<< is the same as <<. */}
135 ">>" { return K_RS; }
136 ">>>" { return K_RSS; }
137 "**" { return K_POW; }
138 "<=" { return K_LE; }
139 ">=" { return K_GE; }
140 "=>" { return K_EG; }
141 "*>" { return K_SG; }
142 "==" { return K_EQ; }
143 "!=" { return K_NE; }
144 "===" { return K_CEQ; }
145 "!==" { return K_CNE; }
146 "||" { return K_LOR; }
147 "&&" { return K_LAND; }
148 "&&&" { return K_TAND; }
149 "~|" { return K_NOR; }
150 "~^" { return K_NXOR; }
151 "^~" { return K_NXOR; }
152 "~&" { return K_NAND; }
153 "->" { return K_TRIGGER; }
154 "+:" { return K_PO_POS; }
155 "-:" { return K_PO_NEG; }
156 "<+" { return K_CONTRIBUTE; }
158 /* Watch out for the tricky case of (*). Cannot parse this as "(*"
159 and ")", but since I know that this is really ( * ), replace it
160 with "*" and return that. */
161 "("{W}*"*"{W}*")" { return '*'; }
163 <EDGES>"]" { BEGIN(0); return yytext[0]; }
164 [}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
166 \" { BEGIN(CSTRING); }
167 <CSTRING>\\\\ { yymore(); /* Catch \\, which is a \ escaping itself */ }
168 <CSTRING>\\\" { yymore(); /* Catch \", which is an escaped quote */ }
169 <CSTRING>\n { BEGIN(0);
170 yylval.text = strdup(yytext);
171 VLerror(yylloc, "Missing close quote of string.");
172 yylloc.first_line += 1;
174 <CSTRING>\" { BEGIN(0);
175 yylval.text = strdup(yytext);
176 yylval.text[strlen(yytext)-1] = 0;
178 <CSTRING>. { yymore(); }
180 <UDPTABLE>\(\?0\) { return '_'; }
181 <UDPTABLE>\(\?1\) { return '+'; }
182 <UDPTABLE>\(\?[xX]\) { return '%'; }
183 <UDPTABLE>\(\?\?\) { return '*'; }
184 <UDPTABLE>\(01\) { return 'r'; }
185 <UDPTABLE>\(0[xX]\) { return 'Q'; }
186 <UDPTABLE>\(b[xX]\) { return 'q'; }
187 <UDPTABLE>\(b0\) { return 'f'; /* b0 is 10|00, but only 10 is meaningful */}
188 <UDPTABLE>\(b1\) { return 'r'; /* b1 is 11|01, but only 01 is meaningful */}
189 <UDPTABLE>\(0\?\) { return 'P'; }
190 <UDPTABLE>\(10\) { return 'f'; }
191 <UDPTABLE>\(1[xX]\) { return 'M'; }
192 <UDPTABLE>\(1\?\) { return 'N'; }
193 <UDPTABLE>\([xX]0\) { return 'F'; }
194 <UDPTABLE>\([xX]1\) { return 'R'; }
195 <UDPTABLE>\([xX]\?\) { return 'B'; }
196 <UDPTABLE>[bB] { return 'b'; }
197 <UDPTABLE>[lL] { return 'l'; /* IVL extension */ }
198 <UDPTABLE>[hH] { return 'h'; /* IVL extension */ }
199 <UDPTABLE>[fF] { return 'f'; }
200 <UDPTABLE>[rR] { return 'r'; }
201 <UDPTABLE>[xX] { return 'x'; }
202 <UDPTABLE>[nN] { return 'n'; }
203 <UDPTABLE>[pP] { return 'p'; }
204 <UDPTABLE>[01\?\*\-] { return yytext[0]; }
206 <EDGES>"01" { return K_edge_descriptor; }
207 <EDGES>"0x" { return K_edge_descriptor; }
208 <EDGES>"0z" { return K_edge_descriptor; }
209 <EDGES>"10" { return K_edge_descriptor; }
210 <EDGES>"1x" { return K_edge_descriptor; }
211 <EDGES>"1z" { return K_edge_descriptor; }
212 <EDGES>"x0" { return K_edge_descriptor; }
213 <EDGES>"x1" { return K_edge_descriptor; }
214 <EDGES>"z0" { return K_edge_descriptor; }
215 <EDGES>"z1" { return K_edge_descriptor; }
217 [a-zA-Z_][a-zA-Z0-9$_]* {
218 int rc = lexor_keyword_code(yytext, yyleng);
221 yylval.text = strdupnew(yytext);
222 if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
223 rc = PATHPULSE_IDENTIFIER;
235 /* If this identifier names a discipline, then return this as
236 a DISCIPLINE_IDENTIFIER and return the discipline as the
238 if (rc == IDENTIFIER && gn_verilog_ams_flag) {
239 perm_string tmp = lex_strings.make(yylval.text);
240 map<perm_string,discipline_t*>::iterator cur = disciplines.find(tmp);
241 if (cur != disciplines.end()) {
242 yylval.discipline = (*cur).second;
243 rc = DISCIPLINE_IDENTIFIER;
252 yylval.text = strdupnew(yytext+1);
256 if (strcmp(yytext,"$setuphold") == 0)
258 if (strcmp(yytext,"$attribute") == 0)
260 if (strcmp(yytext,"$hold") == 0)
262 if (strcmp(yytext,"$period") == 0)
264 if (strcmp(yytext,"$recovery") == 0)
266 if (strcmp(yytext,"$recrem") == 0)
268 if (strcmp(yytext,"$setup") == 0)
270 if (strcmp(yytext,"$width") == 0)
272 yylval.text = strdupnew(yytext);
273 return SYSTEM_IDENTIFIER; }
276 \'[sS]?[dD][ \t]*[0-9][0-9_]* { yylval.number = make_unsized_dec(yytext);
277 return BASED_NUMBER; }
278 \'[sS]?[dD][ \t]*[xzXZ?]_* { yylval.number = make_undef_highz_dec(yytext);
279 return BASED_NUMBER; }
280 \'[sS]?[bB][ \t]*[0-1xzXZ_\?]+ { yylval.number = make_unsized_binary(yytext);
281 return BASED_NUMBER; }
282 \'[sS]?[oO][ \t]*[0-7xzXZ_\?]+ { yylval.number = make_unsized_octal(yytext);
283 return BASED_NUMBER; }
284 \'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
285 return BASED_NUMBER; }
288 yylval.number = make_unsized_dec(yytext);
289 based_size = yylval.number->as_ulong();
292 /* These rules handle the scaled real literals from Verilog-AMS. The
293 value is a number with a single letter scale factor. If
294 verilog-ams is not enabled, then reject this rule. If it is
295 enabled, then collect the scale and use it to scale the value. */
296 [0-9][0-9_]*\.[0-9][0-9_]*/{S} {
297 if (!gn_verilog_ams_flag) REJECT;
302 if (!gn_verilog_ams_flag) REJECT;
307 size_t token_len = strlen(yytext);
308 char*tmp = new char[token_len + 5];
311 switch (tmp[token_len-1]) {
312 case 'a': scale = -18; break; /* atto- */
313 case 'f': scale = -15; break; /* femto- */
314 case 'p': scale = -12; break; /* pico- */
315 case 'n': scale = -9; break; /* nano- */
316 case 'u': scale = -6; break; /* micro- */
317 case 'm': scale = -3; break; /* milli- */
318 case 'k': scale = 3; break; /* kilo- */
319 case 'K': scale = 3; break; /* kilo- */
320 case 'M': scale = 6; break; /* mega- */
321 case 'G': scale = 9; break; /* giga- */
322 case 'T': scale = 12; break; /* tera- */
323 default: assert(0); break;
325 snprintf(tmp+token_len-1, 5, "e%d", scale);
326 yylval.realtime = new verireal(tmp);
332 [0-9][0-9_]*\.[0-9][0-9_]*([Ee][+-]?[0-9][0-9_]*)? {
333 yylval.realtime = new verireal(yytext);
336 [0-9][0-9_]*[Ee][+-]?[0-9][0-9_]* {
337 yylval.realtime = new verireal(yytext);
341 /* Notice and handle the timescale directive. */
343 ^{W}?`timescale { BEGIN(PPTIMESCALE); }
344 <PPTIMESCALE>.* { process_timescale(yytext); }
346 yylloc.first_line += 1;
350 /* These are directives that I do not yet support. I think that IVL
351 should handle these, not an external preprocessor. */
353 ^{W}?`celldefine{W}?.* { }
354 ^{W}?`default_decay_time{W}?.* { }
355 ^{W}?`default_trireg_strength{W}?.* { }
356 ^{W}?`delay_mode_distributed{W}?.* { }
357 ^{W}?`delay_mode_unit{W}?.* { }
358 ^{W}?`delay_mode_path{W}?.* { }
359 ^{W}?`delay_mode_zero{W}?.* { }
360 ^{W}?`disable_portfaults{W}?.* { }
361 ^{W}?`enable_portfaults{W}?.* { }
362 ^{W}?`endcelldefine{W}?.* { }
365 ^{W}?`nosuppress_faults{W}?.* { }
366 ^{W}?`nounconnected_drive{W}?.* { }
368 ^{W}?`resetall{W}?.* { }
369 ^{W}?`suppress_faults{W}?.* { }
370 ^{W}?`unconnected_drive{W}?.* { }
371 ^{W}?`uselib{W}?.* { }
373 ^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); }
375 <PPBEGIN_KEYWORDS>\"[a-zA-Z0-9 -]*\".* {
376 keyword_mask_stack.push_front(lexor_keyword_mask);
378 char*word = yytext+1;
379 char*tail = strchr(word, '"');
381 if (strcmp(word,"1364-1995") == 0) {
382 lexor_keyword_mask = GN_KEYWORDS_1364_1995;
383 } else if (strcmp(word,"1364-2001") == 0) {
384 lexor_keyword_mask = GN_KEYWORDS_1364_1995
385 |GN_KEYWORDS_1364_2001
386 |GN_KEYWORDS_1364_2001_CONFIG;
387 } else if (strcmp(word,"1364-2001-noconfig") == 0) {
388 lexor_keyword_mask = GN_KEYWORDS_1364_1995
389 |GN_KEYWORDS_1364_2001;
390 } else if (strcmp(word,"1364-2005") == 0) {
391 lexor_keyword_mask = GN_KEYWORDS_1364_1995
392 |GN_KEYWORDS_1364_2001
393 |GN_KEYWORDS_1364_2001_CONFIG
394 |GN_KEYWORDS_1364_2005;
395 } else if (strcmp(word,"VAMS-2.3") == 0) {
396 lexor_keyword_mask = GN_KEYWORDS_1364_1995
397 |GN_KEYWORDS_1364_2001
398 |GN_KEYWORDS_1364_2001_CONFIG
399 |GN_KEYWORDS_1364_2005
400 |GN_KEYWORDS_VAMS_2_3;
402 fprintf(stderr, "%s:%d: Ignoring unknown keywords string: %s\n",
403 yylloc.text, yylloc.first_line, word);
408 <PPBEGIN_KEYWORDS>.* {
409 fprintf(stderr, "%s:%d: Malformed keywords specification: %s\n",
410 yylloc.text, yylloc.first_line, yytext);
414 ^{W}?`end_keywords{W}?.* {
415 if (!keyword_mask_stack.empty()) {
416 lexor_keyword_mask = keyword_mask_stack.front();
417 keyword_mask_stack.pop_front();
419 fprintf(stderr, "%s:%d: Mismatched end_keywords directive\n",
420 yylloc.text, yylloc.first_line);
424 /* Notice and handle the default_nettype directive. The lexor
425 detects the default_nettype keyword, and the second part of the
426 rule collects the rest of the line and processes it. We only need
427 to look for the first work, and interpret it. */
429 `default_nettype{W}? { BEGIN(PPDEFAULT_NETTYPE); }
430 <PPDEFAULT_NETTYPE>.* {
431 NetNet::Type net_type;
432 size_t wordlen = strcspn(yytext, " \t\f\r\n");
434 if (strcmp(yytext,"wire") == 0) {
435 net_type = NetNet::WIRE;
437 } else if (strcmp(yytext,"none") == 0) {
438 net_type = NetNet::NONE;
441 cerr << yylloc.text << ":" << yylloc.first_line
442 << " error: Net type " << yytext
443 << " is not a valid (and supported)"
444 << " default net type." << endl;
445 net_type = NetNet::WIRE;
448 pform_set_default_nettype(net_type, yylloc.text, yylloc.first_line);
450 <PPDEFAULT_NETTYPE>\n {
451 yylloc.first_line += 1;
455 /* These are directives that are not supported by me and should have
456 been handled by an external preprocessor such as ivlpp. */
459 cerr << yylloc.text << ":" << yylloc.first_line <<
460 ": `define not supported. Use an external preprocessor."
465 cerr << yylloc.text << ":" << yylloc.first_line <<
466 ": `else not supported. Use an external preprocessor."
471 cerr << yylloc.text << ":" << yylloc.first_line <<
472 ": `endif not supported. Use an external preprocessor."
477 cerr << yylloc.text << ":" << yylloc.first_line <<
478 ": `ifdef not supported. Use an external preprocessor."
483 cerr << yylloc.text << ":" << yylloc.first_line <<
484 ": `include not supported. Use an external preprocessor."
489 cerr << yylloc.text << ":" << yylloc.first_line <<
490 ": `undef not supported. Use an external preprocessor."
495 `{W} { cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
496 << "Stray tic (`) here. Perhaps you put white space" << endl;
497 cerr << yylloc.text << ":" << yylloc.first_line << ": : "
498 << "between the tic and preprocessor directive?"
502 /* Final catchall. something got lost or mishandled. */
503 /* XXX Should we tell the luser something about the lexical state? */
505 <*>.|\n { cerr << yylloc.text << ":" << yylloc.first_line
506 << ": error: unmatched character (";
507 if (isgraph(yytext[0]))
510 cerr << "hex " << hex << (0xffU & ((unsigned) (yytext[0])));
518 * The UDP state table needs some slightly different treatment by the
519 * lexor. The level characters are normally accepted as other things,
520 * so the parser needs to switch my mode when it believes in needs to.
522 void lex_start_table()
532 static verinum*make_unsized_binary(const char*txt)
534 bool sign_flag = false;
535 const char*ptr = txt;
536 assert(*ptr == '\'');
539 if (tolower(*ptr) == 's') {
544 assert(tolower(*ptr) == 'b');
547 while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
551 for (const char*idx = ptr ; *idx ; idx += 1)
552 if (*idx != '_') size += 1;
554 if ((based_size > 0) && (size > based_size)) yywarn(yylloc,
555 "extra digits given for sized binary constant.");
557 verinum::V*bits = new verinum::V[size];
563 bits[--idx] = verinum::V0;
566 bits[--idx] = verinum::V1;
568 case 'z': case 'Z': case '?':
569 bits[--idx] = verinum::Vz;
572 bits[--idx] = verinum::Vx;
577 fprintf(stderr, "%c\n", ptr[0]);
583 verinum*out = new verinum(bits, size, false);
584 out->has_sign(sign_flag);
590 static verinum*make_unsized_octal(const char*txt)
592 bool sign_flag = false;
593 const char*ptr = txt;
594 assert(*ptr == '\'');
597 if (tolower(*ptr) == 's') {
602 assert(tolower(*ptr) == 'o');
605 while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
609 for (const char*idx = ptr ; *idx ; idx += 1)
610 if (*idx != '_') size += 3;
612 if (based_size > 0) {
613 int rem = based_size % 3;
614 if (rem != 0) based_size += 3 - rem;
615 if (size > based_size) yywarn(yylloc,
616 "extra digits given for sized octal constant.");
619 verinum::V*bits = new verinum::V[size];
625 case '0': case '1': case '2': case '3':
626 case '4': case '5': case '6': case '7':
628 bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
629 bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
630 bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
633 bits[--idx] = verinum::Vx;
634 bits[--idx] = verinum::Vx;
635 bits[--idx] = verinum::Vx;
637 case 'z': case 'Z': case '?':
638 bits[--idx] = verinum::Vz;
639 bits[--idx] = verinum::Vz;
640 bits[--idx] = verinum::Vz;
650 verinum*out = new verinum(bits, size, false);
651 out->has_sign(sign_flag);
657 static verinum*make_unsized_hex(const char*txt)
659 bool sign_flag = false;
660 const char*ptr = txt;
661 assert(*ptr == '\'');
664 if (tolower(*ptr) == 's') {
668 assert(tolower(*ptr) == 'h');
671 while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
675 for (const char*idx = ptr ; *idx ; idx += 1)
676 if (*idx != '_') size += 4;
678 if (based_size > 0) {
679 int rem = based_size % 4;
680 if (rem != 0) based_size += 4 - rem;
681 if (size > based_size) yywarn(yylloc,
682 "extra digits given for sized hex constant.");
685 verinum::V*bits = new verinum::V[size];
691 case '0': case '1': case '2': case '3': case '4':
692 case '5': case '6': case '7': case '8': case '9':
694 bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
695 bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
696 bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
697 bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
699 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
700 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
701 val = tolower(*ptr) - 'a' + 10;
702 bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
703 bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
704 bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
705 bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
708 bits[--idx] = verinum::Vx;
709 bits[--idx] = verinum::Vx;
710 bits[--idx] = verinum::Vx;
711 bits[--idx] = verinum::Vx;
713 case 'z': case 'Z': case '?':
714 bits[--idx] = verinum::Vz;
715 bits[--idx] = verinum::Vz;
716 bits[--idx] = verinum::Vz;
717 bits[--idx] = verinum::Vz;
727 verinum*out = new verinum(bits, size, false);
728 out->has_sign(sign_flag);
734 /* Divide the integer given by the string by 2. Return the remainder bit. */
735 static int dec_buf_div2(char *buf)
738 int len = strlen(buf);
745 /* dst_ptr overwrites buf, but all characters that are overwritten
746 were already used by the reader. */
749 while(buf[pos] == '0')
752 for(; pos<len; ++pos){
756 assert(isdigit(buf[pos]));
758 partial= partial*10 + (buf[pos]-'0');
761 *dst_ptr = partial/2 + '0';
762 partial = partial & 1;
772 // If result of division was zero string, it should remain that way.
773 // Don't eat the last zero...
783 /* Support a single x, z or ? as a decimal constant (from 1364-2005). */
784 static verinum* make_undef_highz_dec(const char* ptr)
786 bool signed_flag = false;
788 assert(*ptr == '\'');
789 /* The number may have decorations of the form 'sd<code>,
790 possibly with space between the d and the <code>.
791 Also, the 's' is optional, and marks the number as signed. */
794 if (tolower(*ptr) == 's') {
799 assert(tolower(*ptr) == 'd');
802 while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
805 /* Process the code. */
806 verinum::V* bits = new verinum::V[1];
810 bits[0] = verinum::Vx;
815 bits[0] = verinum::Vz;
821 while (*ptr == '_') ptr += 1;
824 verinum*out = new verinum(bits, 1, false);
825 out->has_sign(signed_flag);
831 * Making a decimal number is much easier then the other base numbers
832 * because there are no z or x values to worry about. It is much
833 * harder then other base numbers because the width needed in bits is
837 static verinum*make_unsized_dec(const char*ptr)
840 bool signed_flag = false;
843 if (ptr[0] == '\'') {
844 /* The number has decorations of the form 'sd<digits>,
845 possibly with space between the d and the <digits>.
846 Also, the 's' is optional, and markes the number as
850 if (tolower(*ptr) == 's') {
855 assert(tolower(*ptr) == 'd');
858 while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
862 /* ... or an undecorated decimal number is passed
863 it. These numbers are treated as signed decimal. */
864 assert(isdigit(*ptr));
869 /* Copy the digits into a buffer that I can use to do in-place
872 while ((idx < sizeof buf) && (*ptr != 0)) {
881 if (idx == sizeof buf) {
882 fprintf(stderr, "Ridiculously long"
883 " decimal constant will be truncated!\n");
888 unsigned tmp_size = idx * 4 + 1;
889 verinum::V *bits = new verinum::V[tmp_size];
892 while (idx < tmp_size) {
893 int rem = dec_buf_div2(buf);
894 bits[idx++] = (rem == 1) ? verinum::V1 : verinum::V0;
897 assert(strcmp(buf, "0") == 0);
899 /* Now calculate the minimum number of bits needed to
900 represent this unsigned number. */
901 unsigned size = tmp_size;
902 while ((size > 1) && (bits[size-1] == verinum::V0))
905 /* Now account for the signedness. Don't leave a 1 in the high
906 bit if this is a signed number. */
907 if (signed_flag && (bits[size-1] == verinum::V1)) {
909 assert(size <= tmp_size);
912 /* Since we never have the real number of bits that a decimal
913 number represents we do not check for extra bits. */
914 // if (based_size > 0) { }
916 verinum*res = new verinum(bits, size, false);
917 res->has_sign(signed_flag);
925 * The timescale parameter has the form:
926 * " <num> xs / <num> xs"
928 static void process_timescale(const char*txt)
931 const char*cp = txt + strspn(txt, " \t");
938 num = strtoul(cp, &tmp, 10);
940 VLerror(yylloc, "Invalid timescale string.");
949 VLerror(yylloc, "Invalid timescale unit number.");
954 cp += strspn(cp, " \t");
955 ctmp = cp + strcspn(cp, " \t/");
957 if (strncmp("s", cp, ctmp-cp) == 0) {
960 } else if (strncmp("ms", cp, ctmp-cp) == 0) {
963 } else if (strncmp("us", cp, ctmp-cp) == 0) {
966 } else if (strncmp("ns", cp, ctmp-cp) == 0) {
969 } else if (strncmp("ps", cp, ctmp-cp) == 0) {
972 } else if (strncmp("fs", cp, ctmp-cp) == 0) {
976 VLerror(yylloc, "Invalid timescale unit of measurement");
981 cp += strspn(cp, " \t/");
983 num = strtoul(cp, &tmp, 10);
985 VLerror(yylloc, "Invalid timescale string.");
994 VLerror(yylloc, "Invalid timescale precision number.");
999 cp += strspn(cp, " \t");
1000 ctmp = cp + strcspn(cp, " \t\r");
1002 if (strncmp("s", cp, ctmp-cp) == 0) {
1005 } else if (strncmp("ms", cp, ctmp-cp) == 0) {
1008 } else if (strncmp("us", cp, ctmp-cp) == 0) {
1011 } else if (strncmp("ns", cp, ctmp-cp) == 0) {
1014 } else if (strncmp("ps", cp, ctmp-cp) == 0) {
1017 } else if (strncmp("fs", cp, ctmp-cp) == 0) {
1021 VLerror(yylloc, "Invalid timescale precision units of measurement");
1025 pform_set_timescale(unit, prec, yylloc.text, yylloc.first_line);
1034 * The line directive matches lines of the form #line "foo" N and
1035 * calls this function. Here I parse out the file name and line
1036 * number, and change the yylloc to suite.
1038 static void line_directive()
1040 char*qt1 = strchr(yytext, '"');
1044 char*qt2 = strchr(qt1, '"');
1047 char*buf = new char[qt2-qt1+1];
1048 strncpy(buf, qt1, qt2-qt1);
1051 yylloc.text = set_file_name(buf);
1054 yylloc.first_line = strtoul(qt2,0,0);
1057 static void line_directive2()
1059 assert(strncmp(yytext,"`line",5) == 0);
1060 char*cp = yytext + strlen("`line");
1061 cp += strspn(cp, " ");
1062 yylloc.first_line = strtoul(cp,&cp,10);
1064 yylloc.first_line -= 1;
1066 cp += strspn(cp, " ");
1067 if (*cp == 0) return;
1069 char*qt1 = strchr(yytext, '"');
1073 char*qt2 = strchr(qt1, '"');
1076 char*buf = new char[qt2-qt1+1];
1077 strncpy(buf, qt1, qt2-qt1);
1080 yylloc.text = set_file_name(buf);
1083 extern FILE*vl_input;
1086 yyrestart(vl_input);
1087 yylloc.first_line = 1;
1089 /* Announce the first file name. */
1090 yylloc.text = set_file_name(strdupnew(vl_file.c_str()));