4 * Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
6 * This source code is free software; you can redistribute it
7 * and/or modify it in source code form under the terms of the GNU
8 * General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
38 # for timescales (regex subst patterns)
45 /* Recognize the various line directives. */
46 ^"#line"[ \t]+.+ { line_directive(); }
47 ^[ \t]?"`line"[ \t]+.+ { line_directive2(); }
50 \n { yylloc.first_line += 1; }
52 /* C++ style comments start with / / and run to the end of the
53 current line. These are very easy to handle. The meta-comments
54 format is a little more tricky to handle, but do what we can. */
56 /* The lexor detects "// synthesis translate_on/off" meta-comments,
57 we handle them here by turning on/off a flag. The pform uses
58 that flag to attach implicit attributes to "initial" and
59 "always" statements. */
61 "//"{W}*"synthesis"{W}+"translate_on"{W}*\n { pform_mc_translate_on(true); }
62 "//"{W}*"synthesis"{W}+"translate_off"{W}*\n { pform_mc_translate_on(false); }
63 "//" { comment_enter = YY_START; BEGIN(LCOMMENT); }
64 <LCOMMENT>. { yymore(); }
65 <LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
68 /* The contents of C-style comments are ignored, like white space. */
70 "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
72 <CCOMMENT>\n { yylloc.first_line += 1; }
73 <CCOMMENT>"*/" { BEGIN(comment_enter); }
76 states
= (#('module', 'exclusive'),
77 ('timescale', 'exclusive'),)
79 from parse_tokens
import tokens
80 tokens
+= ['timescale', 'LITERAL', 'IDENTIFIER', 'DEC_NUMBER', 'BASED_NUMBER',
85 t
.lexer
.lineno
+= t
.value
.count('\n')
87 t_ignore_cppcomment
= r
'//.*'
104 * Resolve the ambiguity between the += assignment
105 * operator and +=> polarity edge path operator
107 * +=> should be treated as two separate tokens '+' and
108 * '=>' (K_EG), therefore we only consume the first
109 * character of the matched pattern i.e. either + or -
110 * and push back the rest of the matches text (=>) in
128 t_K_NXOR
= r
"(\~\^|\^\~)"
133 t_K_CONTRIBUTE
= r
"<\+"
135 t_K_MINUS_EQ
= r
"\-="
142 t_K_LS_EQ
= r
"(<<=|<<<=)"
148 t_K_SCOPE_RES
= r
"::"
150 tokens
+= [ 'K_PSTAR', 'K_STARP', 'K_DOTSTAR', 'K_LS',
151 'K_RS', 'K_RSS', 'K_POW', 'K_LE', 'K_GE', 'K_EG', 'K_SG',
152 'K_EQ', 'K_NE', 'K_CEQ', 'K_CNE', 'K_WEQ', 'K_WNE',
153 'K_LOR', 'K_LAND', 'K_TAND', 'K_NOR', 'K_NXOR',
154 'K_NAND', 'K_TRIGGER', 'K_PO_POS', 'K_PO_NEG', 'K_CONTRIBUTE',
155 'K_PLUS_EQ', 'K_MINUS_EQ', 'K_MUL_EQ', 'K_DIV_EQ', 'K_MOD_EQ',
156 'K_AND_EQ', 'K_OR_EQ', 'K_XOR_EQ', 'K_LS_EQ', 'K_RS_EQ',
157 'K_RSS_EQ', 'K_INCR', 'K_DECR', 'K_LP',
161 lexor_keyword_code
= {
164 "absdelay" : 'K_absdelay',
165 "abstol" : 'K_abstol',
166 "accept_on" : 'K_accept_on',
167 "access" : 'K_access',
170 "ac_stim" : 'K_ac_stim',
172 "aliasparam" : 'K_aliasparam',
173 "always" : 'K_always',
174 "always_comb" : 'K_always_comb',
175 "always_ff" : 'K_always_ff',
176 "always_latch" : 'K_always_latch',
177 "analog" : 'K_analog',
178 "analysis" : 'K_analysis',
182 "assert" : 'K_assert',
183 "assign" : 'K_assign',
184 "assume" : 'K_assume',
188 "automatic" : 'K_automatic',
189 "before" : 'K_before',
193 "binsof" : 'K_binsof',
195 "branch" : 'K_branch',
199 "bufif0" : 'K_bufif0',
200 "bufif1" : 'K_bufif1',
207 "chandle" : 'K_chandle',
208 "checker" : 'K_checker',
210 "clocking" : 'K_clocking',
212 "config" : 'K_config',
213 "connect" : 'K_connect',
214 "connectmodule" : 'K_connectmodule',
215 "connectrules" : 'K_connectrules',
217 "constraint" : 'K_constraint',
218 "context" : 'K_context',
219 "continue" : 'K_continue',
220 "continuous" : 'K_continuous',
224 "covergroup" : 'K_covergroup',
225 "coverpoint" : 'K_coverpoint',
228 "ddt_nature" : 'K_ddt_nature',
230 "deassign" : 'K_deassign',
231 "default" : 'K_default',
232 "defparam" : 'K_defparam',
233 "design" : 'K_design',
234 "disable" : 'K_disable',
235 "discipline" : 'K_discipline',
236 "discrete" : 'K_discrete',
239 "domain" : 'K_domain',
240 "driver_update" : 'K_driver_update',
244 "endcase" : 'K_endcase',
245 "endchecker" : 'K_endchecker',
246 "endconfig" : 'K_endconfig',
247 "endclass" : 'K_endclass',
248 "endclocking" : 'K_endclocking',
249 "endconnectrules" : 'K_endconnectrules',
250 "enddiscipline" : 'K_enddiscipline',
251 "endfunction" : 'K_endfunction',
252 "endgenerate" : 'K_endgenerate',
253 "endgroup" : 'K_endgroup',
254 "endinterface" : 'K_endinterface',
255 "endmodule" : 'K_endmodule',
256 "endnature" : 'K_endnature',
257 "endpackage" : 'K_endpackage',
258 "endparamset" : 'K_endparamset',
259 "endprimitive" : 'K_endprimitive',
260 "endprogram" : 'K_endprogram',
261 "endproperty" : 'K_endproperty',
262 "endspecify" : 'K_endspecify',
263 "endsequence" : 'K_endsequence',
264 "endtable" : 'K_endtable',
265 "endtask" : 'K_endtask',
268 "eventually" : 'K_eventually',
269 "exclude" : 'K_exclude',
271 "expect" : 'K_expect',
272 "export" : 'K_export',
273 "extends" : 'K_extends',
274 "extern" : 'K_extern',
276 "final_step" : 'K_final_step',
277 "first_match" : 'K_first_match',
278 "flicker_noise" : 'K_flicker_noise',
282 "foreach" : 'K_foreach',
284 "forever" : 'K_forever',
286 "forkjoin" : 'K_forkjoin',
288 "function" : 'K_function',
289 "generate" : 'K_generate',
290 "genvar" : 'K_genvar',
291 "global" : 'K_global',
292 "ground" : 'K_ground',
293 "highz0" : 'K_highz0',
294 "highz1" : 'K_highz1',
297 "idtmod" : 'K_idtmod',
298 "idt_nature" : 'K_idt_nature',
301 "ifnone" : 'K_ifnone',
302 "ignore_bins" : 'K_ignore_bins',
303 "illegal_bins" : 'K_illegal_bins',
304 "implies" : 'K_implies',
305 "implements" : 'K_implements',
306 "import" : 'K_import',
307 "incdir" : 'K_incdir',
308 "include" : 'K_include',
310 "initial" : 'K_initial',
311 "initial_step" : 'K_initial_step',
314 "inside" : 'K_inside',
315 "instance" : 'K_instance',
317 "integer" : 'K_integer',
318 "interconnect" : 'K_interconnect',
319 "interface" : 'K_interface',
320 "intersect" : 'K_intersect',
322 "join_any" : 'K_join_any',
323 "join_none" : 'K_join_none',
324 "laplace_nd" : 'K_laplace_nd',
325 "laplace_np" : 'K_laplace_np',
326 "laplace_zd" : 'K_laplace_zd',
327 "laplace_zp" : 'K_laplace_zp',
329 "last_crossing" : 'K_last_crossing',
331 "liblist" : 'K_liblist',
332 "library" : 'K_library',
333 "limexp" : 'K_limexp',
336 "localparam" : 'K_localparam',
338 # This is defined by SystemVerilog 1800-2005 and as an Icarus extension.'
340 "longint" : 'K_longint',
341 "macromodule" : 'K_macromodule',
342 "matches" : 'K_matches',
344 "medium" : 'K_medium',
345 "merged" : 'K_merged',
347 "modport" : 'K_modport',
348 "module" : 'K_module',
350 "nature" : 'K_nature',
351 "negedge" : 'K_negedge',
352 "net_resolution" : 'K_net_resolution',
353 "nettype" : 'K_nettype',
355 "nexttime" : 'K_nexttime',
357 "noise_table" : 'K_noise_table',
359 "noshowcancelled" : 'K_noshowcancelled',
361 "notif0" : 'K_notif0',
362 "notif1" : 'K_notif1',
365 "output" : 'K_output',
366 "package" : 'K_package',
367 "packed" : 'K_packed',
368 "parameter" : 'K_parameter',
369 "paramset" : 'K_paramset',
371 "posedge" : 'K_posedge',
372 "potential" : 'K_potential',
374 "primitive" : 'K_primitive',
375 "priority" : 'K_priority',
376 "program" : 'K_program',
377 "property" : 'K_property',
378 "protected" : 'K_protected',
381 "pulldown" : 'K_pulldown',
382 "pullup" : 'K_pullup',
383 "pulsestyle_onevent" : 'K_pulsestyle_onevent',
384 "pulsestyle_ondetect" : 'K_pulsestyle_ondetect',
388 "randcase" : 'K_randcase',
389 "randsequence" : 'K_randsequence',
392 "realtime" : 'K_realtime',
395 "reject_on" : 'K_reject_on',
396 "release" : 'K_release',
397 "repeat" : 'K_repeat',
398 "resolveto" : 'K_resolveto',
399 "restrict" : 'K_restrict',
400 "return" : 'K_return',
404 "rtranif0" : 'K_rtranif0',
405 "rtranif1" : 'K_rtranif1',
406 "s_always" : 'K_s_always',
407 "s_eventually" : 'K_s_eventually',
408 "s_nexttime" : 'K_s_nexttime',
409 "s_until" : 'K_s_until',
410 "s_until_with" : 'K_s_until_with',
411 "scalared" : 'K_scalared',
412 "sequence" : 'K_sequence',
413 "shortint" : 'K_shortint',
414 "shortreal" : 'K_shortreal',
415 "showcancelled" : 'K_showcancelled',
416 "signed" : 'K_signed',
423 "specify" : 'K_specify',
424 "specparam" : 'K_specparam',
427 "static" : 'K_static',
428 # This is defined by both SystemVerilog 1800-2005 and Verilog-AMS 2.3',
429 "string" : 'K_string',
430 "strong" : 'K_strong',
431 "strong0" : 'K_strong0',
432 "strong1" : 'K_strong1',
433 "struct" : 'K_struct',
435 "supply0" : 'K_supply0',
436 "supply1" : 'K_supply1',
437 "sync_accept_on" : 'K_sync_accept_on',
438 "sync_reject_on" : 'K_sync_reject_on',
440 "tagged" : 'K_tagged',
445 "throughout" : 'K_throughout',
447 "timeprecision" : 'K_timeprecision',
449 "timeunit" : 'K_timeunit',
451 "tranif0" : 'K_tranif0',
452 "tranif1" : 'K_tranif1',
453 "transition" : 'K_transition',
457 "triand" : 'K_triand',
459 "trireg" : 'K_trireg',
461 "typedef" : 'K_typedef',
463 "unique" : 'K_unique',
464 "unique0" : 'K_unique',
466 # Reserved for future use!',
467 "unsigned" : 'K_unsigned',
469 "until_with" : 'K_until_with',
470 "untyped" : 'K_untyped',
474 "vectored" : 'K_vectored',
475 "virtual" : 'K_virtual',
478 "wait_order" : 'K_wait_order',
484 "white_noise" : 'K_white_noise',
485 "wildcard" : 'K_wildcard',
488 "within" : 'K_within',
489 # This is the name originally proposed for uwire and is deprecated!',
492 # This is defined by Verilog-AMS 2.3 and as an Icarus extension.',
502 literals
= [ '[', '}', '{', ';', ':', '[', ']', ',', '(', ')',
503 '#', '=', '.', '@', '&', '!', '?', '<', '>', '%',
504 '|', '^', '~', '+', '*', '/', '-']
507 /* Watch out for the tricky case of (*). Cannot parse this as "(*"
508 and ")", but since I know that this is really ( * ), replace it
509 with "*" and return that. */
510 "("{W}*"*"{W}*")" { return '*'; }
512 <EDGES>"]" { BEGIN(0); return yytext[0]; }
513 [}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
515 \" { BEGIN(CSTRING); }
516 <CSTRING>\\\\ { yymore(); /* Catch \\, which is a \ escaping itself */ }
517 <CSTRING>\\\" { yymore(); /* Catch \", which is an escaped quote */ }
518 <CSTRING>\n { BEGIN(0);
519 yylval.text = strdupnew(yytext);
520 VLerror(yylloc, "Missing close quote of string.");
521 yylloc.first_line += 1;
523 <CSTRING>\" { BEGIN(0);
524 yylval.text = strdupnew(yytext);
525 yylval.text[strlen(yytext)-1] = 0;
527 <CSTRING>. { yymore(); }
529 /* The UDP Table is a unique lexical environment. These are most
530 tokens that we can expect in a table. */
531 <UDPTABLE>\(\?0\) { return '_'; }
532 <UDPTABLE>\(\?1\) { return '+'; }
533 <UDPTABLE>\(\?[xX]\) { return '%'; }
534 <UDPTABLE>\(\?\?\) { return '*'; }
535 <UDPTABLE>\(01\) { return 'r'; }
536 <UDPTABLE>\(0[xX]\) { return 'Q'; }
537 <UDPTABLE>\(b[xX]\) { return 'q'; }
538 <UDPTABLE>\(b0\) { return 'f'; /* b0 is 10|00, but only 10 is meaningful */}
539 <UDPTABLE>\(b1\) { return 'r'; /* b1 is 11|01, but only 01 is meaningful */}
540 <UDPTABLE>\(0\?\) { return 'P'; }
541 <UDPTABLE>\(10\) { return 'f'; }
542 <UDPTABLE>\(1[xX]\) { return 'M'; }
543 <UDPTABLE>\(1\?\) { return 'N'; }
544 <UDPTABLE>\([xX]0\) { return 'F'; }
545 <UDPTABLE>\([xX]1\) { return 'R'; }
546 <UDPTABLE>\([xX]\?\) { return 'B'; }
547 <UDPTABLE>[bB] { return 'b'; }
548 <UDPTABLE>[lL] { return 'l'; /* IVL extension */ }
549 <UDPTABLE>[hH] { return 'h'; /* IVL extension */ }
550 <UDPTABLE>[fF] { return 'f'; }
551 <UDPTABLE>[rR] { return 'r'; }
552 <UDPTABLE>[xX] { return 'x'; }
553 <UDPTABLE>[nN] { return 'n'; }
554 <UDPTABLE>[pP] { return 'p'; }
555 <UDPTABLE>[01\?\*\-:;] { return yytext[0]; }
557 <EDGES>"01" { return K_edge_descriptor; }
558 <EDGES>"0x" { return K_edge_descriptor; }
559 <EDGES>"0z" { return K_edge_descriptor; }
560 <EDGES>"10" { return K_edge_descriptor; }
561 <EDGES>"1x" { return K_edge_descriptor; }
562 <EDGES>"1z" { return K_edge_descriptor; }
563 <EDGES>"x0" { return K_edge_descriptor; }
564 <EDGES>"x1" { return K_edge_descriptor; }
565 <EDGES>"z0" { return K_edge_descriptor; }
566 <EDGES>"z1" { return K_edge_descriptor; }
572 code = t.lexer.lexdata[t.modulestart:t.lexpos]
575 t.lexer.lineno += t.value.count('\n')
578 t_module_ignore = ' \t'
582 r
'[a-zA-Z_][a-zA-Z0-9$_]*'
584 print ("literal", word
)
585 keyword
= lexor_keyword_code
.get(t
.value
, 'IDENTIFIER')
586 #if keyword in ['K_module', 'K_macromodule']:
587 # t.lexer.modulestart = t.lexpos+len(t.value)
588 # t.lexer.begin('module')
589 if keyword
== 'IDENTIFIER':
590 t
.type = 'IDENTIFIER'
599 yylval.text = strdupnew(yytext);
600 if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
601 rc = PATHPULSE_IDENTIFIER;
625 /* Special case: If this is part of a scoped name, then check
626 the package for identifier details. For example, if the
627 source file is foo::bar, the parse.y will note the
628 PACKAGE_IDENTIFIER and "::" token and mark the
629 "in_package_scope" variable. Then this lexor will see the
630 identifier here and interpret it in the package scope. */
631 if (in_package_scope) {
632 if (rc == IDENTIFIER) {
633 if (data_type_t*type = pform_test_type_identifier(in_package_scope, yylval.text)) {
634 yylval.type_identifier.text = yylval.text;
635 yylval.type_identifier.type = type;
636 rc = TYPE_IDENTIFIER;
639 in_package_scope = 0;
643 /* If this identifier names a discipline, then return this as
644 a DISCIPLINE_IDENTIFIER and return the discipline as the
646 if (rc == IDENTIFIER && gn_verilog_ams_flag) {
647 perm_string tmp = lex_strings.make(yylval.text);
648 map<perm_string,ivl_discipline_t>::iterator cur = disciplines.find(tmp);
649 if (cur != disciplines.end()) {
651 yylval.discipline = (*cur).second;
652 rc = DISCIPLINE_IDENTIFIER;
656 /* If this identifier names a previously declared package, then
657 return this as a PACKAGE_IDENTIFIER instead. */
658 if (rc == IDENTIFIER && gn_system_verilog()) {
659 if (PPackage*pkg = pform_test_package_identifier(yylval.text)) {
661 yylval.package = pkg;
662 rc = PACKAGE_IDENTIFIER;
666 /* If this identifier names a previously declared type, then
667 return this as a TYPE_IDENTIFIER instead. */
668 if (rc == IDENTIFIER && gn_system_verilog()) {
669 if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
670 yylval.type_identifier.text = yylval.text;
671 yylval.type_identifier.type = type;
672 rc = TYPE_IDENTIFIER;
682 yylval.text = strdupnew(yytext+1);
683 if (gn_system_verilog()) {
684 if (PPackage*pkg = pform_test_package_identifier(yylval.text)) {
686 yylval.package = pkg;
687 return PACKAGE_IDENTIFIER;
690 if (gn_system_verilog()) {
691 if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
692 yylval.type_identifier.text = yylval.text;
693 yylval.type_identifier.type = type;
694 return TYPE_IDENTIFIER;
701 /* The 1364-1995 timing checks. */
702 if (strcmp(yytext,"$hold") == 0)
704 if (strcmp(yytext,"$nochange") == 0)
706 if (strcmp(yytext,"$period") == 0)
708 if (strcmp(yytext,"$recovery") == 0)
710 if (strcmp(yytext,"$setup") == 0)
712 if (strcmp(yytext,"$setuphold") == 0)
714 if (strcmp(yytext,"$skew") == 0)
716 if (strcmp(yytext,"$width") == 0)
718 /* The new 1364-2001 timing checks. */
719 if (strcmp(yytext,"$fullskew") == 0)
721 if (strcmp(yytext,"$recrem") == 0)
723 if (strcmp(yytext,"$removal") == 0)
725 if (strcmp(yytext,"$timeskew") == 0)
728 if (strcmp(yytext,"$attribute") == 0)
731 if (gn_system_verilog() && strcmp(yytext,"$unit") == 0) {
732 yylval.package = pform_units.back();
733 return PACKAGE_IDENTIFIER;
736 yylval.text = strdupnew(yytext);
737 return SYSTEM_IDENTIFIER; }
741 r
'\'[sS
]?
[dD
][ \t]*[0-9][0-9_]*'
742 t.type = 'BASED_NUMBER
'
743 #t.value = word # make_unsized_dec(yytext);
746 def t_undef_highz_dec(t):
747 r'\'[sS
]?
[dD
][ \t]*[xzXZ?
]_
*'
748 t.type = 'BASED_NUMBER
'
749 #t.value = word # make_undef_highz_dec(yytext);
752 def t_based_make_unsized_binary(t):
753 r'\'[sS
]?
[bB
][ \t]*[0-1xzXZ?
][0-1xzXZ?_
]*'
754 t.type = 'BASED_NUMBER
'
755 #t.value = word # make_unsized_binary(yytext);
758 def t_make_unsized_octal(t):
759 r'\'[sS
]?
[oO
][ \t]*[0-7xzXZ?
][0-7xzXZ?_
]*'
760 t.type = 'BASED_NUMBER
'
761 #t.value = word # make_unsized_octal(yytext);
764 def t_make_unsized_hex(t):
765 r'\'[sS
]?
[hH
][ \t]*[0-9a
-fA
-FxzXZ?
][0-9a
-fA
-FxzXZ?_
]*'
766 t.type = 'BASED_NUMBER
'
767 #t.value = word # make_unsized_hex(yytext);
770 def t_unbased_make_unsized_binary(t):
772 t.type = 'UNBASED_NUMBER
'
773 #t.value = word # make_unsized_binary(yytext);
777 /* Decimal numbers are the usual. But watch out for the UDPTABLE
778 mode, where there are no decimal numbers. Reject the match if we
779 are in the UDPTABLE state. */
782 if (YY_START==UDPTABLE) {
786 def t_make_unsized_dec(t):
788 t.type = 'DEC_NUMBER
'
789 #t.value = word # make_unsized_dec(yytext);
790 #based_size = yylval.number->as_ulong();
794 /* Notice and handle the `timescale directive. */
800 t.lexer.timestart = t.lexpos+len(t.value)
801 t.lexer.push_state('timescale
')
803 #t_timescale_ignore_toeol = r'.+\n'
804 t_timescale_ignore = ' \t'
805 #t_timescale_ignore_whitespace = r'\s
+'
808 def t_timescale_end(t):
810 code = t.lexer.lexdata[t.lexer.timestart:t.lexpos]
818 <PPTIMESCALE>.* { process_timescale(yytext); }
821 cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
822 "`timescale directive can not be inside a module "
823 "definition." << endl;
826 yylloc.first_line += 1;
832 /* This rule handles scaled time values for SystemVerilog. */
833 [0-9][0-9_]*(\.[0-9][0-9_]*)?{TU}?s {
834 if (gn_system_verilog()) {
835 yylval.text = strdupnew(yytext);
839 /* These rules handle the scaled real literals from Verilog-AMS. The
840 value is a number with a single letter scale factor. If
841 verilog-ams is not enabled, then reject this rule. If it is
842 enabled, then collect the scale and use it to scale the value. */
843 [0-9][0-9_]*\.[0-9][0-9_]*/{S} {
844 if (!gn_verilog_ams_flag) REJECT;
849 if (!gn_verilog_ams_flag) REJECT;
854 size_t token_len = strlen(yytext);
855 char*tmp = new char[token_len + 5];
858 switch (tmp[token_len-1]) {
859 case 'a
': scale = -18; break; /* atto- */
860 case 'f
': scale = -15; break; /* femto- */
861 case 'p
': scale = -12; break; /* pico- */
862 case 'n
': scale = -9; break; /* nano- */
863 case 'u
': scale = -6; break; /* micro- */
864 case 'm
': scale = -3; break; /* milli- */
865 case 'k
': scale = 3; break; /* kilo- */
866 case 'K
': scale = 3; break; /* kilo- */
867 case 'M
': scale = 6; break; /* mega- */
868 case 'G
': scale = 9; break; /* giga- */
869 case 'T
': scale = 12; break; /* tera- */
870 default: assert(0); break;
872 snprintf(tmp+token_len-1, 5, "e%d", scale);
873 yylval.realtime = new verireal(tmp);
879 [0-9][0-9_]*\.[0-9][0-9_]*([Ee][+-]?[0-9][0-9_]*)? {
880 yylval.realtime = new verireal(yytext);
883 [0-9][0-9_]*[Ee][+-]?[0-9][0-9_]* {
884 yylval.realtime = new verireal(yytext);
888 /* Notice and handle the `celldefine and `endcelldefine directives. */
890 ^{W}?`celldefine{W}? { in_celldefine = true; }
891 ^{W}?`endcelldefine{W}? { in_celldefine = false; }
893 /* Notice and handle the resetall directive. */
897 cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
898 "`resetall directive can not be inside a module "
899 "definition." << endl;
902 cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
903 "`resetall directive can not be inside a UDP "
904 "definition." << endl;
910 /* Notice and handle the `unconnected_drive directive. */
911 ^{W}?`unconnected_drive { BEGIN(PPUCDRIVE); }
912 <PPUCDRIVE>.* { process_ucdrive(yytext); }
915 cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
916 "`unconnected_drive directive can not be inside a "
917 "module definition." << endl;
920 yylloc.first_line += 1;
923 ^{W}?`nounconnected_drive{W}? {
925 cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
926 "`nounconnected_drive directive can not be inside a "
927 "module definition." << endl;
930 uc_drive = UCD_NONE; }
932 /* These are directives that I do not yet support. I think that IVL
933 should handle these, not an external preprocessor. */
934 /* From 1364-2005 Chapter 19. */
935 ^{W}?`pragme{W}?.* { }
937 /* From 1364-2005 Annex D. */
938 ^{W}?`default_decay_time{W}?.* { }
939 ^{W}?`default_trireg_strength{W}?.* { }
940 ^{W}?`delay_mode_distributed{W}?.* { }
941 ^{W}?`delay_mode_path{W}?.* { }
942 ^{W}?`delay_mode_unit{W}?.* { }
943 ^{W}?`delay_mode_zero{W}?.* { }
945 /* From other places. */
946 ^{W}?`disable_portfaults{W}?.* { }
947 ^{W}?`enable_portfaults{W}?.* { }
949 ^{W}?`nosuppress_faults{W}?.* { }
951 ^{W}?`suppress_faults{W}?.* { }
952 ^{W}?`uselib{W}?.* { }
954 ^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); }
956 <PPBEGIN_KEYWORDS>\"[a-zA-Z0-9 -\.]*\".* {
957 keyword_mask_stack.push_front(lexor_keyword_mask);
959 char*word = yytext+1;
960 char*tail = strchr(word, '"');
962 if (strcmp(word,"1364-1995") == 0) {
963 lexor_keyword_mask = GN_KEYWORDS_1364_1995;
964 } else if (strcmp(word,"1364-2001") == 0) {
965 lexor_keyword_mask = GN_KEYWORDS_1364_1995
966 |GN_KEYWORDS_1364_2001
967 |GN_KEYWORDS_1364_2001_CONFIG;
968 } else if (strcmp(word,"1364-2001-noconfig
") == 0) {
969 lexor_keyword_mask = GN_KEYWORDS_1364_1995
970 |GN_KEYWORDS_1364_2001;
971 } else if (strcmp(word,"1364-2005") == 0) {
972 lexor_keyword_mask = GN_KEYWORDS_1364_1995
973 |GN_KEYWORDS_1364_2001
974 |GN_KEYWORDS_1364_2001_CONFIG
975 |GN_KEYWORDS_1364_2005;
976 } else if (strcmp(word,"1800-2005") == 0) {
977 lexor_keyword_mask = GN_KEYWORDS_1364_1995
978 |GN_KEYWORDS_1364_2001
979 |GN_KEYWORDS_1364_2001_CONFIG
980 |GN_KEYWORDS_1364_2005
981 |GN_KEYWORDS_1800_2005;
982 } else if (strcmp(word,"1800-2009") == 0) {
983 lexor_keyword_mask = GN_KEYWORDS_1364_1995
984 |GN_KEYWORDS_1364_2001
985 |GN_KEYWORDS_1364_2001_CONFIG
986 |GN_KEYWORDS_1364_2005
987 |GN_KEYWORDS_1800_2005
988 |GN_KEYWORDS_1800_2009;
989 } else if (strcmp(word,"1800-2012") == 0) {
990 lexor_keyword_mask = GN_KEYWORDS_1364_1995
991 |GN_KEYWORDS_1364_2001
992 |GN_KEYWORDS_1364_2001_CONFIG
993 |GN_KEYWORDS_1364_2005
994 |GN_KEYWORDS_1800_2005
995 |GN_KEYWORDS_1800_2009
996 |GN_KEYWORDS_1800_2012;
997 } else if (strcmp(word,"VAMS
-2.3") == 0) {
998 lexor_keyword_mask = GN_KEYWORDS_1364_1995
999 |GN_KEYWORDS_1364_2001
1000 |GN_KEYWORDS_1364_2001_CONFIG
1001 |GN_KEYWORDS_1364_2005
1002 |GN_KEYWORDS_VAMS_2_3;
1004 fprintf(stderr, "%s:%d: Ignoring unknown keywords string
: %s\n",
1005 yylloc.text, yylloc.first_line, word);
1010 <PPBEGIN_KEYWORDS>.* {
1011 fprintf(stderr, "%s:%d: Malformed keywords specification
: %s\n",
1012 yylloc.text, yylloc.first_line, yytext);
1016 ^{W}?`end_keywords{W}?.* {
1017 if (!keyword_mask_stack.empty()) {
1018 lexor_keyword_mask = keyword_mask_stack.front();
1019 keyword_mask_stack.pop_front();
1021 fprintf(stderr, "%s:%d: Mismatched end_keywords directive
\n",
1022 yylloc.text, yylloc.first_line);
1026 /* Notice and handle the default_nettype directive. The lexor
1027 detects the default_nettype keyword, and the second part of the
1028 rule collects the rest of the line and processes it. We only need
1029 to look for the first work, and interpret it. */
1031 `default_nettype{W}? { BEGIN(PPDEFAULT_NETTYPE); }
1032 <PPDEFAULT_NETTYPE>.* {
1033 NetNet::Type net_type;
1034 size_t wordlen = strcspn(yytext, " \t\f\r\n");
1035 yytext[wordlen] = 0;
1036 /* Add support for other wire types and better error detection. */
1037 if (strcmp(yytext,"wire
") == 0) {
1038 net_type = NetNet::WIRE;
1040 } else if (strcmp(yytext,"tri
") == 0) {
1041 net_type = NetNet::TRI;
1043 } else if (strcmp(yytext,"tri0
") == 0) {
1044 net_type = NetNet::TRI0;
1046 } else if (strcmp(yytext,"tri1
") == 0) {
1047 net_type = NetNet::TRI1;
1049 } else if (strcmp(yytext,"wand
") == 0) {
1050 net_type = NetNet::WAND;
1052 } else if (strcmp(yytext,"triand
") == 0) {
1053 net_type = NetNet::TRIAND;
1055 } else if (strcmp(yytext,"wor
") == 0) {
1056 net_type = NetNet::WOR;
1058 } else if (strcmp(yytext,"trior
") == 0) {
1059 net_type = NetNet::TRIOR;
1061 } else if (strcmp(yytext,"none
") == 0) {
1062 net_type = NetNet::NONE;
1065 cerr << yylloc.text << ":" << yylloc.first_line
1066 << ": error
: Net
type " << yytext
1067 << " is not a
valid (or supported
)"
1068 << " default net
type." << endl;
1069 net_type = NetNet::WIRE;
1072 pform_set_default_nettype(net_type, yylloc.text, yylloc.first_line);
1074 <PPDEFAULT_NETTYPE>\n {
1075 yylloc.first_line += 1;
1079 /* These are directives that are not supported by me and should have
1080 been handled by an external preprocessor such as ivlpp. */
1082 ^{W}?`define{W}?.* {
1083 cerr << yylloc.text << ":" << yylloc.first_line <<
1084 ": warning
: `define
not supported
. Use an external preprocessor
."
1089 cerr << yylloc.text << ":" << yylloc.first_line <<
1090 ": warning
: `
else not supported
. Use an external preprocessor
."
1095 cerr << yylloc.text << ":" << yylloc.first_line <<
1096 ": warning
: `elsif
not supported
. Use an external preprocessor
."
1101 cerr << yylloc.text << ":" << yylloc.first_line <<
1102 ": warning
: `endif
not supported
. Use an external preprocessor
."
1107 cerr << yylloc.text << ":" << yylloc.first_line <<
1108 ": warning
: `ifdef
not supported
. Use an external preprocessor
."
1112 ^{W}?`ifndef{W}?.* {
1113 cerr << yylloc.text << ":" << yylloc.first_line <<
1114 ": warning
: `ifndef
not supported
. Use an external preprocessor
."
1119 cerr << yylloc.text << ":" << yylloc.first_line <<
1120 ": warning
: `include
not supported
. Use an external preprocessor
."
1125 cerr << yylloc.text << ":" << yylloc.first_line <<
1126 ": warning
: `undef
not supported
. Use an external preprocessor
."
1131 `{W} { cerr << yylloc.text << ":" << yylloc.first_line << ": error
: "
1132 << "Stray
tic (`
) here
. Perhaps you put white space
" << endl;
1133 cerr << yylloc.text << ":" << yylloc.first_line << ": : "
1134 << "between the tic
and preprocessor directive?
"
1138 . { return yytext[0]; }
1140 /* Final catchall. something got lost or mishandled. */
1141 /* XXX Should we tell the user something about the lexical state? */
1143 <*>.|\n { cerr << yylloc.text << ":" << yylloc.first_line
1144 << ": error
: unmatched
character (";
1145 if (isprint(yytext[0]))
1148 cerr << "hex " << hex << ((unsigned char) yytext[0]);
1150 cerr << ")" << endl;
1156 * The UDP state table needs some slightly different treatment by the
1157 * lexor. The level characters are normally accepted as other things,
1158 * so the parser needs to switch my mode when it believes in needs to.
1160 void lex_end_table()
1165 static unsigned truncate_to_integer_width(verinum::V*bits, unsigned size)
1167 if (size <= integer_width) return size;
1169 verinum::V pad = bits[size-1];
1170 if (pad == verinum::V1) pad = verinum::V0;
1172 for (unsigned idx = integer_width; idx < size; idx += 1) {
1173 if (bits[idx] != pad) {
1174 yywarn(yylloc, "Unsized numeric constant truncated to integer width
.");
1178 return integer_width;
1181 verinum*make_unsized_binary(const char*txt)
1183 bool sign_flag = false;
1184 bool single_flag = false;
1185 const char*ptr = txt;
1186 assert(*ptr == '\'');
1189 if (tolower(*ptr) == 's') {
1194 assert((tolower(*ptr) == 'b') || gn_system_verilog());
1195 if (tolower(*ptr) == 'b') {
1198 assert(sign_flag == false);
1202 while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1206 for (const char*idx = ptr ; *idx ; idx += 1)
1207 if (*idx != '_') size += 1;
1210 VLerror(yylloc, "Numeric literal has no digits
in it
.");
1211 verinum*out = new verinum();
1212 out->has_sign(sign_flag);
1213 out->is_single(single_flag);
1217 if ((based_size > 0) && (size > based_size)) yywarn(yylloc,
1218 "extra digits given
for sized binary constant
.");
1220 verinum::V*bits = new verinum::V[size];
1222 unsigned idx = size;
1226 bits[--idx] = verinum::V0;
1229 bits[--idx] = verinum::V1;
1231 case 'z': case 'Z': case '?':
1232 bits[--idx] = verinum::Vz;
1235 bits[--idx] = verinum::Vx;
1240 fprintf(stderr, "%c\n", ptr[0]);
1246 if (gn_strict_expr_width_flag && (based_size == 0))
1247 size = truncate_to_integer_width(bits, size);
1249 verinum*out = new verinum(bits, size, false);
1250 out->has_sign(sign_flag);
1251 out->is_single(single_flag);
1257 verinum*make_unsized_octal(const char*txt)
1259 bool sign_flag = false;
1260 const char*ptr = txt;
1261 assert(*ptr == '\'');
1264 if (tolower(*ptr) == 's') {
1269 assert(tolower(*ptr) == 'o');
1272 while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1276 for (const char*idx = ptr ; *idx ; idx += 1)
1277 if (*idx != '_') size += 3;
1279 if (based_size > 0) {
1280 int rem = based_size % 3;
1281 if (rem != 0) based_size += 3 - rem;
1282 if (size > based_size) yywarn(yylloc,
1283 "extra digits given
for sized octal constant
.");
1286 verinum::V*bits = new verinum::V[size];
1288 unsigned idx = size;
1292 case '0': case '1': case '2': case '3':
1293 case '4': case '5': case '6': case '7':
1295 bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
1296 bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
1297 bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
1300 bits[--idx] = verinum::Vx;
1301 bits[--idx] = verinum::Vx;
1302 bits[--idx] = verinum::Vx;
1304 case 'z': case 'Z': case '?':
1305 bits[--idx] = verinum::Vz;
1306 bits[--idx] = verinum::Vz;
1307 bits[--idx] = verinum::Vz;
1317 if (gn_strict_expr_width_flag && (based_size == 0))
1318 size = truncate_to_integer_width(bits, size);
1320 verinum*out = new verinum(bits, size, false);
1321 out->has_sign(sign_flag);
1327 verinum*make_unsized_hex(const char*txt)
1329 bool sign_flag = false;
1330 const char*ptr = txt;
1331 assert(*ptr == '\'');
1334 if (tolower(*ptr) == 's') {
1338 assert(tolower(*ptr) == 'h');
1341 while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1345 for (const char*idx = ptr ; *idx ; idx += 1)
1346 if (*idx != '_') size += 4;
1348 if (based_size > 0) {
1349 int rem = based_size % 4;
1350 if (rem != 0) based_size += 4 - rem;
1351 if (size > based_size) yywarn(yylloc,
1352 "extra digits given
for sized
hex constant
.");
1355 verinum::V*bits = new verinum::V[size];
1357 unsigned idx = size;
1361 case '0': case '1': case '2': case '3': case '4':
1362 case '5': case '6': case '7': case '8': case '9':
1364 bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
1365 bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
1366 bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
1367 bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
1369 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1370 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1371 val = tolower(*ptr) - 'a' + 10;
1372 bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
1373 bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
1374 bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
1375 bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
1378 bits[--idx] = verinum::Vx;
1379 bits[--idx] = verinum::Vx;
1380 bits[--idx] = verinum::Vx;
1381 bits[--idx] = verinum::Vx;
1383 case 'z': case 'Z': case '?':
1384 bits[--idx] = verinum::Vz;
1385 bits[--idx] = verinum::Vz;
1386 bits[--idx] = verinum::Vz;
1387 bits[--idx] = verinum::Vz;
1397 if (gn_strict_expr_width_flag && (based_size == 0))
1398 size = truncate_to_integer_width(bits, size);
1400 verinum*out = new verinum(bits, size, false);
1401 out->has_sign(sign_flag);
1407 /* Divide the integer given by the string by 2. Return the remainder bit. */
1408 static int dec_buf_div2(char *buf)
1411 int len = strlen(buf);
1418 /* dst_ptr overwrites buf, but all characters that are overwritten
1419 were already used by the reader. */
1422 while(buf[pos] == '0')
1425 for(; pos<len; ++pos){
1429 assert(isdigit(buf[pos]));
1431 partial= partial*10 + (buf[pos]-'0');
1434 *dst_ptr = partial/2 + '0';
1435 partial = partial & 1;
1445 // If result of division was zero string, it should remain that way.
1446 // Don't eat the last zero...
1447 if (dst_ptr == buf){
1456 /* Support a single x, z or ? as a decimal constant (from 1364-2005). */
1457 verinum* make_undef_highz_dec(const char* ptr)
1459 bool signed_flag = false;
1461 assert(*ptr == '\'');
1462 /* The number may have decorations of the form 'sd<code>,
1463 possibly with space between the d and the <code>.
1464 Also, the 's' is optional, and marks the number as signed. */
1467 if (tolower(*ptr) == 's') {
1472 assert(tolower(*ptr) == 'd');
1475 while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1478 /* Process the code. */
1479 verinum::V* bits = new verinum::V[1];
1483 bits[0] = verinum::Vx;
1488 bits[0] = verinum::Vz;
1494 while (*ptr == '_') ptr += 1;
1497 verinum*out = new verinum(bits, 1, false);
1498 out->has_sign(signed_flag);
1504 * Making a decimal number is much easier than the other base numbers
1505 * because there are no z or x values to worry about. It is much
1506 * harder than other base numbers because the width needed in bits is
1507 * hard to calculate.
1510 verinum*make_unsized_dec(const char*ptr)
1513 bool signed_flag = false;
1516 if (ptr[0] == '\'') {
1517 /* The number has decorations of the form 'sd<digits>,
1518 possibly with space between the d and the <digits>.
1519 Also, the 's' is optional, and marks the number as
1523 if (tolower(*ptr) == 's') {
1528 assert(tolower(*ptr) == 'd');
1531 while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1535 /* ... or an undecorated decimal number is passed
1536 it. These numbers are treated as signed decimal. */
1537 assert(isdigit(*ptr));
1542 /* Copy the digits into a buffer that I can use to do in-place
1545 while ((idx < sizeof buf) && (*ptr != 0)) {
1551 buf[idx++] = *ptr++;
1554 if (idx == sizeof buf) {
1555 fprintf(stderr, "Ridiculously
long"
1556 " decimal constant will be truncated
!\n");
1561 unsigned tmp_size = idx * 4 + 1;
1562 verinum::V *bits = new verinum::V[tmp_size];
1565 while (idx < tmp_size) {
1566 int rem = dec_buf_div2(buf);
1567 bits[idx++] = (rem == 1) ? verinum::V1 : verinum::V0;
1570 assert(strcmp(buf, "0") == 0);
1572 /* Now calculate the minimum number of bits needed to
1573 represent this unsigned number. */
1574 unsigned size = tmp_size;
1575 while ((size > 1) && (bits[size-1] == verinum::V0))
1578 /* Now account for the signedness. Don't leave a 1 in the high
1579 bit if this is a signed number. */
1580 if (signed_flag && (bits[size-1] == verinum::V1)) {
1582 assert(size <= tmp_size);
1585 /* Since we never have the real number of bits that a decimal
1586 number represents we do not check for extra bits. */
1587 // if (based_size > 0) { }
1589 if (gn_strict_expr_width_flag && (based_size == 0))
1590 size = truncate_to_integer_width(bits, size);
1592 verinum*res = new verinum(bits, size, false);
1593 res->has_sign(signed_flag);
1600 * Convert the string to a time unit or precision.
1601 * Returns true on failure.
1603 static bool get_timescale_const(const char *&cp, int &res, bool is_unit)
1605 /* Check for the 1 digit. */
1608 VLerror(yylloc, "Invalid `timescale unit constant
"
1611 VLerror(yylloc, "Invalid `timescale precision constant
"
1618 /* Check the number of zeros after the 1. */
1619 res = strspn(cp, "0");
1622 VLerror(yylloc, "Invalid `timescale unit constant
"
1623 "(number of zeros
)");
1625 VLerror(yylloc, "Invalid `timescale precision constant
"
1626 "(number of zeros
)");
1632 /* Skip any space between the digits and the scaling string. */
1633 cp += strspn(cp, " \t");
1635 /* Now process the scaling string. */
1636 if (strncmp("s
", cp, 1) == 0) {
1641 } else if (strncmp("ms
", cp, 2) == 0) {
1646 } else if (strncmp("us
", cp, 2) == 0) {
1651 } else if (strncmp("ns
", cp, 2) == 0) {
1656 } else if (strncmp("ps
", cp, 2) == 0) {
1661 } else if (strncmp("fs
", cp, 2) == 0) {
1669 VLerror(yylloc, "Invalid `timescale unit scale
");
1671 VLerror(yylloc, "Invalid `timescale precision scale
");
1678 * process either a pull0 or a pull1.
1680 static void process_ucdrive(const char*txt)
1682 UCDriveType ucd = UCD_NONE;
1683 const char*cp = txt + strspn(txt, " \t");
1685 /* Skip the space after the `unconnected_drive directive. */
1687 VLerror(yylloc, "Space required after `unconnected_drive
"
1692 /* Check for the pull keyword. */
1693 if (strncmp("pull
", cp, 4) != 0) {
1694 VLerror(yylloc, "pull required
for `unconnected_drive
"
1699 if (*cp == '0') ucd = UCD_PULL0;
1700 else if (*cp == '1') ucd = UCD_PULL1;
1702 cerr << yylloc.text << ":" << yylloc.first_line << ": error
: "
1703 "`unconnected_drive does
not support
'pull" << *cp
1710 /* Verify that only space and/or a single line comment is left. */
1711 cp += strspn(cp, " \t");
1712 if (strncmp(cp, "//", 2) != 0 &&
1713 (size_t)(cp-yytext) != strlen(yytext)) {
1714 VLerror(yylloc, "Invalid `unconnected_drive
directive (extra
"
1715 "garbage after precision
).");
1723 * The timescale parameter has the form:
1724 * " <num
> xs
/ <num
> xs
"
1726 static void process_timescale(const char*txt)
1728 const char*cp = txt + strspn(txt, " \t");
1730 /* Skip the space after the `timescale directive. */
1732 VLerror(yylloc, "Space required after `timescale directive
.");
1739 /* Get the time units. */
1740 if (get_timescale_const(cp, unit, true)) return;
1742 /* Skip any space after the time units, the '/' and any
1743 * space after the '/'. */
1744 cp += strspn(cp, " \t");
1746 VLerror(yylloc, "`timescale separator
'/' appears to be missing
.");
1750 cp += strspn(cp, " \t");
1752 /* Get the time precision. */
1753 if (get_timescale_const(cp, prec, false)) return;
1755 /* Verify that only space and/or a single line comment is left. */
1756 cp += strspn(cp, " \t");
1757 if (strncmp(cp, "//", 2) != 0 &&
1758 (size_t)(cp-yytext) != strlen(yytext)) {
1759 VLerror(yylloc, "Invalid `timescale
directive (extra garbage
"
1760 "after precision
).");
1764 /* The time unit must be greater than or equal to the precision. */
1766 VLerror(yylloc, "error
: `timescale unit must
not be less than
"
1771 pform_set_timescale(unit, prec, yylloc.text, yylloc.first_line);
1780 * The line directive matches lines of the form #line "foo
" N and
1781 * calls this function. Here I parse out the file name and line
1782 * number, and change the yylloc to suite.
1784 static void line_directive()
1787 /* Skip any leading space. */
1788 char *cp = strchr(yytext, '#');
1789 /* Skip the #line directive. */
1790 assert(strncmp(cp, "#line", 5) == 0);
1792 /* Skip the space after the
#line directive. */
1793 cp
+= strspn(cp
, " \t");
1795 /* Find the starting
" and skip it. */
1796 char*fn_start = strchr(cp, '"');
1797 if (cp != fn_start) {
1798 VLerror(yylloc, "Invalid #line directive (file name start).");
1803 /* Find the last ". */
1804 char*fn_end = strrchr(fn_start, '"');
1806 VLerror(yylloc, "Invalid
#line directive (file name end).");
1810 /* Copy the
file name
and assign it to yylloc
. */
1811 char
*buf
= new char
[fn_end
-fn_start
+1];
1812 strncpy(buf
, fn_start
, fn_end
-fn_start
);
1813 buf
[fn_end
-fn_start
] = 0;
1815 /* Skip the space after the
file name
. */
1819 cpr
+= strspn(cp
, " \t");
1821 VLerror(yylloc
, "Invalid #line directive (missing space after "
1828 /* Get the line number
and verify that it
is correct
. */
1829 unsigned
long lineno
= strtoul(cp
, &cpr
, 10);
1831 VLerror(yylloc
, "Invalid line number for #line directive.");
1837 /* Verify that only space
is left
. */
1838 cpr
+= strspn(cp
, " \t");
1839 if ((size_t
)(cpr
-yytext
) != strlen(yytext
)) {
1840 VLerror(yylloc
, "Invalid #line directive (extra garbage after "
1846 /* Now we can assign the new values to yyloc
. */
1847 yylloc
.text
= set_file_name(buf
);
1848 yylloc
.first_line
= lineno
;
1852 * The line directive matches lines of the form `line N
"foo" M
and
1853 * calls this function
. Here I parse out the
file name
and line
1854 * number
, and change the yylloc to suite
. M
is ignored
.
1856 static void
line_directive2()
1859 /* Skip any leading space
. */
1860 char
*cp
= strchr(yytext
, '`');
1861 /* Skip the `line directive
. */
1862 assert(strncmp(cp
, "`line", 5) == 0);
1865 /* strtoul skips leading space
. */
1866 unsigned
long lineno
= strtoul(cp
, &cpr
, 10);
1868 VLerror(yylloc
, "Invalid line number for `line directive.");
1874 /* Skip the space between the line number
and the
file name
. */
1875 cpr
+= strspn(cp
, " \t");
1877 VLerror(yylloc
, "Invalid `line directive (missing space after "
1883 /* Find the starting
" and skip it. */
1884 char*fn_start = strchr(cp, '"');
1885 if (cp != fn_start) {
1886 VLerror(yylloc, "Invalid `line directive (file name start).");
1891 /* Find the last ". */
1892 char*fn_end = strrchr(fn_start, '"');
1894 VLerror(yylloc, "Invalid `line
directive (file name end
).");
1898 /* Skip the space after the file name. */
1901 cpr += strspn(cp, " \t");
1903 VLerror(yylloc, "Invalid `line
directive (missing space after
"
1909 /* Check that the level is correct, we do not need the level. */
1910 if (strspn(cp, "012") != 1) {
1911 VLerror(yylloc, "Invalid level
for `line directive
.");
1916 /* Verify that only space and/or a single line comment is left. */
1917 cp += strspn(cp, " \t");
1918 if (strncmp(cp, "//", 2) != 0 &&
1919 (size_t)(cp-yytext) != strlen(yytext)) {
1920 VLerror(yylloc, "Invalid `line
directive (extra garbage after
"
1925 /* Copy the file name and assign it and the line number to yylloc. */
1926 char*buf = new char[fn_end-fn_start+1];
1927 strncpy(buf, fn_start, fn_end-fn_start);
1928 buf[fn_end-fn_start] = 0;
1930 yylloc.text = set_file_name(buf);
1931 yylloc.first_line = lineno;
1935 * Reset all compiler directives. This will be called when a `resetall
1936 * directive is encountered or when a new compilation unit is started.
1938 static void reset_all()
1940 pform_set_default_nettype(NetNet::WIRE, yylloc.text, yylloc.first_line);
1941 in_celldefine = false;
1942 uc_drive = UCD_NONE;
1943 pform_set_timescale(def_ts_units, def_ts_prec, 0, 0);
1946 extern FILE*vl_input;
1949 yyrestart(vl_input);
1950 yylloc.first_line = 1;
1952 /* Announce the first file name. */
1953 yylloc.text = set_file_name(strdupnew(vl_file.c_str()));
1955 if (separate_compilation) {
1957 if (!keyword_mask_stack.empty()) {
1958 lexor_keyword_mask = keyword_mask_stack.back();
1959 keyword_mask_stack.clear();
1965 * Modern version of flex (>=2.5.9) can clean up the scanner data.
1967 void destroy_lexor()
1969 # ifdef FLEX_SCANNER
1970 # if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
1971 # if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
1979 def t_timescale_error(t):
1980 print("%d: Timescale error
'%s'" % (t.lexer.lineno, t.value[0]))
1985 def t_module_error(t):
1986 print("%d: Module error
'%s'" % (t.lexer.lineno, t.value[0]))
1992 print("%d: Illegal character
'%s'" % (t.lexer.lineno, t.value[0]))
1996 tokens = list(set(tokens))
2000 if __name__ == '__main__':