first commit
[sv2nmigen.git] / lexor.py
1 """
2 %{
3 /*
4  * Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com)
5  *
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)
10  *    any later version.
11  *
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.
16  *
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.
20  */
21 """
22
23 from ply import lex
24
25 """
26 %x CCOMMENT
27 %x PCOMMENT
28 %x LCOMMENT
29 %x CSTRING
30 %s UDPTABLE
31 %x PPTIMESCALE
32 %x PPUCDRIVE
33 %x PPDEFAULT_NETTYPE
34 %x PPBEGIN_KEYWORDS
35 %s EDGES
36 %x REAL_SCALE
37
38 # for timescales (regex subst patterns)
39 W = r'[ \t\b\f\r]+'
40 S = r'[afpnumkKMGT]'
41 TU r'[munpf]'
42
43 %%
44
45   /* Recognize the various line directives. */
46 ^"#line"[ \t]+.+ { line_directive(); }
47 ^[ \t]?"`line"[ \t]+.+ { line_directive2(); }
48
49 [ \t\b\f\r] { ; }
50 \n { yylloc.first_line += 1; }
51
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. */
55
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. */
60
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); }
66
67
68   /* The contents of C-style comments are ignored, like white space. */
69
70 "/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
71 <CCOMMENT>.    { ; }
72 <CCOMMENT>\n   { yylloc.first_line += 1; }
73 <CCOMMENT>"*/" { BEGIN(comment_enter); }
74 """
75
76 states = (#('module', 'exclusive'),
77           ('timescale', 'exclusive'),)
78
79 from parse_tokens import tokens
80 tokens += ['timescale', 'LITERAL', 'IDENTIFIER', 'DEC_NUMBER', 'BASED_NUMBER',
81            'UNBASED_NUMBER']
82
83 def t_ccomment(t):
84     r'/\*(.|\n)*?\*/'
85     t.lexer.lineno += t.value.count('\n')
86
87 t_ignore_cppcomment = r'//.*'
88
89 t_ignore = ' \t\n'
90
91 t_K_PSTAR = r"\(\*"
92 t_K_STARP = r"\*\)"
93 t_K_DOTSTAR = r"\.\*"
94 t_K_LS = r"(<<|<<<)"
95 t_K_RS = r">>" 
96 t_K_RSS = r">>>"
97 t_K_POW = r"\*\*"
98 t_K_LE = r"<="
99 t_K_GE = r">="
100 t_K_EG = r"=>"
101 """
102 "+=>"|"-=>"     {
103                         /*
104                          * Resolve the ambiguity between the += assignment
105                          * operator and +=> polarity edge path operator
106                          *
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
111                          * the input stream.
112                          */
113                         yyless(1);
114                         return yytext[0];
115                 }
116 """
117 t_K_SG = r"\*>"
118 t_K_EQ = r"=="
119 t_K_NE = r"!="
120 t_K_CEQ = r"==="
121 t_K_CNE = r"!=="
122 t_K_WEQ = r"==\?"
123 t_K_WNE = r"!=\?"
124 t_K_LOR = r"\|\|"
125 t_K_LAND = r"\&\&"
126 t_K_TAND = r"\&\&\&"
127 t_K_NOR = r"\~\|"
128 t_K_NXOR = r"(\~\^|\^\~)"
129 t_K_NAND = r"\~\&"
130 t_K_TRIGGER = r"\->"
131 t_K_PO_POS = r"\+:"
132 t_K_PO_NEG = r"\-:"
133 t_K_CONTRIBUTE = r"<\+"
134 t_K_PLUS_EQ = r"\+="
135 t_K_MINUS_EQ = r"\-="
136 t_K_MUL_EQ = r"\*="
137 t_K_DIV_EQ = r"\/="
138 t_K_MOD_EQ = r"\%="
139 t_K_AND_EQ = r"\&="
140 t_K_OR_EQ = r"\|="
141 t_K_XOR_EQ = r"\^="
142 t_K_LS_EQ = r"(<<=|<<<=)"
143 t_K_RS_EQ = r">>="
144 t_K_RSS_EQ = r">>>="
145 t_K_INCR = r"\+\+"
146 t_K_DECR = r"\\--"
147 t_K_LP = r"\'\{"
148 t_K_SCOPE_RES = r"::"
149
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',
158     'K_SCOPE_RES'
159         ]
160
161 lexor_keyword_code = {
162     "above"                                     : 'K_above',
163     "abs"                                       : 'K_abs',
164     "absdelay"                          : 'K_absdelay',
165     "abstol"                                    : 'K_abstol',
166     "accept_on"                         : 'K_accept_on',
167     "access"                                    : 'K_access',
168     "acos"                                      : 'K_acos',
169     "acosh"                                     : 'K_acosh',
170     "ac_stim"                           : 'K_ac_stim',
171     "alias"                                     : 'K_alias',
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',
179     "and"                                       : 'K_and',
180     "asin"                                      : 'K_asin',
181     "asinh"                                     : 'K_asinh',
182     "assert"            : 'K_assert',
183     "assign"                                    : 'K_assign',
184     "assume"                                    : 'K_assume',
185     "atan"                                      : 'K_atan',
186     "atan2"                                     : 'K_atan2',
187     "atanh"                                     : 'K_atanh',
188     "automatic"                         : 'K_automatic',
189     "before"                                    : 'K_before',
190     "begin"                                     : 'K_begin',
191     "bind"                                      : 'K_bind',
192     "bins"                                      : 'K_bins',
193     "binsof"                                    : 'K_binsof',
194     "bit"                                       : 'K_bit',
195     "branch"                                    : 'K_branch',
196     "break"                                     : 'K_break',
197     "bool"                                      : 'K_bool',
198     "buf"                                       : 'K_buf',
199     "bufif0"                                    : 'K_bufif0',
200     "bufif1"                                    : 'K_bufif1',
201     "byte"                                      : 'K_byte',
202     "case"                                      : 'K_case',
203     "casex"                                     : 'K_casex',
204     "casez"                                     : 'K_casez',
205     "ceil"                                      : 'K_ceil',
206     "cell"                              : 'K_cell',
207     "chandle"                           : 'K_chandle',
208     "checker"                           : 'K_checker',
209     "class"                                     : 'K_class',
210     "clocking"                          : 'K_clocking',
211     "cmos"                                      : 'K_cmos',
212     "config"                            : 'K_config',
213     "connect"                           : 'K_connect',
214     "connectmodule"                             : 'K_connectmodule',
215     "connectrules"                              : 'K_connectrules',
216     "const"                                     : 'K_const',
217     "constraint"                                : 'K_constraint',
218     "context"                           : 'K_context',
219     "continue"                          : 'K_continue',
220     "continuous"                                : 'K_continuous',
221     "cos"                                       : 'K_cos',
222     "cosh"                                      : 'K_cosh',
223     "cover"                                     : 'K_cover',
224     "covergroup"                                : 'K_covergroup',
225     "coverpoint"                                : 'K_coverpoint',
226     "cross"                                     : 'K_cross',
227     "ddt"                                       : 'K_ddt',
228     "ddt_nature"                                : 'K_ddt_nature',
229     "ddx"                                       : 'K_ddx',
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',
237     "dist"                                      : 'K_dist',
238     "do"                                        : 'K_do',
239     "domain"                                    : 'K_domain',
240     "driver_update"                             : 'K_driver_update',
241     "edge"                                      : 'K_edge',
242     "else"                                      : 'K_else',
243     "end"                                       : 'K_end',
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',
266     "enum"                                      : 'K_enum',
267     "event"                                     : 'K_event',
268     "eventually"                                : 'K_eventually',
269     "exclude"                           : 'K_exclude',
270     "exp"                                       : 'K_exp',
271     "expect"                                    : 'K_expect',
272     "export"                                    : 'K_export',
273     "extends"                           : 'K_extends',
274     "extern"                                    : 'K_extern',
275     "final"                                     : 'K_final',
276     "final_step"                                : 'K_final_step',
277     "first_match"                               : 'K_first_match',
278     "flicker_noise"                             : 'K_flicker_noise',
279     "floor"                                     : 'K_floor',
280     "flow"                                      : 'K_flow',
281     "for"                                       : 'K_for',
282     "foreach"                           : 'K_foreach',
283     "force"                                     : 'K_force',
284     "forever"                           : 'K_forever',
285     "fork"                                      : 'K_fork',
286     "forkjoin"                          : 'K_forkjoin',
287     "from"                                      : 'K_from',
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',
295     "hypot"                                     : 'K_hypot',
296     "idt"                                       : 'K_idt',
297     "idtmod"                                    : 'K_idtmod',
298     "idt_nature"                                : 'K_idt_nature',
299     "if"                                        : 'K_if',
300     "iff"                                       : 'K_iff',
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',
309     "inf"                                       : 'K_inf',
310     "initial"                           : 'K_initial',
311     "initial_step"                              : 'K_initial_step',
312     "inout"                                     : 'K_inout',
313     "input"                                     : 'K_input',
314     "inside"                                    : 'K_inside',
315     "instance"                  : 'K_instance',
316     "int"                                       : 'K_int',
317     "integer"                           : 'K_integer',
318     "interconnect"                              : 'K_interconnect',
319     "interface"                         : 'K_interface',
320     "intersect"                         : 'K_intersect',
321     "join"                                      : 'K_join',
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',
328     "large"                                     : 'K_large',
329     "last_crossing"                             : 'K_last_crossing',
330     "let"                                       : 'K_let',
331     "liblist"                   : 'K_liblist',
332     "library"                   : 'K_library',
333     "limexp"                                    : 'K_limexp',
334     "ln"                                        : 'K_ln',
335     "local"                                     : 'K_local',
336     "localparam"                                : 'K_localparam',
337     "log"                                       : 'K_log',
338     # This is defined by SystemVerilog 1800-2005 and as an Icarus extension.'
339     "logic"             : 'K_logic',
340     "longint"                           : 'K_longint',
341     "macromodule"                               : 'K_macromodule',
342     "matches"                           : 'K_matches',
343     "max"                                       : 'K_max',
344     "medium"                                    : 'K_medium',
345     "merged"                                    : 'K_merged',
346     "min"                                       : 'K_min',
347     "modport"                           : 'K_modport',
348     "module"                                    : 'K_module',
349     "nand"                                      : 'K_nand',
350     "nature"                                    : 'K_nature',
351     "negedge"                           : 'K_negedge',
352     "net_resolution"                            : 'K_net_resolution',
353     "nettype"                           : 'K_nettype',
354     "new"                                       : 'K_new',
355     "nexttime"                          : 'K_nexttime',
356     "nmos"                                      : 'K_nmos',
357     "noise_table"                               : 'K_noise_table',
358     "nor"                                       : 'K_nor',
359     "noshowcancelled"                   : 'K_noshowcancelled',
360     "not"                                       : 'K_not',
361     "notif0"                                    : 'K_notif0',
362     "notif1"                                    : 'K_notif1',
363     "null"                                      : 'K_null',
364     "or"                                        : 'K_or',
365     "output"                                    : 'K_output',
366     "package"                           : 'K_package',
367     "packed"                                    : 'K_packed',
368     "parameter"                         : 'K_parameter',
369     "paramset"                          : 'K_paramset',
370     "pmos"                                      : 'K_pmos',
371     "posedge"                           : 'K_posedge',
372     "potential"                         : 'K_potential',
373     "pow"                                       : 'K_pow',
374     "primitive"                         : 'K_primitive',
375     "priority"                          : 'K_priority',
376     "program"                           : 'K_program',
377     "property"                          : 'K_property',
378     "protected"                         : 'K_protected',
379     "pull0"                                     : 'K_pull0',
380     "pull1"                                     : 'K_pull1',
381     "pulldown"                          : 'K_pulldown',
382     "pullup"                                    : 'K_pullup',
383     "pulsestyle_onevent"                        : 'K_pulsestyle_onevent',
384     "pulsestyle_ondetect"                       : 'K_pulsestyle_ondetect',
385     "pure"                                      : 'K_pure',
386     "rand"                                      : 'K_rand',
387     "randc"                                     : 'K_randc',
388     "randcase"                          : 'K_randcase',
389     "randsequence"                              : 'K_randsequence',
390     "rcmos"                                     : 'K_rcmos',
391     "real"                                      : 'K_real',
392     "realtime"                          : 'K_realtime',
393     "ref"                                       : 'K_ref',
394     "reg"                                       : 'K_reg',
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',
401     "rnmos"                                     : 'K_rnmos',
402     "rpmos"                                     : 'K_rpmos',
403     "rtran"                                     : 'K_rtran',
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',
417     "sin"                                       : 'K_sin',
418     "sinh"                                      : 'K_sinh',
419     "slew"                                      : 'K_slew',
420     "small"                                     : 'K_small',
421     "soft"                                      : 'K_soft',
422     "solve"                                     : 'K_solve',
423     "specify"                           : 'K_specify',
424     "specparam"                         : 'K_specparam',
425     "split"                                     : 'K_split',
426     "sqrt"                                      : 'K_sqrt',
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',
434     "super"                                     : 'K_super',
435     "supply0"                           : 'K_supply0',
436     "supply1"                           : 'K_supply1',
437     "sync_accept_on"                            : 'K_sync_accept_on',
438     "sync_reject_on"                            : 'K_sync_reject_on',
439     "table"                                     : 'K_table',
440     "tagged"                                    : 'K_tagged',
441     "tan"                                       : 'K_tan',
442     "tanh"                                      : 'K_tanh',
443     "task"                                      : 'K_task',
444     "this"                                      : 'K_this',
445     "throughout"                                : 'K_throughout',
446     "time"                                      : 'K_time',
447     "timeprecision"                             : 'K_timeprecision',
448     "timer"                                     : 'K_timer',
449     "timeunit"                          : 'K_timeunit',
450     "tran"                                      : 'K_tran',
451     "tranif0"                           : 'K_tranif0',
452     "tranif1"                           : 'K_tranif1',
453     "transition"                                : 'K_transition',
454     "tri"                                       : 'K_tri',
455     "tri0"                                      : 'K_tri0',
456     "tri1"                                      : 'K_tri1',
457     "triand"                                    : 'K_triand',
458     "trior"                                     : 'K_trior',
459     "trireg"                                    : 'K_trireg',
460     "type"                                      : 'K_type',
461     "typedef"                           : 'K_typedef',
462     "union"                                     : 'K_union',
463     "unique"                                    : 'K_unique',
464     "unique0"                           : 'K_unique',
465     "units"                                     : 'K_units',
466     # Reserved for future use!',
467     "unsigned"                          : 'K_unsigned',
468     "until"                                     : 'K_until',
469     "until_with"                                : 'K_until_with',
470     "untyped"                           : 'K_untyped',
471     "use"                               : 'K_use',
472     "uwire"                                     : 'K_uwire',
473     "var"                                       : 'K_var',
474     "vectored"                          : 'K_vectored',
475     "virtual"                           : 'K_virtual',
476     "void"                                      : 'K_void',
477     "wait"                                      : 'K_wait',
478     "wait_order"                                : 'K_wait_order',
479     "wand"                                      : 'K_wand',
480     "weak"                                      : 'K_weak',
481     "weak0"                                     : 'K_weak0',
482     "weak1"                                     : 'K_weak1',
483     "while"                                     : 'K_while',
484     "white_noise"                               : 'K_white_noise',
485     "wildcard"                          : 'K_wildcard',
486     "wire"                                      : 'K_wire',
487     "with"                                      : 'K_with',
488     "within"                                    : 'K_within',
489     # This is the name originally proposed for uwire and is deprecated!',
490     "wone"                                      : 'K_wone',
491     "wor"                                       : 'K_wor',
492     # This is defined by Verilog-AMS 2.3 and as an Icarus extension.',
493     "wreal"             : 'K_wreal',
494     "xnor"                                      : 'K_xnor',
495     "xor"                                       : 'K_xor',
496     "zi_nd"                                     : 'K_zi_nd',
497     "zi_np"                                     : 'K_zi_np',
498     "zi_zd"                                     : 'K_zi_zd',
499     "zi_zp"                                     : 'K_zi_zp',
500 }
501
502 literals = [ '[', '}', '{', ';', ':', '[', ']', ',', '(', ')',
503             '#', '=', '.', '@', '&', '!', '?', '<', '>', '%', 
504             '|', '^', '~', '+', '*', '/', '-']
505
506 """
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 '*'; }
511
512 <EDGES>"]" { BEGIN(0); return yytext[0]; }
513 [}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
514
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;
522                 return STRING; }
523 <CSTRING>\"   { BEGIN(0);
524                 yylval.text = strdupnew(yytext);
525                 yylval.text[strlen(yytext)-1] = 0;
526                 return STRING; }
527 <CSTRING>.    { yymore(); }
528
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]; }
556
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; }
567 """
568
569 """
570 def t_module_end(t):
571     r'endmodule'
572     code = t.lexer.lexdata[t.modulestart:t.lexpos]
573     t.type = 'INITIAL'
574     t.value = code
575     t.lexer.lineno += t.value.count('\n')
576     return t
577
578 t_module_ignore = ' \t'
579 """
580
581 def t_LITERAL(t):
582     r'[a-zA-Z_][a-zA-Z0-9$_]*'
583     word = t.value
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'
591         t.value = keyword
592         return t
593     t.type = keyword
594     return t
595
596 """
597       switch (rc) {
598           case IDENTIFIER:
599             yylval.text = strdupnew(yytext);
600             if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
601                   rc = PATHPULSE_IDENTIFIER;
602             break;
603
604           case K_edge:
605             BEGIN(EDGES);
606             break;
607
608           case K_primitive:
609             in_UDP = true;
610             break;
611
612           case K_endprimitive:
613             in_UDP = false;
614             break;
615
616           case K_table:
617             BEGIN(UDPTABLE);
618             break;
619
620           default:
621             yylval.text = 0;
622             break;
623       }
624
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;
637                   }
638             }
639             in_package_scope = 0;
640             return rc;
641       }
642
643         /* If this identifier names a discipline, then return this as
644            a DISCIPLINE_IDENTIFIER and return the discipline as the
645            value instead. */
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()) {
650                   delete[]yylval.text;
651                   yylval.discipline = (*cur).second;
652                   rc = DISCIPLINE_IDENTIFIER;
653             }
654       }
655
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)) {
660                   delete[]yylval.text;
661                   yylval.package = pkg;
662                   rc = PACKAGE_IDENTIFIER;
663             }
664       }
665
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;
673             }
674       }
675
676       return rc;
677   }
678 """
679
680 """
681 \\[^ \t\b\f\r\n]+         {
682       yylval.text = strdupnew(yytext+1);
683       if (gn_system_verilog()) {
684             if (PPackage*pkg = pform_test_package_identifier(yylval.text)) {
685                   delete[]yylval.text;
686                   yylval.package = pkg;
687                   return PACKAGE_IDENTIFIER;
688             }
689       }
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;
695             }
696       }
697       return IDENTIFIER;
698   }
699
700 \$([a-zA-Z0-9$_]+)        {
701         /* The 1364-1995 timing checks. */
702       if (strcmp(yytext,"$hold") == 0)
703             return K_Shold;
704       if (strcmp(yytext,"$nochange") == 0)
705             return K_Snochange;
706       if (strcmp(yytext,"$period") == 0)
707             return K_Speriod;
708       if (strcmp(yytext,"$recovery") == 0)
709             return K_Srecovery;
710       if (strcmp(yytext,"$setup") == 0)
711             return K_Ssetup;
712       if (strcmp(yytext,"$setuphold") == 0)
713             return K_Ssetuphold;
714       if (strcmp(yytext,"$skew") == 0)
715             return K_Sskew;
716       if (strcmp(yytext,"$width") == 0)
717             return K_Swidth;
718         /* The new 1364-2001 timing checks. */
719       if (strcmp(yytext,"$fullskew") == 0)
720             return K_Sfullskew;
721       if (strcmp(yytext,"$recrem") == 0)
722             return K_Srecrem;
723       if (strcmp(yytext,"$removal") == 0)
724             return K_Sremoval;
725       if (strcmp(yytext,"$timeskew") == 0)
726             return K_Stimeskew;
727
728       if (strcmp(yytext,"$attribute") == 0)
729             return KK_attribute;
730
731       if (gn_system_verilog() && strcmp(yytext,"$unit") == 0) {
732             yylval.package = pform_units.back();
733             return PACKAGE_IDENTIFIER;
734       }
735
736       yylval.text = strdupnew(yytext);
737       return SYSTEM_IDENTIFIER; }
738 """
739
740 def t_dec_number(t):
741     r'\'[sS]?[dD][ \t]*[0-9][0-9_]*'
742     t.type = 'BASED_NUMBER'
743     #t.value = word # make_unsized_dec(yytext);
744     return t
745
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);
750     return t
751
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);
756     return t
757
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);
762     return t
763
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);
768     return t
769
770 def t_unbased_make_unsized_binary(t):
771     r'\'[01xzXZ]'
772     t.type = 'UNBASED_NUMBER'
773     #t.value = word # make_unsized_binary(yytext);
774     return t
775
776 """
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. */
780 """
781 """
782       if (YY_START==UDPTABLE) {
783             REJECT;
784       } else {
785 """
786 def t_make_unsized_dec(t):
787     r'[0-9][0-9_]*'
788     t.type = 'DEC_NUMBER'
789     #t.value = word # make_unsized_dec(yytext);
790     #based_size = yylval.number->as_ulong();
791     return t
792
793 """
794   /* Notice and handle the `timescale directive. */
795 """
796
797 def t_timescale(t):
798     #r'^{W}?`timescale'
799     r'`timescale'
800     t.lexer.timestart = t.lexpos+len(t.value)
801     t.lexer.push_state('timescale')
802
803 #t_timescale_ignore_toeol = r'.+\n'
804 t_timescale_ignore = ' \t'
805 #t_timescale_ignore_whitespace = r'\s+'
806 #t_code_ignore = ""
807
808 def t_timescale_end(t):
809     r'.+\n'
810     code = t.lexer.lexdata[t.lexer.timestart:t.lexpos]
811     t.type = 'timescale'
812     t.value = code
813     t.lexer.pop_state()
814     print "match", code
815     return t
816
817 """
818 <PPTIMESCALE>.* { process_timescale(yytext); }
819 <PPTIMESCALE>\n {
820       if (in_module) {
821             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
822                     "`timescale directive can not be inside a module "
823                     "definition." << endl;
824             error_count += 1;
825       }
826       yylloc.first_line += 1;
827       BEGIN(0); }
828 """
829
830 """
831
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);
836             return TIME_LITERAL;
837       } else REJECT; }
838
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;
845       BEGIN(REAL_SCALE);
846       yymore();  }
847
848 [0-9][0-9_]*/{S} {
849       if (!gn_verilog_ams_flag) REJECT;
850       BEGIN(REAL_SCALE);
851       yymore();  }
852
853 <REAL_SCALE>{S} {
854       size_t token_len = strlen(yytext);
855       char*tmp = new char[token_len + 5];
856       int scale = 0;
857       strcpy(tmp, yytext);
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;
871       }
872       snprintf(tmp+token_len-1, 5, "e%d", scale);
873       yylval.realtime = new verireal(tmp);
874       delete[]tmp;
875
876       BEGIN(0);
877       return REALTIME;  }
878
879 [0-9][0-9_]*\.[0-9][0-9_]*([Ee][+-]?[0-9][0-9_]*)? {
880       yylval.realtime = new verireal(yytext);
881       return REALTIME; }
882
883 [0-9][0-9_]*[Ee][+-]?[0-9][0-9_]* {
884       yylval.realtime = new verireal(yytext);
885       return REALTIME; }
886
887
888   /* Notice and handle the `celldefine and `endcelldefine directives. */
889
890 ^{W}?`celldefine{W}?    { in_celldefine = true; }
891 ^{W}?`endcelldefine{W}? { in_celldefine = false; }
892
893   /* Notice and handle the resetall directive. */
894
895 ^{W}?`resetall{W}? {
896       if (in_module) {
897             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
898                     "`resetall directive can not be inside a module "
899                     "definition." << endl;
900             error_count += 1;
901       } else if (in_UDP) {
902             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
903                     "`resetall directive can not be inside a UDP "
904                     "definition." << endl;
905             error_count += 1;
906       } else {
907             reset_all();
908       } }
909
910   /* Notice and handle the `unconnected_drive directive. */
911 ^{W}?`unconnected_drive { BEGIN(PPUCDRIVE); }
912 <PPUCDRIVE>.* { process_ucdrive(yytext); }
913 <PPUCDRIVE>\n {
914       if (in_module) {
915             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
916                     "`unconnected_drive directive can not be inside a "
917                     "module definition." << endl;
918             error_count += 1;
919       }
920       yylloc.first_line += 1;
921       BEGIN(0); }
922
923 ^{W}?`nounconnected_drive{W}? {
924       if (in_module) {
925             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
926                     "`nounconnected_drive directive can not be inside a "
927                     "module definition." << endl;
928             error_count += 1;
929       }
930       uc_drive = UCD_NONE; }
931
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}?.*                  {  }
936
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}?.*         {  }
944
945   /* From other places. */
946 ^{W}?`disable_portfaults{W}?.*      {  }
947 ^{W}?`enable_portfaults{W}?.*       {  }
948 `endprotect                         {  }
949 ^{W}?`nosuppress_faults{W}?.*       {  }
950 `protect                            {  }
951 ^{W}?`suppress_faults{W}?.*         {  }
952 ^{W}?`uselib{W}?.*                  {  }
953
954 ^{W}?`begin_keywords{W}? { BEGIN(PPBEGIN_KEYWORDS); }
955
956 <PPBEGIN_KEYWORDS>\"[a-zA-Z0-9 -\.]*\".* {
957       keyword_mask_stack.push_front(lexor_keyword_mask);
958
959       char*word = yytext+1;
960       char*tail = strchr(word, '"');
961       tail[0] = 0;
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;
1003       } else {
1004             fprintf(stderr, "%s:%d: Ignoring unknown keywords string: %s\n",
1005                     yylloc.text, yylloc.first_line, word);
1006       }
1007       BEGIN(0);
1008  }
1009
1010 <PPBEGIN_KEYWORDS>.* {
1011       fprintf(stderr, "%s:%d: Malformed keywords specification: %s\n",
1012               yylloc.text, yylloc.first_line, yytext);
1013       BEGIN(0);
1014  }
1015
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();
1020       } else {
1021             fprintf(stderr, "%s:%d: Mismatched end_keywords directive\n",
1022                     yylloc.text, yylloc.first_line);
1023       }
1024  }
1025
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. */
1030
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;
1039
1040       } else if (strcmp(yytext,"tri") == 0) {
1041             net_type = NetNet::TRI;
1042
1043       } else if (strcmp(yytext,"tri0") == 0) {
1044             net_type = NetNet::TRI0;
1045
1046       } else if (strcmp(yytext,"tri1") == 0) {
1047             net_type = NetNet::TRI1;
1048
1049       } else if (strcmp(yytext,"wand") == 0) {
1050             net_type = NetNet::WAND;
1051
1052       } else if (strcmp(yytext,"triand") == 0) {
1053             net_type = NetNet::TRIAND;
1054
1055       } else if (strcmp(yytext,"wor") == 0) {
1056             net_type = NetNet::WOR;
1057
1058       } else if (strcmp(yytext,"trior") == 0) {
1059             net_type = NetNet::TRIOR;
1060
1061       } else if (strcmp(yytext,"none") == 0) {
1062             net_type = NetNet::NONE;
1063
1064       } else {
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;
1070             error_count += 1;
1071       }
1072       pform_set_default_nettype(net_type, yylloc.text, yylloc.first_line);
1073   }
1074 <PPDEFAULT_NETTYPE>\n {
1075       yylloc.first_line += 1;
1076       BEGIN(0); }
1077
1078
1079   /* These are directives that are not supported by me and should have
1080      been handled by an external preprocessor such as ivlpp. */
1081
1082 ^{W}?`define{W}?.* {
1083       cerr << yylloc.text << ":" << yylloc.first_line <<
1084             ": warning: `define not supported. Use an external preprocessor."
1085            << endl;
1086   }
1087
1088 ^{W}?`else{W}?.* {
1089       cerr << yylloc.text << ":" << yylloc.first_line <<
1090             ": warning: `else not supported. Use an external preprocessor."
1091            << endl;
1092   }
1093
1094 ^{W}?`elsif{W}?.* {
1095       cerr << yylloc.text << ":" << yylloc.first_line <<
1096             ": warning: `elsif not supported. Use an external preprocessor."
1097            << endl;
1098   }
1099
1100 ^{W}?`endif{W}?.* {
1101       cerr << yylloc.text << ":" << yylloc.first_line <<
1102             ": warning: `endif not supported. Use an external preprocessor."
1103            << endl;
1104   }
1105
1106 ^{W}?`ifdef{W}?.* {
1107       cerr << yylloc.text << ":" << yylloc.first_line <<
1108             ": warning: `ifdef not supported. Use an external preprocessor."
1109            << endl;
1110   }
1111
1112 ^{W}?`ifndef{W}?.* {
1113       cerr << yylloc.text << ":" << yylloc.first_line <<
1114             ": warning: `ifndef not supported. Use an external preprocessor."
1115            << endl;
1116   }
1117
1118 ^`include{W}?.* {
1119       cerr << yylloc.text << ":" << yylloc.first_line <<
1120             ": warning: `include not supported. Use an external preprocessor."
1121            << endl;
1122   }
1123
1124 ^`undef{W}?.* {
1125       cerr << yylloc.text << ":" << yylloc.first_line <<
1126             ": warning: `undef not supported. Use an external preprocessor."
1127            << endl;
1128   }
1129
1130
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?"
1135             << endl;
1136        error_count += 1; }
1137
1138 . { return yytext[0]; }
1139
1140   /* Final catchall. something got lost or mishandled. */
1141   /* XXX Should we tell the user something about the lexical state? */
1142
1143 <*>.|\n {   cerr << yylloc.text << ":" << yylloc.first_line
1144            << ": error: unmatched character (";
1145       if (isprint(yytext[0]))
1146             cerr << yytext[0];
1147       else
1148             cerr << "hex " << hex << ((unsigned char) yytext[0]);
1149
1150       cerr << ")" << endl;
1151       error_count += 1; }
1152
1153 %%
1154
1155 /*
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.
1159  */
1160 void lex_end_table()
1161 {
1162       BEGIN(INITIAL);
1163 }
1164
1165 static unsigned truncate_to_integer_width(verinum::V*bits, unsigned size)
1166 {
1167       if (size <= integer_width) return size;
1168
1169       verinum::V pad = bits[size-1];
1170       if (pad == verinum::V1) pad = verinum::V0;
1171
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.");
1175                   break;
1176             }
1177       }
1178       return integer_width;
1179 }
1180
1181 verinum*make_unsized_binary(const char*txt)
1182 {
1183       bool sign_flag = false;
1184       bool single_flag = false;
1185       const char*ptr = txt;
1186       assert(*ptr == '\'');
1187       ptr += 1;
1188
1189       if (tolower(*ptr) == 's') {
1190             sign_flag = true;
1191             ptr += 1;
1192       }
1193
1194       assert((tolower(*ptr) == 'b') || gn_system_verilog());
1195       if (tolower(*ptr) == 'b') {
1196             ptr += 1;
1197       } else {
1198             assert(sign_flag == false);
1199             single_flag = true;
1200       }
1201
1202       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1203             ptr += 1;
1204
1205       unsigned size = 0;
1206       for (const char*idx = ptr ;  *idx ;  idx += 1)
1207             if (*idx != '_') size += 1;
1208
1209       if (size == 0) {
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);
1214             return out;
1215       }
1216
1217       if ((based_size > 0) && (size > based_size)) yywarn(yylloc,
1218           "extra digits given for sized binary constant.");
1219
1220       verinum::V*bits = new verinum::V[size];
1221
1222       unsigned idx = size;
1223       while (*ptr) {
1224             switch (ptr[0]) {
1225                 case '0':
1226                   bits[--idx] = verinum::V0;
1227                   break;
1228                 case '1':
1229                   bits[--idx] = verinum::V1;
1230                   break;
1231                 case 'z': case 'Z': case '?':
1232                   bits[--idx] = verinum::Vz;
1233                   break;
1234                 case 'x': case 'X':
1235                   bits[--idx] = verinum::Vx;
1236                   break;
1237                   case '_':
1238                   break;
1239                 default:
1240                   fprintf(stderr, "%c\n", ptr[0]);
1241                   assert(0);
1242             }
1243             ptr += 1;
1244       }
1245
1246       if (gn_strict_expr_width_flag && (based_size == 0))
1247             size = truncate_to_integer_width(bits, size);
1248
1249       verinum*out = new verinum(bits, size, false);
1250       out->has_sign(sign_flag);
1251       out->is_single(single_flag);
1252       delete[]bits;
1253       return out;
1254 }
1255
1256
1257 verinum*make_unsized_octal(const char*txt)
1258 {
1259       bool sign_flag = false;
1260       const char*ptr = txt;
1261       assert(*ptr == '\'');
1262       ptr += 1;
1263
1264       if (tolower(*ptr) == 's') {
1265             sign_flag = true;
1266             ptr += 1;
1267       }
1268
1269       assert(tolower(*ptr) == 'o');
1270       ptr += 1;
1271
1272       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1273             ptr += 1;
1274
1275       unsigned size = 0;
1276       for (const char*idx = ptr ;  *idx ;  idx += 1)
1277             if (*idx != '_') size += 3;
1278
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.");
1284       }
1285
1286       verinum::V*bits = new verinum::V[size];
1287
1288       unsigned idx = size;
1289       while (*ptr) {
1290             unsigned val;
1291             switch (ptr[0]) {
1292                 case '0': case '1': case '2': case '3':
1293                 case '4': case '5': case '6': case '7':
1294                   val = *ptr - '0';
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;
1298                   break;
1299                 case 'x': case 'X':
1300                   bits[--idx] = verinum::Vx;
1301                   bits[--idx] = verinum::Vx;
1302                   bits[--idx] = verinum::Vx;
1303                   break;
1304                 case 'z': case 'Z': case '?':
1305                   bits[--idx] = verinum::Vz;
1306                   bits[--idx] = verinum::Vz;
1307                   bits[--idx] = verinum::Vz;
1308                   break;
1309                 case '_':
1310                   break;
1311                 default:
1312                   assert(0);
1313             }
1314             ptr += 1;
1315       }
1316
1317       if (gn_strict_expr_width_flag && (based_size == 0))
1318             size = truncate_to_integer_width(bits, size);
1319
1320       verinum*out = new verinum(bits, size, false);
1321       out->has_sign(sign_flag);
1322       delete[]bits;
1323       return out;
1324 }
1325
1326
1327 verinum*make_unsized_hex(const char*txt)
1328 {
1329       bool sign_flag = false;
1330       const char*ptr = txt;
1331       assert(*ptr == '\'');
1332       ptr += 1;
1333
1334       if (tolower(*ptr) == 's') {
1335             sign_flag = true;
1336             ptr += 1;
1337       }
1338       assert(tolower(*ptr) == 'h');
1339
1340       ptr += 1;
1341       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1342             ptr += 1;
1343
1344       unsigned size = 0;
1345       for (const char*idx = ptr ;  *idx ;  idx += 1)
1346             if (*idx != '_') size += 4;
1347
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.");
1353       }
1354
1355       verinum::V*bits = new verinum::V[size];
1356
1357       unsigned idx = size;
1358       while (*ptr) {
1359             unsigned val;
1360             switch (ptr[0]) {
1361                 case '0': case '1': case '2': case '3': case '4':
1362                 case '5': case '6': case '7': case '8': case '9':
1363                   val = *ptr - '0';
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;
1368                   break;
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;
1376                   break;
1377                 case 'x': case 'X':
1378                   bits[--idx] = verinum::Vx;
1379                   bits[--idx] = verinum::Vx;
1380                   bits[--idx] = verinum::Vx;
1381                   bits[--idx] = verinum::Vx;
1382                   break;
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;
1388                   break;
1389                 case '_':
1390                   break;
1391                 default:
1392                   assert(0);
1393             }
1394             ptr += 1;
1395       }
1396
1397       if (gn_strict_expr_width_flag && (based_size == 0))
1398             size = truncate_to_integer_width(bits, size);
1399
1400       verinum*out = new verinum(bits, size, false);
1401       out->has_sign(sign_flag);
1402       delete[]bits;
1403       return out;
1404 }
1405
1406
1407 /* Divide the integer given by the string by 2. Return the remainder bit. */
1408 static int dec_buf_div2(char *buf)
1409 {
1410     int partial;
1411     int len = strlen(buf);
1412     char *dst_ptr;
1413     int pos;
1414
1415     partial = 0;
1416     pos = 0;
1417
1418     /* dst_ptr overwrites buf, but all characters that are overwritten
1419        were already used by the reader. */
1420     dst_ptr = buf;
1421
1422     while(buf[pos] == '0')
1423         ++pos;
1424
1425     for(; pos<len; ++pos){
1426         if (buf[pos]=='_')
1427             continue;
1428
1429         assert(isdigit(buf[pos]));
1430
1431         partial= partial*10 + (buf[pos]-'0');
1432
1433         if (partial >= 2){
1434             *dst_ptr = partial/2 + '0';
1435             partial = partial & 1;
1436
1437             ++dst_ptr;
1438         }
1439         else{
1440             *dst_ptr = '0';
1441             ++dst_ptr;
1442         }
1443     }
1444
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){
1448         *dst_ptr = '0';
1449         ++dst_ptr;
1450     }
1451     *dst_ptr = 0;
1452
1453     return partial;
1454 }
1455
1456 /* Support a single x, z or ? as a decimal constant (from 1364-2005). */
1457 verinum* make_undef_highz_dec(const char* ptr)
1458 {
1459       bool signed_flag = false;
1460
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. */
1465       ptr += 1;
1466
1467       if (tolower(*ptr) == 's') {
1468           signed_flag = true;
1469           ptr += 1;
1470       }
1471
1472       assert(tolower(*ptr) == 'd');
1473       ptr += 1;
1474
1475       while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1476           ptr += 1;
1477
1478         /* Process the code. */
1479       verinum::V* bits = new verinum::V[1];
1480       switch (*ptr) {
1481           case 'x':
1482           case 'X':
1483             bits[0] = verinum::Vx;
1484             break;
1485           case 'z':
1486           case 'Z':
1487           case '?':
1488             bits[0] = verinum::Vz;
1489             break;
1490           default:
1491             assert(0);
1492       }
1493       ptr += 1;
1494       while (*ptr == '_') ptr += 1;
1495       assert(*ptr == 0);
1496
1497       verinum*out = new verinum(bits, 1, false);
1498       out->has_sign(signed_flag);
1499       delete[]bits;
1500       return out;
1501 }
1502
1503 /*
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.
1508  */
1509
1510 verinum*make_unsized_dec(const char*ptr)
1511 {
1512       char buf[4096];
1513       bool signed_flag = false;
1514       unsigned idx;
1515
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
1520                  signed. */
1521             ptr += 1;
1522
1523             if (tolower(*ptr) == 's') {
1524                   signed_flag = true;
1525                   ptr += 1;
1526             }
1527
1528             assert(tolower(*ptr) == 'd');
1529             ptr += 1;
1530
1531             while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
1532                   ptr += 1;
1533
1534       } else {
1535               /* ... or an undecorated decimal number is passed
1536                  it. These numbers are treated as signed decimal. */
1537             assert(isdigit(*ptr));
1538             signed_flag = true;
1539       }
1540
1541
1542         /* Copy the digits into a buffer that I can use to do in-place
1543            decimal divides. */
1544       idx = 0;
1545       while ((idx < sizeof buf) && (*ptr != 0)) {
1546             if (*ptr == '_') {
1547                   ptr += 1;
1548                   continue;
1549             }
1550
1551             buf[idx++] = *ptr++;
1552       }
1553
1554       if (idx == sizeof buf) {
1555             fprintf(stderr, "Ridiculously long"
1556                     " decimal constant will be truncated!\n");
1557             idx -= 1;
1558       }
1559
1560       buf[idx] = 0;
1561       unsigned tmp_size = idx * 4 + 1;
1562       verinum::V *bits = new verinum::V[tmp_size];
1563
1564       idx = 0;
1565       while (idx < tmp_size) {
1566             int rem = dec_buf_div2(buf);
1567             bits[idx++] = (rem == 1) ? verinum::V1 : verinum::V0;
1568       }
1569
1570       assert(strcmp(buf, "0") == 0);
1571
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))
1576             size -= 1;
1577
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)) {
1581             size += 1;
1582             assert(size <= tmp_size);
1583       }
1584
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) { }
1588
1589       if (gn_strict_expr_width_flag && (based_size == 0))
1590             size = truncate_to_integer_width(bits, size);
1591
1592       verinum*res = new verinum(bits, size, false);
1593       res->has_sign(signed_flag);
1594
1595       delete[]bits;
1596       return res;
1597 }
1598
1599 /*
1600  * Convert the string to a time unit or precision.
1601  * Returns true on failure.
1602  */
1603 static bool get_timescale_const(const char *&cp, int &res, bool is_unit)
1604 {
1605         /* Check for the 1 digit. */
1606       if (*cp != '1') {
1607             if (is_unit) {
1608                   VLerror(yylloc, "Invalid `timescale unit constant "
1609                                   "(1st digit)");
1610             } else {
1611                   VLerror(yylloc, "Invalid `timescale precision constant "
1612                                   "(1st digit)");
1613             }
1614             return true;
1615       }
1616       cp += 1;
1617
1618         /* Check the number of zeros after the 1. */
1619       res = strspn(cp, "0");
1620       if (res > 2) {
1621             if (is_unit) {
1622                   VLerror(yylloc, "Invalid `timescale unit constant "
1623                                   "(number of zeros)");
1624             } else {
1625                   VLerror(yylloc, "Invalid `timescale precision constant "
1626                                   "(number of zeros)");
1627             }
1628             return true;
1629       }
1630       cp += res;
1631
1632         /* Skip any space between the digits and the scaling string. */
1633       cp += strspn(cp, " \t");
1634
1635         /* Now process the scaling string. */
1636       if (strncmp("s", cp, 1) == 0) {
1637             res -= 0;
1638             cp += 1;
1639             return false;
1640
1641       } else if (strncmp("ms", cp, 2) == 0) {
1642             res -= 3;
1643             cp += 2;
1644             return false;
1645
1646       } else if (strncmp("us", cp, 2) == 0) {
1647             res -= 6;
1648             cp += 2;
1649             return false;
1650
1651       } else if (strncmp("ns", cp, 2) == 0) {
1652             res -= 9;
1653             cp += 2;
1654             return false;
1655
1656       } else if (strncmp("ps", cp, 2) == 0) {
1657             res -= 12;
1658             cp += 2;
1659             return false;
1660
1661       } else if (strncmp("fs", cp, 2) == 0) {
1662             res -= 15;
1663             cp += 2;
1664             return false;
1665
1666       }
1667
1668       if (is_unit) {
1669             VLerror(yylloc, "Invalid `timescale unit scale");
1670       } else {
1671             VLerror(yylloc, "Invalid `timescale precision scale");
1672       }
1673       return true;
1674 }
1675
1676
1677 /*
1678  * process either a pull0 or a pull1.
1679  */
1680 static void process_ucdrive(const char*txt)
1681 {
1682       UCDriveType ucd = UCD_NONE;
1683       const char*cp = txt + strspn(txt, " \t");
1684
1685         /* Skip the space after the `unconnected_drive directive. */
1686       if (cp == txt) {
1687             VLerror(yylloc, "Space required after `unconnected_drive "
1688                             "directive.");
1689             return;
1690       }
1691
1692         /* Check for the pull keyword. */
1693       if (strncmp("pull", cp, 4) != 0) {
1694             VLerror(yylloc, "pull required for `unconnected_drive "
1695                             "directive.");
1696             return;
1697       }
1698       cp += 4;
1699       if (*cp == '0') ucd = UCD_PULL0;
1700       else if (*cp == '1') ucd = UCD_PULL1;
1701       else {
1702             cerr << yylloc.text << ":" << yylloc.first_line << ": error: "
1703                     "`unconnected_drive does not support 'pull" << *cp
1704                  << "'." << endl;
1705             error_count += 1;
1706             return;
1707       }
1708       cp += 1;
1709
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).");
1716             return;
1717       }
1718
1719       uc_drive = ucd;
1720 }
1721
1722 /*
1723  * The timescale parameter has the form:
1724  *      " <num> xs / <num> xs"
1725  */
1726 static void process_timescale(const char*txt)
1727 {
1728       const char*cp = txt + strspn(txt, " \t");
1729
1730         /* Skip the space after the `timescale directive. */
1731       if (cp == txt) {
1732             VLerror(yylloc, "Space required after `timescale directive.");
1733             return;
1734       }
1735
1736       int unit = 0;
1737       int prec = 0;
1738
1739         /* Get the time units. */
1740       if (get_timescale_const(cp, unit, true)) return;
1741
1742         /* Skip any space after the time units, the '/' and any
1743          * space after the '/'. */
1744       cp += strspn(cp, " \t");
1745       if (*cp != '/') {
1746             VLerror(yylloc, "`timescale separator '/' appears to be missing.");
1747             return;
1748       }
1749       cp += 1;
1750       cp += strspn(cp, " \t");
1751
1752         /* Get the time precision. */
1753       if (get_timescale_const(cp, prec, false)) return;
1754
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).");
1761             return;
1762       }
1763
1764         /* The time unit must be greater than or equal to the precision. */
1765       if (unit < prec) {
1766             VLerror(yylloc, "error: `timescale unit must not be less than "
1767                             "the precision.");
1768             return;
1769       }
1770
1771       pform_set_timescale(unit, prec, yylloc.text, yylloc.first_line);
1772 }
1773
1774 int yywrap()
1775 {
1776       return 1;
1777 }
1778
1779 /*
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.
1783  */
1784 static void line_directive()
1785 {
1786       char *cpr;
1787         /* Skip any leading space. */
1788       char *cp = strchr(yytext, '#');
1789         /* Skip the #line directive. */
1790       assert(strncmp(cp, "#line", 5) == 0);
1791       cp += 5;
1792         /* Skip the space after the #line directive. */
1793       cp += strspn(cp, " \t");
1794
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).");
1799             return;
1800       }
1801       fn_start += 1;
1802
1803         /* Find the last ". */
1804       char*fn_end = strrchr(fn_start, '"');
1805       if (!fn_end) {
1806             VLerror(yylloc, "Invalid #line directive (file name end).");
1807             return;
1808       }
1809
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;
1814
1815         /* Skip the space after the file name. */
1816       cp = fn_end;
1817       cp += 1;
1818       cpr = cp;
1819       cpr += strspn(cp, " \t");
1820       if (cp == cpr) {
1821             VLerror(yylloc, "Invalid #line directive (missing space after "
1822                             "file name).");
1823             delete[] buf;
1824             return;
1825       }
1826       cp = cpr;
1827
1828         /* Get the line number and verify that it is correct. */
1829       unsigned long lineno = strtoul(cp, &cpr, 10);
1830       if (cp == cpr) {
1831             VLerror(yylloc, "Invalid line number for #line directive.");
1832             delete[] buf;
1833             return;
1834       }
1835       cp = cpr;
1836
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 "
1841                             "line number).");
1842             delete[] buf;
1843             return;
1844       }
1845
1846         /* Now we can assign the new values to yyloc. */
1847       yylloc.text = set_file_name(buf);
1848       yylloc.first_line = lineno;
1849 }
1850
1851 /*
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.
1855  */
1856 static void line_directive2()
1857 {
1858       char *cpr;
1859         /* Skip any leading space. */
1860       char *cp = strchr(yytext, '`');
1861         /* Skip the `line directive. */
1862       assert(strncmp(cp, "`line", 5) == 0);
1863       cp += 5;
1864
1865         /* strtoul skips leading space. */
1866       unsigned long lineno = strtoul(cp, &cpr, 10);
1867       if (cp == cpr) {
1868             VLerror(yylloc, "Invalid line number for `line directive.");
1869             return;
1870       }
1871       lineno -= 1;
1872       cp = cpr;
1873
1874         /* Skip the space between the line number and the file name. */
1875       cpr += strspn(cp, " \t");
1876       if (cp == cpr) {
1877             VLerror(yylloc, "Invalid `line directive (missing space after "
1878                             "line number).");
1879             return;
1880       }
1881       cp = cpr;
1882
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).");
1887             return;
1888       }
1889       fn_start += 1;
1890
1891         /* Find the last ". */
1892       char*fn_end = strrchr(fn_start, '"');
1893       if (!fn_end) {
1894             VLerror(yylloc, "Invalid `line directive (file name end).");
1895             return;
1896       }
1897
1898         /* Skip the space after the file name. */
1899       cp = fn_end + 1;
1900       cpr = cp;
1901       cpr += strspn(cp, " \t");
1902       if (cp == cpr) {
1903             VLerror(yylloc, "Invalid `line directive (missing space after "
1904                             "file name).");
1905             return;
1906       }
1907       cp = cpr;
1908
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.");
1912             return;
1913       }
1914       cp += 1;
1915
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 "
1921                             "level).");
1922             return;
1923       }
1924
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;
1929
1930       yylloc.text = set_file_name(buf);
1931       yylloc.first_line = lineno;
1932 }
1933
1934 /*
1935  * Reset all compiler directives. This will be called when a `resetall
1936  * directive is encountered or when a new compilation unit is started.
1937  */
1938 static void reset_all()
1939 {
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);
1944 }
1945
1946 extern FILE*vl_input;
1947 void reset_lexor()
1948 {
1949       yyrestart(vl_input);
1950       yylloc.first_line = 1;
1951
1952         /* Announce the first file name. */
1953       yylloc.text = set_file_name(strdupnew(vl_file.c_str()));
1954
1955       if (separate_compilation) {
1956             reset_all();
1957             if (!keyword_mask_stack.empty()) {
1958                   lexor_keyword_mask = keyword_mask_stack.back();
1959                   keyword_mask_stack.clear();
1960             }
1961       }
1962 }
1963
1964 /*
1965  * Modern version of flex (>=2.5.9) can clean up the scanner data.
1966  */
1967 void destroy_lexor()
1968 {
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
1972     yylex_destroy();
1973 #     endif
1974 #   endif
1975 # endif
1976 }
1977 """
1978
1979 def t_timescale_error(t):
1980     print("%d: Timescale error '%s'" % (t.lexer.lineno, t.value[0]))
1981     print(t.value)
1982     raise RuntimeError
1983
1984 """
1985 def t_module_error(t):
1986     print("%d: Module error '%s'" % (t.lexer.lineno, t.value[0]))
1987     print(t.value)
1988     raise RuntimeError
1989 """
1990
1991 def t_error(t):
1992     print("%d: Illegal character '%s'" % (t.lexer.lineno, t.value[0]))
1993     print(t.value)
1994     t.lexer.skip(1)
1995
1996 tokens = list(set(tokens))
1997
1998 lex.lex()
1999
2000 if __name__ == '__main__':
2001     lex.runmain()
2002