add extra pass-through rules
[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 = word
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