""" %{ /* * Copyright (c) 1998-2017 Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ """ from parse_tokens import tokens from ply import lex lex_debug = 0 # DOCSTRING REMOVED states = ( # ('module', 'exclusive'), ('timescale', 'exclusive'),) tokens += ['timescale', 'LITERAL', 'IDENTIFIER', 'DEC_NUMBER', 'BASED_NUMBER', 'UNBASED_NUMBER'] def t_ccomment(t): r'/\*(.|\n)*?\*/' t.lexer.lineno += t.value.count('\n') t_ignore_cppcomment = r'//.*' t_ignore = ' \t\n' t_K_PSTAR = r"\(\*" t_K_STARP = r"\*\)" t_K_DOTSTAR = r"\.\*" t_K_LS = r"(<<|<<<)" t_K_RS = r">>" t_K_RSS = r">>>" t_K_POW = r"\*\*" t_K_LE = r"<=" t_K_GE = r">=" t_K_EG = r"=>" """ "+=>"|"-=>" { /* * Resolve the ambiguity between the += assignment * operator and +=> polarity edge path operator * * +=> should be treated as two separate tokens '+' and * '=>' (K_EG), therefore we only consume the first * character of the matched pattern i.e. either + or - * and push back the rest of the matches text (=>) in * the input stream. */ yyless(1); return yytext[0]; } """ t_K_SG = r"\*>" t_K_EQ = r"==" t_K_NE = r"!=" t_K_CEQ = r"===" t_K_CNE = r"!==" t_K_WEQ = r"==\?" t_K_WNE = r"!=\?" t_K_LOR = r"\|\|" t_K_LAND = r"\&\&" t_K_TAND = r"\&\&\&" t_K_NOR = r"\~\|" t_K_NXOR = r"(\~\^|\^\~)" t_K_NAND = r"\~\&" t_K_TRIGGER = r"\->" t_K_PO_POS = r"\+:" t_K_PO_NEG = r"\-:" t_K_CONTRIBUTE = r"<\+" t_K_PLUS_EQ = r"\+=" t_K_MINUS_EQ = r"\-=" t_K_MUL_EQ = r"\*=" t_K_DIV_EQ = r"\/=" t_K_MOD_EQ = r"\%=" t_K_AND_EQ = r"\&=" t_K_OR_EQ = r"\|=" t_K_XOR_EQ = r"\^=" t_K_LS_EQ = r"(<<=|<<<=)" t_K_RS_EQ = r">>=" t_K_RSS_EQ = r">>>=" t_K_INCR = r"\+\+" t_K_DECR = r"\\--" t_K_LP = r"\'\{" t_K_SCOPE_RES = r"::" tokens += ['K_PSTAR', 'K_STARP', 'K_DOTSTAR', 'K_LS', 'K_RS', 'K_RSS', 'K_POW', 'K_LE', 'K_GE', 'K_EG', 'K_SG', 'K_EQ', 'K_NE', 'K_CEQ', 'K_CNE', 'K_WEQ', 'K_WNE', 'K_LOR', 'K_LAND', 'K_TAND', 'K_NOR', 'K_NXOR', 'K_NAND', 'K_TRIGGER', 'K_PO_POS', 'K_PO_NEG', 'K_CONTRIBUTE', 'K_PLUS_EQ', 'K_MINUS_EQ', 'K_MUL_EQ', 'K_DIV_EQ', 'K_MOD_EQ', 'K_AND_EQ', 'K_OR_EQ', 'K_XOR_EQ', 'K_LS_EQ', 'K_RS_EQ', 'K_RSS_EQ', 'K_INCR', 'K_DECR', 'K_LP', 'K_SCOPE_RES' ] lexor_keyword_code = { "above" : 'K_above', "abs" : 'K_abs', "absdelay" : 'K_absdelay', "abstol" : 'K_abstol', "accept_on" : 'K_accept_on', "access" : 'K_access', "acos" : 'K_acos', "acosh" : 'K_acosh', "ac_stim" : 'K_ac_stim', "alias" : 'K_alias', "aliasparam" : 'K_aliasparam', "always" : 'K_always', "always_comb" : 'K_always_comb', "always_ff" : 'K_always_ff', "always_latch" : 'K_always_latch', "analog" : 'K_analog', "analysis" : 'K_analysis', "and" : 'K_and', "asin" : 'K_asin', "asinh" : 'K_asinh', "assert" : 'K_assert', "assign" : 'K_assign', "assume" : 'K_assume', "atan" : 'K_atan', "atan2" : 'K_atan2', "atanh" : 'K_atanh', "automatic" : 'K_automatic', "before" : 'K_before', "begin" : 'K_begin', "bind" : 'K_bind', "bins" : 'K_bins', "binsof" : 'K_binsof', "bit" : 'K_bit', "branch" : 'K_branch', "break" : 'K_break', "bool" : 'K_bool', "buf" : 'K_buf', "bufif0" : 'K_bufif0', "bufif1" : 'K_bufif1', "byte" : 'K_byte', "case" : 'K_case', "casex" : 'K_casex', "casez" : 'K_casez', "ceil" : 'K_ceil', "cell" : 'K_cell', "chandle" : 'K_chandle', "checker" : 'K_checker', "class" : 'K_class', "clocking" : 'K_clocking', "cmos" : 'K_cmos', "config" : 'K_config', "connect" : 'K_connect', "connectmodule" : 'K_connectmodule', "connectrules" : 'K_connectrules', "const" : 'K_const', "constraint" : 'K_constraint', "context" : 'K_context', "continue" : 'K_continue', "continuous" : 'K_continuous', "cos" : 'K_cos', "cosh" : 'K_cosh', "cover" : 'K_cover', "covergroup" : 'K_covergroup', "coverpoint" : 'K_coverpoint', "cross" : 'K_cross', "ddt" : 'K_ddt', "ddt_nature" : 'K_ddt_nature', "ddx" : 'K_ddx', "deassign" : 'K_deassign', "default" : 'K_default', "defparam" : 'K_defparam', "design" : 'K_design', "disable" : 'K_disable', "discipline" : 'K_discipline', "discrete" : 'K_discrete', "dist" : 'K_dist', "do" : 'K_do', "domain" : 'K_domain', "driver_update" : 'K_driver_update', "edge" : 'K_edge', "else" : 'K_else', "end" : 'K_end', "endcase" : 'K_endcase', "endchecker" : 'K_endchecker', "endconfig" : 'K_endconfig', "endclass" : 'K_endclass', "endclocking" : 'K_endclocking', "endconnectrules" : 'K_endconnectrules', "enddiscipline" : 'K_enddiscipline', "endfunction" : 'K_endfunction', "endgenerate" : 'K_endgenerate', "endgroup" : 'K_endgroup', "endinterface" : 'K_endinterface', "endmodule" : 'K_endmodule', "endnature" : 'K_endnature', "endpackage" : 'K_endpackage', "endparamset" : 'K_endparamset', "endprimitive" : 'K_endprimitive', "endprogram" : 'K_endprogram', "endproperty" : 'K_endproperty', "endspecify" : 'K_endspecify', "endsequence" : 'K_endsequence', "endtable" : 'K_endtable', "endtask" : 'K_endtask', "enum" : 'K_enum', "event" : 'K_event', "eventually" : 'K_eventually', "exclude" : 'K_exclude', "exp" : 'K_exp', "expect" : 'K_expect', "export" : 'K_export', "extends" : 'K_extends', "extern" : 'K_extern', "final" : 'K_final', "final_step" : 'K_final_step', "first_match" : 'K_first_match', "flicker_noise" : 'K_flicker_noise', "floor" : 'K_floor', "flow" : 'K_flow', "for" : 'K_for', "foreach" : 'K_foreach', "force" : 'K_force', "forever" : 'K_forever', "fork" : 'K_fork', "forkjoin" : 'K_forkjoin', "from" : 'K_from', "function" : 'K_function', "generate" : 'K_generate', "genvar" : 'K_genvar', "global" : 'K_global', "ground" : 'K_ground', "highz0" : 'K_highz0', "highz1" : 'K_highz1', "hypot" : 'K_hypot', "idt" : 'K_idt', "idtmod" : 'K_idtmod', "idt_nature" : 'K_idt_nature', "if" : 'K_if', "iff" : 'K_iff', "ifnone" : 'K_ifnone', "ignore_bins" : 'K_ignore_bins', "illegal_bins" : 'K_illegal_bins', "implies" : 'K_implies', "implements" : 'K_implements', "import" : 'K_import', "incdir" : 'K_incdir', "include" : 'K_include', "inf" : 'K_inf', "initial" : 'K_initial', "initial_step" : 'K_initial_step', "inout" : 'K_inout', "input" : 'K_input', "inside" : 'K_inside', "instance" : 'K_instance', "int" : 'K_int', "integer" : 'K_integer', "interconnect" : 'K_interconnect', "interface" : 'K_interface', "intersect" : 'K_intersect', "join" : 'K_join', "join_any" : 'K_join_any', "join_none" : 'K_join_none', "laplace_nd" : 'K_laplace_nd', "laplace_np" : 'K_laplace_np', "laplace_zd" : 'K_laplace_zd', "laplace_zp" : 'K_laplace_zp', "large" : 'K_large', "last_crossing" : 'K_last_crossing', "let" : 'K_let', "liblist" : 'K_liblist', "library" : 'K_library', "limexp" : 'K_limexp', "ln" : 'K_ln', "local" : 'K_local', "localparam" : 'K_localparam', "log" : 'K_log', # This is defined by SystemVerilog 1800-2005 and as an Icarus extension.' "logic" : 'K_logic', "longint" : 'K_longint', "macromodule" : 'K_macromodule', "matches" : 'K_matches', "max" : 'K_max', "medium" : 'K_medium', "merged" : 'K_merged', "min" : 'K_min', "modport" : 'K_modport', "module" : 'K_module', "nand" : 'K_nand', "nature" : 'K_nature', "negedge" : 'K_negedge', "net_resolution" : 'K_net_resolution', "nettype" : 'K_nettype', "new" : 'K_new', "nexttime" : 'K_nexttime', "nmos" : 'K_nmos', "noise_table" : 'K_noise_table', "nor" : 'K_nor', "noshowcancelled" : 'K_noshowcancelled', "not" : 'K_not', "notif0" : 'K_notif0', "notif1" : 'K_notif1', "null" : 'K_null', "or" : 'K_or', "output" : 'K_output', "package" : 'K_package', "packed" : 'K_packed', "parameter" : 'K_parameter', "paramset" : 'K_paramset', "pmos" : 'K_pmos', "posedge" : 'K_posedge', "potential" : 'K_potential', "pow" : 'K_pow', "primitive" : 'K_primitive', "priority" : 'K_priority', "program" : 'K_program', "property" : 'K_property', "protected" : 'K_protected', "pull0" : 'K_pull0', "pull1" : 'K_pull1', "pulldown" : 'K_pulldown', "pullup" : 'K_pullup', "pulsestyle_onevent" : 'K_pulsestyle_onevent', "pulsestyle_ondetect" : 'K_pulsestyle_ondetect', "pure" : 'K_pure', "rand" : 'K_rand', "randc" : 'K_randc', "randcase" : 'K_randcase', "randsequence" : 'K_randsequence', "rcmos" : 'K_rcmos', "real" : 'K_real', "realtime" : 'K_realtime', "ref" : 'K_ref', "reg" : 'K_reg', "reject_on" : 'K_reject_on', "release" : 'K_release', "repeat" : 'K_repeat', "resolveto" : 'K_resolveto', "restrict" : 'K_restrict', "return" : 'K_return', "rnmos" : 'K_rnmos', "rpmos" : 'K_rpmos', "rtran" : 'K_rtran', "rtranif0" : 'K_rtranif0', "rtranif1" : 'K_rtranif1', "s_always" : 'K_s_always', "s_eventually" : 'K_s_eventually', "s_nexttime" : 'K_s_nexttime', "s_until" : 'K_s_until', "s_until_with" : 'K_s_until_with', "scalared" : 'K_scalared', "sequence" : 'K_sequence', "shortint" : 'K_shortint', "shortreal" : 'K_shortreal', "showcancelled" : 'K_showcancelled', "signed" : 'K_signed', "sin" : 'K_sin', "sinh" : 'K_sinh', "slew" : 'K_slew', "small" : 'K_small', "soft" : 'K_soft', "solve" : 'K_solve', "specify" : 'K_specify', "specparam" : 'K_specparam', "split" : 'K_split', "sqrt" : 'K_sqrt', "static" : 'K_static', # This is defined by both SystemVerilog 1800-2005 and Verilog-AMS 2.3', "string" : 'K_string', "strong" : 'K_strong', "strong0" : 'K_strong0', "strong1" : 'K_strong1', "struct" : 'K_struct', "super" : 'K_super', "supply0" : 'K_supply0', "supply1" : 'K_supply1', "sync_accept_on" : 'K_sync_accept_on', "sync_reject_on" : 'K_sync_reject_on', "table" : 'K_table', "tagged" : 'K_tagged', "tan" : 'K_tan', "tanh" : 'K_tanh', "task" : 'K_task', "this" : 'K_this', "throughout" : 'K_throughout', "time" : 'K_time', "timeprecision" : 'K_timeprecision', "timer" : 'K_timer', "timeunit" : 'K_timeunit', "tran" : 'K_tran', "tranif0" : 'K_tranif0', "tranif1" : 'K_tranif1', "transition" : 'K_transition', "tri" : 'K_tri', "tri0" : 'K_tri0', "tri1" : 'K_tri1', "triand" : 'K_triand', "trior" : 'K_trior', "trireg" : 'K_trireg', "type" : 'K_type', "typedef" : 'K_typedef', "union" : 'K_union', "unique" : 'K_unique', "unique0" : 'K_unique', "units" : 'K_units', # Reserved for future use!', "unsigned" : 'K_unsigned', "until" : 'K_until', "until_with" : 'K_until_with', "untyped" : 'K_untyped', "use" : 'K_use', "uwire" : 'K_uwire', "var" : 'K_var', "vectored" : 'K_vectored', "virtual" : 'K_virtual', "void" : 'K_void', "wait" : 'K_wait', "wait_order" : 'K_wait_order', "wand" : 'K_wand', "weak" : 'K_weak', "weak0" : 'K_weak0', "weak1" : 'K_weak1', "while" : 'K_while', "white_noise" : 'K_white_noise', "wildcard" : 'K_wildcard', "wire" : 'K_wire', "with" : 'K_with', "within" : 'K_within', # This is the name originally proposed for uwire and is deprecated!', "wone" : 'K_wone', "wor" : 'K_wor', # This is defined by Verilog-AMS 2.3 and as an Icarus extension.', "wreal" : 'K_wreal', "xnor" : 'K_xnor', "xor" : 'K_xor', "zi_nd" : 'K_zi_nd', "zi_np" : 'K_zi_np', "zi_zd" : 'K_zi_zd', "zi_zp" : 'K_zi_zp', } literals = ['[', '}', '{', ';', ':', '[', ']', ',', '(', ')', '#', '=', '.', '@', '&', '!', '?', '<', '>', '%', '|', '^', '~', '+', '*', '/', '-'] """ def t_module_end(t): r'endmodule' code = t.lexer.lexdata[t.modulestart:t.lexpos] t.type = 'INITIAL' t.value = code t.lexer.lineno += t.value.count('\n') return t t_module_ignore = ' \t' """ def t_LITERAL(t): r'[a-zA-Z_$][a-zA-Z0-9$_]*' word = t.value keyword = lexor_keyword_code.get(t.value, 'IDENTIFIER') if(lex_debug): print("literal", word, keyword) # if keyword in ['K_module', 'K_macromodule']: # t.lexer.modulestart = t.lexpos+len(t.value) # t.lexer.begin('module') if keyword == 'IDENTIFIER': t.type = 'IDENTIFIER' t.value = word return t t.type = keyword return t def t_dec_number(t): r'\'[sS]?[dD][ \t]*[0-9][0-9_]*' t.type = 'BASED_NUMBER' # t.value = word # make_unsized_dec(yytext); return t def t_undef_highz_dec(t): r'\'[sS]?[dD][ \t]*[xzXZ?]_*' t.type = 'BASED_NUMBER' # t.value = word # make_undef_highz_dec(yytext); return t def t_based_make_unsized_binary(t): r'\'[sS]?[bB][ \t]*[0-1xzXZ?][0-1xzXZ?_]*' t.type = 'BASED_NUMBER' # t.value = word # make_unsized_binary(yytext); return t def t_make_unsized_octal(t): r'\'[sS]?[oO][ \t]*[0-7xzXZ?][0-7xzXZ?_]*' t.type = 'BASED_NUMBER' # t.value = word # make_unsized_octal(yytext); return t def t_make_unsized_hex(t): r'\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ?][0-9a-fA-FxzXZ?_]*' t.type = 'BASED_NUMBER' # t.value = word # make_unsized_hex(yytext); return t def t_unbased_make_unsized_binary(t): r'\'[01xzXZ]' t.type = 'UNBASED_NUMBER' # t.value = word # make_unsized_binary(yytext); return t """ /* Decimal numbers are the usual. But watch out for the UDPTABLE mode, where there are no decimal numbers. Reject the match if we are in the UDPTABLE state. */ """ def t_make_unsized_dec(t): r'[0-9][0-9_]*' t.type = 'DEC_NUMBER' # t.value = word # make_unsized_dec(yytext); # based_size = yylval.number->as_ulong(); return t """ /* Notice and handle the `timescale directive. */ """ def t_timescale(t): # r'^{W}?`timescale' r'`timescale' t.lexer.timestart = t.lexpos+len(t.value) t.lexer.push_state('timescale') #t_timescale_ignore_toeol = r'.+\n' t_timescale_ignore = ' \t' #t_timescale_ignore_whitespace = r'\s+' #t_code_ignore = "" def t_timescale_end(t): r'.+\n' code = t.lexer.lexdata[t.lexer.timestart:t.lexpos] t.type = 'timescale' t.value = code t.lexer.pop_state() print("match", code) return t def t_timescale_error(t): print("%d: Timescale error '%s'" % (t.lexer.lineno, t.value[0])) print(t.value) raise RuntimeError """ def t_module_error(t): print("%d: Module error '%s'" % (t.lexer.lineno, t.value[0])) print(t.value) raise RuntimeError """ def t_error(t): print("%d: Illegal character '%s'" % (t.lexer.lineno, t.value[0])) print(t.value) t.lexer.skip(1) tokens = list(set(tokens)) lex.lex() if __name__ == '__main__': lex.runmain()