'use strict'; const PREC = { PARENT: 37, // () [] :: . Left Highest UNARY: 36, // + - ! ~ & ~& | ~| ^ ~^ ^~ ++ -- (unary) POW: 35, // ** Left MUL: 34, // * / % Left ADD: 33, // + - (binary) Left SHIFT: 32, // << >> <<< >>> Left RELATIONAL: 31, // < <= > >= inside dist Left EQUAL: 30, // == != === !== ==? !=? Left AND: 29, // & (binary) Left XOR: 28, // ^ ~^ ^~ (binary) Left OR: 27, // | (binary) Left // The matches operator shall have higher precedence than the && and || operators MATCHES: 26, LOGICAL_AND: 25, // && Left LOGICAL_OR: 24, // || Left CONDITIONAL: 23, // ?: (conditional operator) Right IMPLICATION: 22, // –> <–> Right ASSIGN: 21, // = += -= *= /= %= &= ^= |= <<= >>= <<<= >>>= := :/ <= None CONCAT: 20, // {} {{}} Concatenation Lowest SPARENT: 19, // [* ] [= ] [-> ] SHARP2: 18, // ## Left throughout: 17, // throughout Right within: 16, // within Left intersect: 15, // intersect Left nexttime: 14, // not, nexttime, s_nexttime and: 13, // and Left or: 12, // or Left iff: 11, // iff Right until: 10, // until, s_until, until_with, s_until_with, implies Right INCIDENCE: 9, // |->, |=>, #-#, #=# Right always: 8 // always, s_always, eventually, s_eventually, — // if-else, case , accept_on, reject_on, // sync_accept_on, sync_reject_on }; function optseq() { return optional(prec.left(seq.apply(null, arguments))); } function repseq() { return repeat(prec.left(seq.apply(null, arguments))); } function commaSep(rule) { return optional(sep1(',', rule)); } function commaSep1(rule) { return seq(rule, repseq(',', rule)); } function sep1(separator, rule) { return prec.left(seq( rule, repeat(prec.left(seq(separator, rule))) )); } function psep1(precedence, separator, rule) { return prec.left(precedence, seq( rule, repeat(prec.left(seq(separator, rule))) )); } function exprOp ($, prior, ops) { return prec.left(prior, seq($.expression, ops, repeat($.attribute_instance), $.expression)); } function constExprOp ($, prior, ops) { return prec.left(prior, seq($.constant_expression, ops, repeat($.attribute_instance), $.constant_expression)); } function directive (command) { return alias(new RegExp('`' + command), 'directive_' + command); } function combi (arr) { const len = arr.length; const len2 = Math.pow(2, len); const res = []; for (let i = 3; i <= len2; i++) { const e = []; for (let j = 0; j < len; j++) { if ((i >> j) & 1) { e.push(arr[j]); } } res.push(e); } return res; } /* Verilog parser grammar based on IEEE Std 1800-2017. */ const rules = { source_file: $ => repeat($._description), /* 22. Compiler directives */ /* 22-1 `include */ double_quoted_string: $ => seq( '"', token.immediate(prec(1, /[^\\"\n]+/)), '"' ), include_compiler_directive_standard: $ => seq( '<', token.immediate(prec(1, /[^\\>\n]+/)), '>' ), include_compiler_directive: $ => seq( directive('include'), choice( $.double_quoted_string, $.include_compiler_directive_standard ) ), /* 22-2 `define */ default_text: $ => /\w+/, macro_text: $ => /(\\(.|\r?\n)|[^\\\n])*/, text_macro_name: $ => seq( $.text_macro_identifier, optseq('(', $.list_of_formal_arguments, ')') ), list_of_formal_arguments: $ => sep1(',', $.formal_argument), formal_argument: $ => seq( $.simple_identifier, optseq('=', $.default_text) ), text_macro_identifier: $ => $._identifier, /* 22-5 define */ text_macro_definition: $ => seq( directive('define'), $.text_macro_name, optional($.macro_text), '\n' ), /* 22-3 usage */ text_macro_usage: $ => seq( '`', $.text_macro_identifier, optseq('(', $.list_of_actual_arguments, ')') ), simple_text_macro_usage: $ => seq( '`', $.text_macro_identifier ), /* 22-4 22-5 */ id_directive: $ => seq( choice( directive('ifdef'), directive('ifndef'), directive('elsif'), directive('undef') /* 22-5-2 */ ), $.text_macro_identifier ), zero_directive: $ => choice( directive('resetall'), /* 22-3 */ directive('undefineall'), /* 22-5-3 */ directive('endif'), directive('else'), directive('nounconnected_drive'), directive('celldefine'), /* 22-10 */ directive('endcelldefine'), directive('end_keywords') /* 22.14 */ ), /* 22-7 timescale */ timescale_compiler_directive: $ => seq( directive('timescale'), $.time_literal, // time_unit, '/', $.time_literal, // time_precision '\n' ), /* 22-8 default_nettype */ default_nettype_compiler_directive: $ => seq( directive('default_nettype'), $.default_nettype_value, '\n' ), default_nettype_value: $ => choice('wire', 'tri', 'tri0', 'tri1', 'wand', 'triand', 'wor', 'trior', 'trireg', 'uwire', 'none'), /* 22-9 */ unconnected_drive: $ => seq( directive('unconnected_drive'), choice('pull0', 'pull1'), '\n' ), /* 22-12 */ line_compiler_directive: $ => seq( directive('line'), $.unsigned_number, $.double_quoted_string, $.unsigned_number, '\n' ), /* 22.13 */ /* `__FILE__ and `__LINE__ */ /* 22.14 */ begin_keywords: $ => seq( directive('begin_keywords'), $.double_quoted_string ), _directives: $ => choice( $.line_compiler_directive, $.include_compiler_directive, $.text_macro_definition, $.text_macro_usage, $.id_directive, $.zero_directive, $.timescale_compiler_directive, $.default_nettype_compiler_directive, $.unconnected_drive, $.begin_keywords ), // TODO missing arguments, empty list of arguments list_of_actual_arguments: $ => sep1(',', $._actual_argument), _actual_argument: $ => $.expression, /* A.1.1 Library source text */ // library_text: $ => repeat($.library_description), // library_description: $ => choice( // $.library_declaration, // $.include_statement, // $.config_declaration, // ';' // ), // // library_declaration: $ => seq( // 'library', // $.library_identifier, // sep1(',', $.file_path_spec), // optseq('-incdir', sep1(',', $.file_path_spec)), // ';' // ), // // include_statement: $ => seq('include', $.file_path_spec, ';'), /* A.1.2 SystemVerilog source text */ _description: $ => choice( $._directives, $.module_declaration, $.udp_declaration, $.interface_declaration, $.program_declaration, $.package_declaration, seq(repeat($.attribute_instance), $._package_item), seq(repeat($.attribute_instance), $.bind_directive) // $.config_declaration, ), // module_nonansi_header: $ => // { attribute_instance } module_keyword [ lifetime ] _module_identifier // { package_import_declaration } [ parameter_port_list ] list_of_ports ';' // // module_ansi_header: $ => // { attribute_instance } module_keyword [ lifetime ] _module_identifier // { package_import_declaration } [ parameter_port_list ] [ list_of_port_declarations ] ';' // // module_declaration: $ => // module_nonansi_header [ timeunits_declaration ] { module_item } // 'endmodule' [ ':' _module_identifier ] // | module_ansi_header [ timeunits_declaration ] { non_port_module_item } // 'endmodule' [ ':' _module_identifier ] // | { attribute_instance } module_keyword [ lifetime ] _module_identifier '(' '.*' ')' ';' // [ timeunits_declaration ] { module_item } 'endmodule' [ ':' _module_identifier ] // | 'extern' module_nonansi_header // | 'extern' module_ansi_header module_header: $ => seq( repeat($.attribute_instance), $.module_keyword, optional($.lifetime), $._module_identifier ), module_nonansi_header: $ => seq( repeat($.package_import_declaration), optional($.parameter_port_list), $.list_of_ports ), module_ansi_header: $ => seq( repeat($.package_import_declaration), choice( seq($.parameter_port_list, optional($.list_of_port_declarations)), $.list_of_port_declarations ) ), module_declaration: $ => choice( seq( $.module_header, optional(choice( $.module_nonansi_header, $.module_ansi_header, seq('(', '.*', ')') )), ';', optional($.timeunits_declaration), repeat($._module_item), 'endmodule', optseq(':', $._module_identifier) ), seq('extern', $.module_header, choice( $.module_nonansi_header, $.module_ansi_header )) ), module_keyword: $ => choice('module', 'macromodule'), interface_declaration: $ => choice( seq( $.interface_nonansi_header, optional($.timeunits_declaration), repeat($.interface_item), 'endinterface', optseq(':', $.interface_identifier) ), seq( $.interface_ansi_header, optional($.timeunits_declaration), repeat($._non_port_interface_item), 'endinterface', optseq(':', $.interface_identifier) ), seq( repeat($.attribute_instance), 'interface', $.interface_identifier, '(', '.*', ')', ';', optional($.timeunits_declaration), repeat($.interface_item), 'endinterface', optseq(':', $.interface_identifier) ), seq('extern', $.interface_nonansi_header), seq('extern', $.interface_ansi_header) ), interface_nonansi_header: $ => seq( repeat($.attribute_instance), 'interface', optional($.lifetime), $.interface_identifier, repeat($.package_import_declaration), optional($.parameter_port_list), $.list_of_ports, ';' ), interface_ansi_header: $ => seq( repeat($.attribute_instance), 'interface', optional($.lifetime), $.interface_identifier, repeat($.package_import_declaration), optional($.parameter_port_list), optional($.list_of_port_declarations), ';' ), program_declaration: $ => choice( seq( $.program_nonansi_header, optional($.timeunits_declaration), repeat($.program_item), 'endprogram', optseq(':', $.program_identifier) ), seq( $.program_ansi_header, optional($.timeunits_declaration), repeat($.non_port_program_item), 'endprogram', optseq(':', $.program_identifier) ), seq( repeat($.attribute_instance), 'program', $.program_identifier, '(', '.*', ')', ';', optional($.timeunits_declaration), repeat($.program_item), 'endprogram', optseq(':', $.program_identifier) ), seq('extern', $.program_nonansi_header), seq('extern', $.program_ansi_header) ), program_nonansi_header: $ => seq( repeat($.attribute_instance), 'program', optional($.lifetime), $.program_identifier, repeat($.package_import_declaration), optional($.parameter_port_list), $.list_of_ports, ';' ), program_ansi_header: $ => seq( repeat($.attribute_instance), 'program', optional($.lifetime), $.program_identifier, repeat($.package_import_declaration), optional($.parameter_port_list), optional($.list_of_port_declarations), ';' ), checker_declaration: $ => seq( 'checker', $.checker_identifier, optseq('(', optional($.checker_port_list), ')'), ';', repseq( repeat($.attribute_instance), $._checker_or_generate_item ), 'endchecker', optseq(':', $.checker_identifier) ), class_declaration: $ => seq( optional('virtual'), 'class', optional($.lifetime), $.class_identifier, optional($.parameter_port_list), optseq( 'extends', $.class_type, optional($.list_of_arguments_parent) ), optseq( 'implements', sep1(',', $.interface_class_type) ), ';', repeat($.class_item), 'endclass', optseq(':', $.class_identifier) ), interface_class_type: $ => seq( $.ps_class_identifier, optional($.parameter_value_assignment) ), interface_class_declaration: $ => seq( 'interface', 'class', $.class_identifier, optional($.parameter_port_list), optseq( 'extends', optional(sep1(',', $.interface_class_type)), ';' ), repeat($.interface_class_item), 'endclass', optseq(':', $.class_identifier) ), interface_class_item: $ => choice( $.type_declaration, seq(repeat($.attribute_instance), $.interface_class_method), seq($._any_parameter_declaration, ';'), ';' ), interface_class_method: $ => seq('pure', 'virtual', $._method_prototype, ';'), package_declaration: $ => seq( repeat($.attribute_instance), 'package', optional($.lifetime), $.package_identifier, ';', optional($.timeunits_declaration), repseq(repeat($.attribute_instance), $._package_item), 'endpackage', optseq(':', $.package_identifier) ), timeunits_declaration: $ => choice( prec.left(seq('timeunit', $.time_literal, optseq('/', $.time_literal), ';')), prec.left(seq('timeprecision', $.time_literal, ';')), prec.left(seq('timeunit', $.time_literal, ';', 'timeprecision', $.time_literal, ';')), prec.left(seq('timeprecision', $.time_literal, ';', 'timeunit', $.time_literal, ';')) ), /* A.1.3 Module parameters and ports */ parameter_port_list: $ => seq( '#', '(', optional(choice( seq($.list_of_param_assignments, repseq(',', $.parameter_port_declaration)), sep1(',', $.parameter_port_declaration) )), ')' ), parameter_port_declaration: $ => choice( $._any_parameter_declaration, seq($.data_type, $.list_of_param_assignments), seq('type', $.list_of_type_assignments) ), list_of_ports: $ => seq( '(', optional(sep1(',', seq( optional($.line_compiler_directive), $.port, optional($.line_compiler_directive) ))), ')' ), list_of_port_declarations: $ => seq( '(', optional(sep1(',', seq( repeat($.attribute_instance), $.ansi_port_declaration ))), ')' ), port_declaration: $ => seq( repeat($.attribute_instance), choice( $.inout_declaration, $.input_declaration, $.output_declaration, $.ref_declaration, $.interface_port_declaration ) ), port: $ => choice( $._port_expression, seq('.', $.port_identifier, '(', optional($._port_expression), ')') ), _port_expression: $ => choice( $.port_reference, seq('{', sep1(',', $.port_reference), '}') ), port_reference: $ => seq( $.port_identifier, optional($.constant_select1) ), port_direction: $ => choice('input', 'output', 'inout', 'ref'), net_port_header1: $ => choice( seq(optional($.port_direction), $.net_port_type1), $.port_direction ), variable_port_header: $ => seq( optional($.port_direction), $._variable_port_type ), interface_port_header: $ => seq( choice( $.interface_identifier, 'interface' ), optseq('.', $.modport_identifier) ), ansi_port_declaration: $ => choice( seq( optional(choice($.net_port_header1, $.interface_port_header)), $.port_identifier, repeat($.unpacked_dimension), optseq('=', $.constant_expression) ), seq( optional($.variable_port_header), $.port_identifier, repeat($._variable_dimension), optseq('=', $.constant_expression) ), seq( optional($.port_direction), '.', $.port_identifier, '(', optional($.expression), ')' ) ), /* A.1.4 Module items */ elaboration_system_task: $ => choice( seq( '$fatal', optseq( '(', $.finish_number, optseq(',', $.list_of_arguments), ')' ), ';' ), seq( choice('$error', '$warning', '$info'), optional($.list_of_arguments_parent), ';' ) ), finish_number: $ => choice('0', '1', '2'), _module_common_item: $ => choice( $._module_or_generate_item_declaration, $.interface_instantiation, $.program_instantiation, $._assertion_item, $.bind_directive, $.continuous_assign, $.net_alias, $.initial_construct, $.final_construct, $.always_construct, $.loop_generate_construct, $._conditional_generate_construct, $.elaboration_system_task ), _module_item: $ => choice( seq($.port_declaration, ';'), $._non_port_module_item ), module_or_generate_item: $ => seq( repeat($.attribute_instance), choice( $.parameter_override, $.gate_instantiation, $.udp_instantiation, $.module_instantiation, $._module_common_item ) ), _module_or_generate_item_declaration: $ => choice( $.package_or_generate_item_declaration, $.genvar_declaration, $.clocking_declaration, seq('default', 'clocking', $.clocking_identifier, ';'), seq('default', 'disable', 'iff', $.expression_or_dist, ';') ), _non_port_module_item: $ => choice( $._directives, $.generate_region, $.module_or_generate_item, $.specify_block, seq(repeat($.attribute_instance), $.specparam_declaration), $.program_declaration, $.module_declaration, $.interface_declaration, $.timeunits_declaration ), parameter_override: $ => seq( 'defparam', $.list_of_defparam_assignments, ';' ), bind_directive: $ => seq( 'bind', choice( seq( $.bind_target_scope, optseq(':', $.bind_target_instance_list) ), $.bind_target_instance ), $._bind_instantiation, ';' ), bind_target_scope: $ => choice( $._module_identifier // $.interface_identifier ), bind_target_instance: $ => seq( $.hierarchical_identifier, optional($.constant_bit_select1) ), bind_target_instance_list: $ => sep1(',', $.bind_target_instance), _bind_instantiation: $ => choice( $.program_instantiation, $.module_instantiation, $.interface_instantiation, $.checker_instantiation ), /* A.1.5 Configuration source text */ config_declaration: $ => seq( 'config', $.config_identifier, ';', repseq($.local_parameter_declaration, ';'), $.design_statement, repeat($.config_rule_statement), 'endconfig', optseq(':', $.config_identifier) ), design_statement: $ => seq( 'design', repseq( optseq($.library_identifier, '.'), $.cell_identifier ), ';' ), config_rule_statement: $ => choice( seq($.default_clause, $.liblist_clause, ';'), seq($.inst_clause, $.liblist_clause, ';'), seq($.inst_clause, $.use_clause, ';'), seq($.cell_clause, $.liblist_clause, ';'), seq($.cell_clause, $.use_clause, ';') ), default_clause: $ => 'default', inst_clause: $ => seq('instance', $.inst_name), inst_name: $ => seq($.topmodule_identifier, repseq('.', $.instance_identifier)), cell_clause: $ => seq('cell', optseq($.library_identifier, '.'), $.cell_identifier), liblist_clause: $ => seq('liblist', repeat($.library_identifier)), use_clause: $ => seq( 'use', choice( sep1(',', $.named_parameter_assignment), seq( optseq($.library_identifier, '.'), $.cell_identifier, optional(sep1(',', $.named_parameter_assignment)) ) ), optseq(':', 'config') ), /* A.1.6 Interface items */ interface_or_generate_item: $ => choice( seq(repeat($.attribute_instance), $._module_common_item), seq(repeat($.attribute_instance), $.extern_tf_declaration) ), extern_tf_declaration: $ => choice( seq('extern', $._method_prototype, ';'), seq('extern', 'forkjoin', $.task_prototype, ';') ), interface_item: $ => choice( seq($.port_declaration, ';'), $._non_port_interface_item ), _non_port_interface_item: $ => choice( $.generate_region, $.interface_or_generate_item, $.program_declaration, $.modport_declaration, $.interface_declaration, $.timeunits_declaration ), /* A.1.7 Program items */ program_item: $ => choice( seq($.port_declaration, ';'), $.non_port_program_item ), non_port_program_item: $ => choice( seq(repeat($.attribute_instance), $.continuous_assign), seq(repeat($.attribute_instance), $._module_or_generate_item_declaration), seq(repeat($.attribute_instance), $.initial_construct), seq(repeat($.attribute_instance), $.final_construct), seq(repeat($.attribute_instance), $.concurrent_assertion_item), $.timeunits_declaration, $._program_generate_item ), _program_generate_item: $ => choice( $.loop_generate_construct, $._conditional_generate_construct, $.generate_region, $.elaboration_system_task ), /* A.1.8 Checker items */ checker_port_list: $ => sep1(',', $.checker_port_item), checker_port_item: $ => seq( repeat($.attribute_instance), optional($.checker_port_direction), optional($.property_formal_type1), $.formal_port_identifier, repeat($._variable_dimension), optseq('=', $._property_actual_arg) ), checker_port_direction: $ => choice('input', 'output'), _checker_or_generate_item: $ => choice( $.checker_or_generate_item_declaration, $.initial_construct, $.always_construct, $.final_construct, $._assertion_item, $.continuous_assign, $._checker_generate_item ), checker_or_generate_item_declaration: $ => choice( seq(optional('rand'), $.data_declaration), $.function_declaration, $.checker_declaration, $._assertion_item_declaration, $.covergroup_declaration, $.genvar_declaration, $.clocking_declaration, seq('default', 'clocking', $.clocking_identifier, ';'), prec.right(PREC.iff, seq('default', 'disable', 'iff', $.expression_or_dist, ';')), ';' ), _checker_generate_item: $ => choice( $.loop_generate_construct, $._conditional_generate_construct, $.generate_region, $.elaboration_system_task ), /* A.1.9 Class items */ class_item: $ => choice( $._directives, seq(repeat($.attribute_instance), $.class_property), seq(repeat($.attribute_instance), $.class_method), seq(repeat($.attribute_instance), $._class_constraint), seq(repeat($.attribute_instance), $.class_declaration), seq(repeat($.attribute_instance), $.covergroup_declaration), seq($._any_parameter_declaration, ';'), ';' ), class_property: $ => choice( seq(repeat($._property_qualifier), $.data_declaration), seq( 'const', repeat($.class_item_qualifier), $.data_type, $.const_identifier, optseq('=', $.constant_expression), ';' ) ), class_method: $ => choice( seq(repeat($.method_qualifier), $.task_declaration), seq(repeat($.method_qualifier), $.function_declaration), seq('pure', 'virtual', repeat($.class_item_qualifier), $._method_prototype, ';'), seq('extern', repeat($.method_qualifier), $._method_prototype, ';'), seq(repeat($.method_qualifier), $.class_constructor_declaration), seq('extern', repeat($.method_qualifier), $.class_constructor_prototype) ), class_constructor_prototype: $ => seq( 'function', 'new', optseq('(', optional($.tf_port_list), ')'), ';' ), _class_constraint: $ => choice( $.constraint_prototype, $.constraint_declaration ), class_item_qualifier: $ => choice('static', 'protected', 'local'), _property_qualifier: $ => choice( $.random_qualifier, $.class_item_qualifier ), random_qualifier: $ => choice('rand', 'randc'), method_qualifier: $ => choice( seq(optional('pure'), 'virtual'), $.class_item_qualifier ), _method_prototype: $ => choice( $.task_prototype, $.function_prototype ), class_constructor_declaration: $ => seq( 'function', optional($.class_scope), 'new', optseq('(', optional($.tf_port_list), ')'), ';', repeat($.block_item_declaration), optseq( 'super', '.', 'new', optional($.list_of_arguments_parent), ';' ), repeat($.function_statement_or_null), 'endfunction', optseq(':', 'new') ), /* A.1.10 Constraints */ constraint_declaration: $ => seq( optional('static'), 'constraint', $.constraint_identifier, $.constraint_block ), constraint_block: $ => seq('{', repeat($.constraint_block_item), '}'), constraint_block_item: $ => choice( seq('solve', $.solve_before_list, 'before', $.solve_before_list, ';'), $.constraint_expression ), solve_before_list: $ => sep1(',', $.constraint_primary), constraint_primary: $ => seq( optional(choice( seq($.implicit_class_handle, '.'), $.class_scope )), $.hierarchical_identifier, optional($.select1) ), constraint_expression: $ => choice( seq(optional('soft'), $.expression_or_dist, ';'), seq($.uniqueness_constraint, ';'), prec.right(PREC.IMPLICATION, seq($.expression, '–>', $.constraint_set)), prec.left(seq( 'if', '(', $.expression, ')', $.constraint_set, optseq('else', $.constraint_set) )), seq( 'foreach', '(', $.ps_or_hierarchical_array_identifier, '[', optional($.loop_variables1), ']', ')', $.constraint_set ), seq('disable', 'soft', $.constraint_primary, ';') ), uniqueness_constraint: $ => seq( 'unique', '{', $.open_range_list, '}' ), constraint_set: $ => choice( $.constraint_expression, seq('{', repeat($.constraint_expression), '}') ), dist_list: $ => sep1(',', $.dist_item), dist_item: $ => seq($.value_range, optional($.dist_weight)), dist_weight: $ => seq(choice(':=', ':/'), $.expression), constraint_prototype: $ => seq( optional($.constraint_prototype_qualifier), optional('static'), 'constraint', $.constraint_identifier, ';' ), constraint_prototype_qualifier: $ => choice('extern', 'pure'), extern_constraint_declaration: $ => seq( optional('static'), 'constraint', $.class_scope, $.constraint_identifier, $.constraint_block ), identifier_list: $ => sep1(',', $._identifier), /* A.1.11 Package items */ _package_item: $ => choice( $.package_or_generate_item_declaration, $.anonymous_program, $.package_export_declaration, $.timeunits_declaration ), package_or_generate_item_declaration: $ => choice( $.net_declaration, $.data_declaration, $.task_declaration, $.function_declaration, $.checker_declaration, $.dpi_import_export, $.extern_constraint_declaration, $.class_declaration, $.interface_class_declaration, // not in spec $.class_constructor_declaration, seq($._any_parameter_declaration, ';'), $.covergroup_declaration, $.overload_declaration, $._assertion_item_declaration, ';' ), anonymous_program: $ => seq( 'program', ';', repeat($.anonymous_program_item), 'endprogram' ), anonymous_program_item: $ => choice( $.task_declaration, $.function_declaration, $.class_declaration, $.covergroup_declaration, $.class_constructor_declaration, ';' ), /* A.2 Declarations */ /* A.2.1 Declaration types */ /* A.2.1.1 Module parameter declarations */ local_parameter_declaration: $ => seq( 'localparam', choice( seq( optional($.data_type_or_implicit1), $.list_of_param_assignments ), seq('type', $.list_of_type_assignments) ) ), parameter_declaration: $ => seq( 'parameter', choice( seq( optional($.data_type_or_implicit1), $.list_of_param_assignments ), seq('type', $.list_of_type_assignments) ) ), _any_parameter_declaration: $ => choice( $.local_parameter_declaration, $.parameter_declaration ), specparam_declaration: $ => seq( 'specparam', optional($.packed_dimension), $.list_of_specparam_assignments, ';' ), /* A.2.1.2 Port declarations */ inout_declaration: $ => seq( 'inout', optional($.net_port_type1), $.list_of_port_identifiers ), input_declaration: $ => seq( 'input', choice( seq(optional($.net_port_type1), $.list_of_port_identifiers), seq(optional($._variable_port_type), $.list_of_variable_identifiers) ) ), output_declaration: $ => seq( 'output', choice( seq(optional($.net_port_type1), $.list_of_port_identifiers), seq(optional($._variable_port_type), $.list_of_variable_port_identifiers) ) ), interface_port_declaration: $ => seq( $.interface_identifier, optseq('.', $.modport_identifier), $.list_of_interface_identifiers ), ref_declaration: $ => seq( 'ref', $._variable_port_type, $.list_of_variable_identifiers ), // A.2.1.3 Type declarations data_declaration: $ => choice( seq( optional('const'), optional('var'), optional($.lifetime), optional($.data_type_or_implicit1), $.list_of_variable_decl_assignments, ';' ), $.type_declaration, $.package_import_declaration, $.net_type_declaration ), package_import_declaration: $ => seq( 'import', sep1(',', $.package_import_item), ';' ), package_import_item: $ => seq( $.package_identifier, '::', choice($._identifier, '*') ), package_export_declaration: $ => seq( 'export', choice('*::*', sep1(',', $.package_import_item)), ';' ), genvar_declaration: $ => seq( 'genvar', $.list_of_genvar_identifiers, ';' ), net_declaration: $ => choice( seq( $.net_type, optional(choice($.drive_strength, $.charge_strength)), optional(choice('vectored', 'scalared')), optional($.data_type_or_implicit1), optional($.delay3), $.list_of_net_decl_assignments, ';' ), seq( $._net_type_identifier, optional($.delay_control), $.list_of_net_decl_assignments, ';' ), seq( 'interconnect', optional($.implicit_data_type1), optseq('#', $.delay_value), sep1(',', seq($._net_identifier, repeat($.unpacked_dimension))), ';' ) ), type_declaration: $ => seq( 'typedef', choice( seq($.data_type, $._type_identifier, repeat($._variable_dimension)), seq( $.interface_instance_identifier, optional($.constant_bit_select1), '.', $._type_identifier, $._type_identifier ), seq( optional(choice( 'enum', 'struct', 'union', 'class', seq('interface', 'class') )), $._type_identifier ) ), ';' ), net_type_declaration: $ => seq( 'nettype', choice( seq( $.data_type, $._net_type_identifier, optseq( 'with', optional(choice($.package_scope, $.class_scope)), $.tf_identifier ) ), seq( optional(choice($.package_scope, $.class_scope)), $._net_type_identifier, $._net_type_identifier ) ), ';' ), lifetime: $ => choice('static', 'automatic'), /* A.2.2 Declaration data types */ /* A.2.2.1 Net and variable types */ casting_type: $ => choice( $._simple_type, $.constant_primary, $._signing, 'string', 'const' ), data_type: $ => choice( seq($.integer_vector_type, optional($._signing), repeat($.packed_dimension)), seq($.integer_atom_type, optional($._signing)), $.non_integer_type, seq( $.struct_union, optseq('packed', optional($._signing)), '{', repeat1($.struct_union_member), '}', repeat($.packed_dimension) ), seq( 'enum', optional($.enum_base_type), '{', sep1(',', $.enum_name_declaration), '}', repeat($.packed_dimension) ), 'string', 'chandle', prec.left(seq( 'virtual', optional('interface'), $.interface_identifier, optional($.parameter_value_assignment), optseq('.', $.modport_identifier) )), seq( optional(choice($.class_scope, $.package_scope)), $._type_identifier, repeat($.packed_dimension) ), $.class_type, 'event', $.ps_covergroup_identifier, $.type_reference ), data_type_or_implicit1: $ => choice( $.data_type, $.implicit_data_type1 ), implicit_data_type1: $ => choice( // reordered : repeat -> repeat1 seq($._signing, repeat($.packed_dimension)), repeat1($.packed_dimension) ), enum_base_type: $ => choice( seq( $.integer_atom_type, optional($._signing) ), seq( $.integer_vector_type, optional($._signing), optional($.packed_dimension) ), seq( $._type_identifier, optional($.packed_dimension) ) ), enum_name_declaration: $ => seq( $.enum_identifier, optseq( '[', $.integral_number, optseq(':', $.integral_number), ']' ), optseq('=', $.constant_expression) ), class_scope: $ => seq($.class_type, '::'), // class_type: $ => prec.left(PREC.PARENT, seq( class_type: $ => prec.right(seq( $.ps_class_identifier, optional($.parameter_value_assignment), repseq( '::', $.class_identifier, optional($.parameter_value_assignment) ) )), _integer_type: $ => choice( $.integer_vector_type, $.integer_atom_type ), integer_atom_type: $ => choice('byte', 'shortint', 'int', 'longint', 'integer', 'time'), integer_vector_type: $ => choice('bit', 'logic', 'reg'), non_integer_type: $ => choice('shortreal', 'real', 'realtime'), net_type: $ => choice('supply0', 'supply1', 'tri', 'triand', 'trior', 'trireg', 'tri0', 'tri1', 'uwire', 'wire', 'wand', 'wor'), net_port_type1: $ => choice( prec.left(-1, seq($.net_type, $.data_type_or_implicit1)), $.net_type, $.data_type_or_implicit1, $._net_type_identifier, seq('interconnect', optional($.implicit_data_type1)) ), _variable_port_type: $ => $._var_data_type, _var_data_type: $ => prec.left(choice( $.data_type, seq('var', optional($.data_type_or_implicit1)) )), _signing: $ => choice('signed', 'unsigned'), _simple_type: $ => choice( $._integer_type, $.non_integer_type, $.ps_type_identifier, $.ps_parameter_identifier ), struct_union_member: $ => seq( repeat($.attribute_instance), optional($.random_qualifier), $.data_type_or_void, $.list_of_variable_decl_assignments, ';' ), data_type_or_void: $ => choice( $.data_type, 'void' ), struct_union: $ => choice( 'struct', seq('union', optional('tagged')) ), type_reference: $ => seq( 'type', '(', choice( $.expression, $.data_type ), ')' ), // A.2.2.2 Strengths drive_strength: $ => seq( '(', choice( seq($.strength0, ',', $.strength1), seq($.strength1, ',', $.strength0), seq($.strength0, ',', 'highz1'), seq($.strength1, ',', 'highz0'), seq('highz0', ',', $.strength1), seq('highz1', ',', $.strength0) ), ')' ), strength0: $ => choice('supply0', 'strong0', 'pull0', 'weak0'), strength1: $ => choice('supply1', 'strong1', 'pull1', 'weak1'), charge_strength: $ => seq('(', choice('small', 'medium', 'large'), ')'), // A.2.2.3 Delays delay3: $ => seq('#', choice( $.delay_value, seq( '(', $.mintypmax_expression, optseq($.mintypmax_expression, optional($.mintypmax_expression) ), ')' ) )), delay2: $ => seq('#', choice( $.delay_value, seq('(', $.mintypmax_expression, optional($.mintypmax_expression), ')') )), delay_value: $ => choice( $.unsigned_number, $.real_number, $.ps_identifier, $.time_literal, '1step' ), /* A.2.3 Declaration lists */ list_of_defparam_assignments: $ => sep1(',', $.defparam_assignment), list_of_genvar_identifiers: $ => sep1(',', $.genvar_identifier), list_of_interface_identifiers: $ => sep1(',', seq( $.interface_identifier, repeat($.unpacked_dimension) )), list_of_net_decl_assignments: $ => sep1(',', $.net_decl_assignment), list_of_param_assignments: $ => sep1(',', $.param_assignment), list_of_port_identifiers: $ => sep1(',', seq( $.port_identifier, repeat($.unpacked_dimension) )), list_of_udp_port_identifiers: $ => sep1(',', $.port_identifier), list_of_specparam_assignments: $ => sep1(',', $.specparam_assignment), list_of_tf_variable_identifiers: $ => sep1(',', seq( $.port_identifier, repeat($._variable_dimension), optseq('=', $.expression) )), list_of_type_assignments: $ => sep1(',', $.type_assignment), list_of_variable_decl_assignments: $ => sep1(',', $.variable_decl_assignment), list_of_variable_identifiers: $ => sep1(',', seq( $._variable_identifier, repeat($._variable_dimension) )), list_of_variable_port_identifiers: $ => sep1(',', seq( $.port_identifier, repeat($._variable_dimension), optseq('=', $.constant_expression) )), /* A.2.4 Declaration assignments */ defparam_assignment: $ => seq( $._hierarchical_parameter_identifier, '=', $.constant_mintypmax_expression ), net_decl_assignment: $ => prec.left(PREC.ASSIGN, seq( $._net_identifier, repeat($.unpacked_dimension), optseq('=', $.expression) )), param_assignment: $ => seq( $.parameter_identifier, repeat($.unpacked_dimension), optseq('=', $.constant_param_expression) ), specparam_assignment: $ => choice( seq($.specparam_identifier, '=', $.constant_mintypmax_expression), $.pulse_control_specparam ), type_assignment: $ => seq( $._type_identifier, optseq('=', $.data_type) ), pulse_control_specparam: $ => choice( seq( 'PATHPULSE$=', '(', $.reject_limit_value, optseq(',', $.error_limit_value), ')' ) // seq( // 'PATHPULSE$', // $.specify_input_terminal_descriptor, // '$', // $.specify_output_terminal_descriptor, // '=', '(', $.reject_limit_value, optseq(',', $.error_limit_value), ')' // ) ), error_limit_value: $ => $.limit_value, reject_limit_value: $ => $.limit_value, limit_value: $ => $.constant_mintypmax_expression, variable_decl_assignment: $ => choice( seq( $._variable_identifier, repeat($._variable_dimension), optseq('=', $.expression) ), seq( $.dynamic_array_variable_identifier, $.unsized_dimension, repeat($._variable_dimension), optseq('=', $.dynamic_array_new) ), seq( $.class_variable_identifier, optseq('=', $.class_new) ) ), class_new: $ => choice( seq( optional($.class_scope), 'new', optional($.list_of_arguments_parent) ), seq('new', $.expression) ), dynamic_array_new: $ => seq( 'new', '[', $.expression, ']', optseq('(', $.expression, ')') ), // A.2.5 Declaration ranges unpacked_dimension: $ => seq( '[', choice( $.constant_range, $.constant_expression ), ']' ), packed_dimension: $ => choice( seq('[', $.constant_range, ']'), $.unsized_dimension ), associative_dimension: $ => seq( '[', choice($.data_type, '*'), ']' ), _variable_dimension: $ => choice( $.unsized_dimension, $.unpacked_dimension, $.associative_dimension, $.queue_dimension ), queue_dimension: $ => seq( '[', '$', optseq(':', $.constant_expression), ']' ), unsized_dimension: $ => seq('[', ']'), // A.2.6 Function declarations function_data_type_or_implicit1: $ => choice( $.data_type_or_void, $.implicit_data_type1 ), function_declaration: $ => seq( 'function', optional($.lifetime), $.function_body_declaration ), function_body_declaration: $ => seq( optional($.function_data_type_or_implicit1), optional(choice( seq($.interface_identifier, '.'), $.class_scope )), $.function_identifier, choice( seq( ';', repeat($.tf_item_declaration) ), seq( '(', optional($.tf_port_list), ')', ';', repeat($.block_item_declaration) ) ), repeat($.function_statement_or_null), 'endfunction', optseq(':', $.function_identifier) ), function_prototype: $ => seq( 'function', $.data_type_or_void, $.function_identifier, optseq( '(', optional($.tf_port_list), ')' ) ), dpi_import_export: $ => choice( seq( 'import', $.dpi_spec_string, optional($.dpi_function_import_property), optseq($.c_identifier, '='), $.dpi_function_proto, ';' ), seq( 'import', $.dpi_spec_string, optional($.dpi_task_import_property), optseq($.c_identifier, '='), $.dpi_task_proto, ';' ), seq( 'export', $.dpi_spec_string, optseq($.c_identifier, '='), 'function', $.function_identifier, ';' ), seq( 'export', $.dpi_spec_string, optseq($.c_identifier, '='), 'task', $.task_identifier, ';' ) ), dpi_spec_string: $ => choice('"DPI-C"', '"DPI"'), dpi_function_import_property: $ => choice('context', 'pure'), dpi_task_import_property: $ => 'context', dpi_function_proto: $ => $.function_prototype, dpi_task_proto: $ => $.task_prototype, // A.2.7 Task declarations task_declaration: $ => seq( 'task', optional($.lifetime), $.task_body_declaration ), task_body_declaration: $ => seq( optional(choice( seq($.interface_identifier, '.'), $.class_scope )), $.task_identifier, choice( seq( ';', repeat($.tf_item_declaration) ), seq( '(', optional($.tf_port_list), ')', ';', repeat($.block_item_declaration) ) ), repeat($.statement_or_null), 'endtask', optseq(':', $.task_identifier) ), tf_item_declaration: $ => choice( $.block_item_declaration, $.tf_port_declaration ), tf_port_list: $ => sep1(',', $.tf_port_item1), tf_port_item1: $ => seq( repeat($.attribute_instance), optional($.tf_port_direction), optional('var'), choice( seq( $.data_type_or_implicit1, optseq( $.port_identifier, repeat($._variable_dimension), optseq('=', $.expression) ) ), seq( $.port_identifier, repeat($._variable_dimension), optseq('=', $.expression) ) ) ), tf_port_direction: $ => choice( $.port_direction, seq('const', 'ref') ), tf_port_declaration: $ => seq( repeat($.attribute_instance), $.tf_port_direction, optional('var'), optional($.data_type_or_implicit1), $.list_of_tf_variable_identifiers, ';' ), task_prototype: $ => seq( 'task', $.task_identifier, optseq('(', optional($.tf_port_list), ')') ), // A.2.8 Block item declarations block_item_declaration: $ => seq( repeat($.attribute_instance), choice( $.data_declaration, seq($._any_parameter_declaration, ';'), $.overload_declaration, $.let_declaration ) ), overload_declaration: $ => seq( 'bind', $.overload_operator, 'function', $.data_type, $.function_identifier, '(', $.overload_proto_formals, ')', ';' ), overload_operator: $ => choice('+', '++', '–', '––', '*', '**', '/', '%', '==', '!=', '<', '<=', '>', '>=', '='), overload_proto_formals: $ => sep1(',', $.data_type), /* A.2.9 Interface declarations */ modport_declaration: $ => seq('modport', sep1(',', $.modport_item), ';'), modport_item: $ => seq( $.modport_identifier, '(', sep1(',', $.modport_ports_declaration), ')' ), modport_ports_declaration: $ => seq( repeat($.attribute_instance), choice( $.modport_simple_ports_declaration, $.modport_tf_ports_declaration, $.modport_clocking_declaration ) ), modport_clocking_declaration: $ => seq('clocking', $.clocking_identifier), modport_simple_ports_declaration: $ => seq( $.port_direction, sep1(',', $.modport_simple_port) ), modport_simple_port: $ => choice( $.port_identifier, seq('.', $.port_identifier, '(', optional($.expression), ')') ), modport_tf_ports_declaration: $ => seq( $.import_export, sep1(',', $._modport_tf_port) ), _modport_tf_port: $ => choice( $._method_prototype, $.tf_identifier ), import_export: $ => choice('import', 'export'), // A.2.10 Assertion declarations concurrent_assertion_item: $ => choice( seq( optseq($._block_identifier, ':'), $._concurrent_assertion_statement ), $.checker_instantiation ), _concurrent_assertion_statement: $ => choice( $.assert_property_statement, $.assume_property_statement, $.cover_property_statement, $.cover_sequence_statement, $.restrict_property_statement ), assert_property_statement: $ => seq( 'assert', 'property', '(', $.property_spec, ')', $.action_block ), assume_property_statement: $ => seq( 'assume', 'property', '(', $.property_spec, ')', $.action_block ), cover_property_statement: $ => seq( 'cover', 'property', '(', $.property_spec, ')', $.statement_or_null ), expect_property_statement: $ => seq( 'expect', '(', $.property_spec, ')', $.action_block ), cover_sequence_statement: $ => seq( 'cover', 'sequence', '(', optional($.clocking_event), optional(prec.right(PREC.iff, seq( 'disable', 'iff', '(', $.expression_or_dist, ')' ))), $.sequence_expr, ')', $.statement_or_null ), restrict_property_statement: $ => seq( 'restrict', 'property', '(', $.property_spec, ')', ';' ), property_instance: $ => seq( $.ps_or_hierarchical_property_identifier, optseq('(', optional($.property_list_of_arguments), ')') ), property_list_of_arguments: $ => choice( seq( sep1(',', optional($._property_actual_arg)), repeat1(seq( // TODO remove 1 ',', '.', $._identifier, '(', optional($._property_actual_arg), ')' )) ), sep1(',', seq( '.', $._identifier, '(', optional($._property_actual_arg), ')' )) ), _property_actual_arg: $ => choice( $.property_expr, $._sequence_actual_arg ), _assertion_item_declaration: $ => choice( $.property_declaration, $.sequence_declaration, $.let_declaration ), property_declaration: $ => seq( 'property', $.property_identifier, optseq('(', optional($.property_port_list), ')'), ';', repeat($.assertion_variable_declaration), $.property_spec, optional(';'), 'endproperty', optseq(':', $.property_identifier) ), property_port_list: $ => sep1(',', $.property_port_item), property_port_item: $ => seq( repeat($.attribute_instance), optseq( 'local', optional($.property_lvar_port_direction) ), optional($.property_formal_type1), $.formal_port_identifier, repeat($._variable_dimension), optseq('=', $._property_actual_arg) ), property_lvar_port_direction: $ => 'input', property_formal_type1: $ => choice( $.sequence_formal_type1, 'property' ), property_spec: $ => seq( optional($.clocking_event), optional(prec.right(PREC.iff, seq( 'disable', 'iff', '(', $.expression_or_dist, ')' ))), $.property_expr ), property_expr: $ => choice( $.sequence_expr, seq('strong', '(', $.sequence_expr, ')'), seq('weak', '(', $.sequence_expr, ')'), prec.left(PREC.PARENT, seq('(', $.property_expr, ')')), // FIXME no assosiativity rules per spec prec.left(PREC.nexttime, seq('not', $.property_expr)), prec.left(PREC.or, seq($.property_expr, 'or', $.property_expr)), prec.left(PREC.and, seq($.property_expr, 'and', $.property_expr)), prec.right(PREC.INCIDENCE, seq($.sequence_expr, '|->', $.property_expr)), prec.right(PREC.INCIDENCE, seq($.sequence_expr, '|=>', $.property_expr)), // FIXME no assosiativity rules per spec prec.left(seq('if', '(', $.expression_or_dist, ')', $.property_expr, optseq('else', $.property_expr))), // FIXME spec bug ( ) are not red seq('case', '(', $.expression_or_dist, ')', repeat1($.property_case_item), 'endcase'), // FIXME spec bug ( ) are not red prec.right(PREC.INCIDENCE, seq($.sequence_expr, '#-#', $.property_expr)), prec.right(PREC.INCIDENCE, seq($.sequence_expr, '#=#', $.property_expr)), // FIXME no assosiativity rules per spec prec.left(PREC.nexttime, seq('nexttime', $.property_expr)), prec.left(PREC.nexttime, seq('nexttime', '[', $.constant_expression, ']', $.property_expr)), // FIXME spec bug constant _expression with the space prec.left(PREC.nexttime, seq('s_nexttime', $.property_expr)), prec.left(PREC.nexttime, seq('s_nexttime', '[', $.constant_expression, ']', $.property_expr)), prec.left(PREC.always, seq('always', $.property_expr)), prec.left(PREC.always, seq('always', '[', $.cycle_delay_const_range_expression, ']', $.property_expr)), prec.left(PREC.always, seq('s_always', '[', $.constant_range, ']', $.property_expr)), prec.left(PREC.always, seq('s_eventually', $.property_expr)), prec.left(PREC.always, seq('eventually', '[', $.constant_range, ']', $.property_expr)), prec.left(PREC.always, seq('s_eventually', '[', $.cycle_delay_const_range_expression, ']', $.property_expr)), prec.right(PREC.until, seq($.property_expr, choice('until', 's_until', 'until_with', 's_until_with', 'implies'), $.property_expr )), prec.right(PREC.iff, seq($.property_expr, 'iff', $.property_expr)), // FIXME no assosiativity rules per spec prec.left(PREC.always, seq( choice('accept_on', 'reject_on', 'sync_accept_on', 'sync_reject_on'), '(', $.expression_or_dist, ')', $.property_expr )), // $.property_instance, prec.left(seq($.clocking_event, $.property_expr)) // FIXME no assosiativity rules per spec ), property_case_item: $ => choice( seq( sep1(',', $.expression_or_dist), ':', $.property_expr, ';' ), seq( 'default', optional(':'), $.property_expr, ';' ) ), sequence_declaration: $ => seq( 'sequence', $._sequence_identifier, optseq( '(', optional($.sequence_port_list), ')' ), ';', repeat($.assertion_variable_declaration), $.sequence_expr, optional(';'), 'endsequence', optseq(':', $._sequence_identifier) ), sequence_port_list: $ => sep1(',', $.sequence_port_item), sequence_port_item: $ => seq( repeat($.attribute_instance), optseq( 'local', optional($.sequence_lvar_port_direction) ), optional($.sequence_formal_type1), $.formal_port_identifier, repeat($._variable_dimension), optseq( '=', $._sequence_actual_arg ) ), sequence_lvar_port_direction: $ => choice('input', 'inout', 'output'), sequence_formal_type1: $ => choice( $.data_type_or_implicit1, 'sequence', 'untyped' ), sequence_expr: $ => choice( prec.left(sep1(',', $.cycle_delay_range, $.sequence_expr)), // FIXME precedence? prec.left(PREC.SHARP2, seq($.sequence_expr, repeat1(seq($.cycle_delay_range, $.sequence_expr)))), seq($.expression_or_dist, optional($._boolean_abbrev)), seq($.sequence_instance, optional($.sequence_abbrev)), prec.left(seq('(', $.sequence_expr, repseq(',', $._sequence_match_item), ')', optional($.sequence_abbrev))), prec.left(PREC.and, seq($.sequence_expr, 'and', $.sequence_expr)), prec.left(PREC.intersect, seq($.sequence_expr, 'intersect', $.sequence_expr)), prec.left(PREC.or, seq($.sequence_expr, 'or', $.sequence_expr)), seq('first_match', '(', $.sequence_expr, repseq(',', $._sequence_match_item), ')'), prec.right(PREC.throughout, seq($.expression_or_dist, 'throughout', $.sequence_expr)), prec.left(PREC.within, seq($.sequence_expr, 'within', $.sequence_expr)), prec.left(seq($.clocking_event, $.sequence_expr)) // FIXME precedence? ), cycle_delay_range: $ => choice( prec.left(seq('##', $.constant_primary)), prec.left(seq('##', '[', $.cycle_delay_const_range_expression, ']')), '##[*]', '##[+]' ), sequence_method_call: $ => seq($.sequence_instance, '.', $.method_identifier), _sequence_match_item: $ => choice( $.operator_assignment, $.inc_or_dec_expression, $.subroutine_call ), sequence_instance: $ => seq( $.ps_or_hierarchical_sequence_identifier, optseq('(', optional($.sequence_list_of_arguments), ')') ), sequence_list_of_arguments: $ => choice( // seq( // sep1(',', optional($._sequence_actual_arg)), // repseq(',', '.', $._identifier, '(', optional($._sequence_actual_arg), ')') // ), sep1(',', seq('.', $._identifier, '(', optional($._sequence_actual_arg), ')')) ), _sequence_actual_arg: $ => choice( $.event_expression, $.sequence_expr ), _boolean_abbrev: $ => choice( $.consecutive_repetition, $.non_consecutive_repetition, $.goto_repetition ), sequence_abbrev: $ => $.consecutive_repetition, consecutive_repetition: $ => choice( seq('[*', $._const_or_range_expression, ']'), '[*]', '[+]' ), non_consecutive_repetition: $ => seq('[=', $._const_or_range_expression, ']'), goto_repetition: $ => seq('[->', $._const_or_range_expression, ']'), _const_or_range_expression: $ => choice( $.constant_expression, $.cycle_delay_const_range_expression ), cycle_delay_const_range_expression: $ => choice( seq($.constant_expression, ':', $.constant_expression), seq($.constant_expression, ':', '$') ), expression_or_dist: $ => seq( $.expression, optional(prec.left(PREC.RELATIONAL, seq('dist', '{', $.dist_list, '}'))) ), assertion_variable_declaration: $ => seq( $._var_data_type, $.list_of_variable_decl_assignments, ';' ), // A.2.11 Covergroup declarations covergroup_declaration: $ => seq( 'covergroup', $.covergroup_identifier, optseq('(', optional($.tf_port_list), ')'), optional($.coverage_event), ';', repeat($.coverage_spec_or_option), 'endgroup', optseq(':', $.covergroup_identifier) ), coverage_spec_or_option: $ => choice( seq(repeat($.attribute_instance), $._coverage_spec), seq(repeat($.attribute_instance), $.coverage_option, ';') ), coverage_option: $ => choice( seq('option', '.', $.member_identifier, '=', $.expression), seq('type_option', '.', $.member_identifier, '=', $.constant_expression) ), _coverage_spec: $ => choice($.cover_point, $.cover_cross), coverage_event: $ => choice( $.clocking_event, seq('with', 'function', 'sample', '(', optional($.tf_port_list), ')'), seq('@@', '(', $.block_event_expression, ')') ), block_event_expression: $ => choice( prec.left(PREC.or, seq($.block_event_expression, 'or', $.block_event_expression)), seq('begin', $.hierarchical_btf_identifier), seq('end', $.hierarchical_btf_identifier) ), hierarchical_btf_identifier: $ => choice( $._hierarchical_tf_identifier, $._hierarchical_block_identifier, prec.left(PREC.PARENT, seq( choice(seq($.hierarchical_identifier, '.'), $.class_scope), $.method_identifier )) ), cover_point: $ => seq( optseq(optional($.data_type_or_implicit1), $.cover_point_identifier, ':'), 'coverpoint', $.expression, optional(prec.right(PREC.iff, seq('iff', '(', $.expression, ')'))), $.bins_or_empty ), bins_or_empty: $ => choice( seq('{', repeat($.attribute_instance), repseq($.bins_or_options, ';'), '}'), ';' ), bins_or_options: $ => choice( $.coverage_option, seq( 'wildcard', $.bins_keyword, $._bin_identifier, optseq('[', optional($._covergroup_expression), ']'), '=', '{', $.covergroup_range_list, '}', optseq('with', '(', $._with_covergroup_expression, ')'), optional(prec.right(PREC.iff, seq('iff', '(', $.expression, ')'))) ), seq( 'wildcard', $.bins_keyword, $._bin_identifier, optseq('[', optional($._covergroup_expression), ']'), '=', $.cover_point_identifier, 'with', '(', $._with_covergroup_expression, ')', optional(prec.right(PREC.iff, seq('iff', '(', $.expression, ')'))) ), seq( 'wildcard', $.bins_keyword, $._bin_identifier, optseq('[', optional($._covergroup_expression), ']'), '=', $._set_covergroup_expression, optional(prec.right(PREC.iff, seq('iff', '(', $.expression, ')'))) ), seq( 'wildcard', $.bins_keyword, $._bin_identifier, optseq('[', ']'), '=', $.trans_list, optional(prec.right(PREC.iff, seq('iff', '(', $.expression, ')'))) ), seq( $.bins_keyword, $._bin_identifier, optseq('[', optional($._covergroup_expression), ']'), '=', 'default', optional(prec.right(PREC.iff, seq('iff', '(', $.expression, ')'))) ), seq( $.bins_keyword, $._bin_identifier, '=', 'default', 'sequence', optional(prec.right(PREC.iff, seq('iff', '(', $.expression, ')'))) ) ), bins_keyword: $ => choice('bins', 'illegal_bins', 'ignore_bins'), trans_list: $ => sep1(',', seq('(', $.trans_set, ')')), trans_set: $ => sep1('=>', $.trans_range_list), trans_range_list: $ => choice( $.trans_item, seq($.trans_item, '[*', $.repeat_range, ']'), seq($.trans_item, '[–>', $.repeat_range, ']'), seq($.trans_item, '[=', $.repeat_range, ']') ), trans_item: $ => $.covergroup_range_list, repeat_range: $ => seq( $._covergroup_expression, optseq(':', $._covergroup_expression) ), cover_cross: $ => seq( optseq($.cross_identifier, ':'), 'cross', $.list_of_cross_items, optional(prec.right(PREC.iff, seq('iff', '(', $.expression, ')'))), $.cross_body ), list_of_cross_items: $ => seq($._cross_item, ',', sep1(',', $._cross_item)), _cross_item: $ => choice( $.cover_point_identifier // $._variable_identifier ), cross_body: $ => choice( seq('{', repseq($.cross_body_item, ';'), '}'), ';' ), cross_body_item: $ => choice( $.function_declaration, // FIXME standard function_declaraton => function_declaration seq($.bins_selection_or_option, ';') ), bins_selection_or_option: $ => choice( seq(repeat($.attribute_instance), $.coverage_option), seq(repeat($.attribute_instance), $.bins_selection) ), bins_selection: $ => seq( $.bins_keyword, $._bin_identifier, '=', $.select_expression, optional(prec.right(PREC.iff, seq('iff', '(', $.expression, ')'))) ), select_expression: $ => choice( $.select_condition, prec.left(PREC.UNARY, seq('!', $.select_condition)), prec.left(PREC.LOGICAL_AND, seq($.select_expression, '&&', $.select_expression)), prec.left(PREC.LOGICAL_OR, seq($.select_expression, '||', $.select_expression)), prec.left(PREC.PARENT, seq('(', $.select_expression, ')')), seq( $.select_expression, 'with', '(', $._with_covergroup_expression, ')', optseq('matches', $._integer_covergroup_expression) ), $.cross_identifier, seq( $._cross_set_expression, optseq('matches', $._integer_covergroup_expression) ) ), select_condition: $ => seq( 'binsof', '(', $.bins_expression, ')', optseq('intersect', '{', $.covergroup_range_list, '}') ), bins_expression: $ => choice( $._variable_identifier, prec.left(PREC.PARENT, seq($.cover_point_identifier, optseq('.', $._bin_identifier))) ), covergroup_range_list: $ => sep1(',', $.covergroup_value_range), covergroup_value_range: $ => choice( $._covergroup_expression, seq('[', $._covergroup_expression, ':', $._covergroup_expression, ']') ), _with_covergroup_expression: $ => $._covergroup_expression, _set_covergroup_expression: $ => $._covergroup_expression, _integer_covergroup_expression: $ => $._covergroup_expression, _cross_set_expression: $ => $._covergroup_expression, _covergroup_expression: $ => $.expression, /* A.2.12 Let declarations */ let_declaration: $ => seq( 'let', $.let_identifier, optseq('(', optional($.let_port_list), ')'), '=', $.expression, ';' ), let_identifier: $ => $._identifier, let_port_list: $ => sep1(',', $.let_port_item), let_port_item: $ => seq( repeat($.attribute_instance), optional($.let_formal_type1), $.formal_port_identifier, repeat($._variable_dimension), optseq('=', $.expression) ), let_formal_type1: $ => choice( $.data_type_or_implicit1, 'untyped' ), let_expression: $ => prec.left(seq( optional($.package_scope), $.let_identifier, optseq('(', optional($.let_list_of_arguments), ')') )), let_list_of_arguments: $ => choice( // FIXME empty string // seq( // sep1(',', optional($.let_actual_arg)), // repseq(',', '.', $._identifier, '(', optional($.let_actual_arg), ')') // ), sep1(',', seq('.', $._identifier, '(', optional($.let_actual_arg), ')')) ), let_actual_arg: $ => $.expression, // A.3 Primitive instances // A.3.1 Primitive instantiation and instances gate_instantiation: $ => seq( choice( seq( $.cmos_switchtype, optional($.delay3), sep1(',', $.cmos_switch_instance) ), seq( $.enable_gatetype, optional($.drive_strength), optional($.delay3), sep1(',', $.enable_gate_instance) ), seq( $.mos_switchtype, optional($.delay3), sep1(',', $.mos_switch_instance) ), seq( $.n_input_gatetype, optional($.drive_strength), optional($.delay2), sep1(',', $.n_input_gate_instance) ), seq( $.n_output_gatetype, optional($.drive_strength), optional($.delay2), sep1(',', $.n_output_gate_instance) ), seq( $.pass_en_switchtype, optional($.delay2), sep1(',', $.pass_enable_switch_instance) ), seq( $.pass_switchtype, sep1(',', $.pass_switch_instance) ), seq( 'pulldown', optional($.pulldown_strength), sep1(',', $.pull_gate_instance) ), seq( 'pullup', optional($.pullup_strength), sep1(',', $.pull_gate_instance) ) ), ';' ), cmos_switch_instance: $ => seq( optional($.name_of_instance), '(', $.output_terminal, ',', $.input_terminal, ',', $.ncontrol_terminal, ',', $.pcontrol_terminal, ')' ), enable_gate_instance: $ => seq( optional($.name_of_instance), '(', $.output_terminal, ',', $.input_terminal, ',', $.enable_terminal, ')' ), mos_switch_instance: $ => seq( optional($.name_of_instance), '(', $.output_terminal, ',', $.input_terminal, ',', $.enable_terminal, ')' ), n_input_gate_instance: $ => seq( optional($.name_of_instance), '(', $.output_terminal, ',', sep1(',', $.input_terminal), ')' ), n_output_gate_instance: $ => seq( optional($.name_of_instance), '(', sep1(',', $.output_terminal), ',', $.input_terminal, ')' ), pass_switch_instance: $ => seq( optional($.name_of_instance), '(', $.inout_terminal, ',', $.inout_terminal, ')' ), pass_enable_switch_instance: $ => seq( optional($.name_of_instance), '(', $.inout_terminal, ',', $.inout_terminal, ',', $.enable_terminal, ')' ), pull_gate_instance: $ => seq( optional($.name_of_instance), '(', $.output_terminal, ')' ), // A.3.2 Primitive strengths pulldown_strength: $ => choice( seq('(', $.strength0, ',', $.strength1, ')'), seq('(', $.strength1, ',', $.strength0, ')'), seq('(', $.strength0, ')') ), pullup_strength: $ =>choice( seq(',', $.strength0, ',', $.strength1, ')'), seq(',', $.strength1, ',', $.strength0, ')'), seq(',', $.strength1, ')') ), // A.3.3 Primitive terminals enable_terminal: $ => $.expression, inout_terminal: $ => $.net_lvalue, input_terminal: $ => $.expression, ncontrol_terminal: $ => $.expression, output_terminal: $ => $.net_lvalue, pcontrol_terminal: $ => $.expression, // A.3.4 Primitive gate and switch types cmos_switchtype: $ => choice('cmos', 'rcmos'), enable_gatetype: $ => choice('bufif0', 'bufif1', 'notif0', 'notif1'), mos_switchtype: $ => choice('nmos', 'pmos', 'rnmos', 'rpmos'), n_input_gatetype: $ => choice('and', 'nand', 'or', 'nor', 'xor', 'xnor'), n_output_gatetype: $ => choice('buf', 'not'), pass_en_switchtype: $ => choice('tranif0', 'tranif1', 'rtranif1', 'rtranif0'), pass_switchtype: $ => choice('tran', 'rtran'), // A.4 Instantiations // A.4.1 Instantiation // A.4.1.1 Module instantiation module_instantiation: $ => seq( $._module_identifier, optional($.parameter_value_assignment), sep1(',', $.hierarchical_instance), ';' ), parameter_value_assignment: $ => seq( '#', '(', optional($.list_of_parameter_assignments), ')' ), list_of_parameter_assignments: $ => choice( sep1(',', $.ordered_parameter_assignment), sep1(',', $.named_parameter_assignment) ), ordered_parameter_assignment: $ => alias($.param_expression, $._ordered_parameter_assignment), named_parameter_assignment: $ => seq( '.', $.parameter_identifier, '(', optional($.param_expression), ')' ), hierarchical_instance: $ => seq( $.name_of_instance, '(', optional($.list_of_port_connections), ')' ), name_of_instance: $ => seq( $.instance_identifier, repeat($.unpacked_dimension) ), // Reordered list_of_port_connections: $ => choice( sep1(',', $.named_port_connection), sep1(',', $.ordered_port_connection) ), ordered_port_connection: $ => seq( repeat($.attribute_instance), $.expression ), // from spec: // named_port_connection: $ => // { attribute_instance } . port_identifier [ ( [ expression ] ) ] // | { attribute_instance } .* named_port_connection: $ => seq( repeat($.attribute_instance), choice( seq('.', $.port_identifier, optseq( '(', optional($.expression), ')' )), '.*' ) ), /* A.4.1.2 Interface instantiation */ interface_instantiation: $ => seq( $.interface_identifier, optional($.parameter_value_assignment), sep1(',', $.hierarchical_instance), ';' ), /* A.4.1.3 Program instantiation */ program_instantiation: $ => seq( $.program_identifier, optional($.parameter_value_assignment), sep1(',', $.hierarchical_instance), ';' ), /* A.4.1.4 Checker instantiation */ checker_instantiation: $ => seq( $.ps_checker_identifier, $.name_of_instance, '(', // optional($.list_of_checker_port_connections), choice( sep1(',', optseq( repeat($.attribute_instance), optional($._property_actual_arg) )), // sep1(',', $.named_checker_port_connection) sep1(',', choice( seq( repeat($.attribute_instance), '.', $.formal_port_identifier, optseq('(', optional($._property_actual_arg), ')') ), seq( repeat($.attribute_instance), '.*' ) )) ), ')', ';' ), // list_of_checker_port_connections1: $ => choice( // sep1(',', optional($.ordered_checker_port_connection1)), // sep1(',', $.named_checker_port_connection) // ), // ordered_checker_port_connection: $ => seq( // repeat($.attribute_instance), // optional($._property_actual_arg) // ), // named_checker_port_connection: $ => choice( // seq( // repeat($.attribute_instance), '.', $.formal_port_identifier, // optseq('(', optional($._property_actual_arg), ')') // ), // seq( // repeat($.attribute_instance, '.*') // ) // ), /* A.4.2 Generated instantiation */ generate_region: $ => seq( 'generate', repeat($._generate_item), 'endgenerate' ), loop_generate_construct: $ => seq( 'for', '(', $.genvar_initialization, ';', $._genvar_expression, ';', $.genvar_iteration, ')', $.generate_block ), genvar_initialization: $ => seq( optional('genvar'), $.genvar_identifier, '=', $.constant_expression ), genvar_iteration: $ => choice( seq($.genvar_identifier, $.assignment_operator, $._genvar_expression), seq($.inc_or_dec_operator, $.genvar_identifier), seq($.genvar_identifier, $.inc_or_dec_operator) ), _conditional_generate_construct: $ => choice( $.if_generate_construct, $.case_generate_construct ), if_generate_construct: $ => prec.left(seq( 'if', '(', $.constant_expression, ')', $.generate_block, optseq('else', $.generate_block) )), case_generate_construct: $ => seq( 'case', '(', $.constant_expression, ')', $.case_generate_item, repeat($.case_generate_item), 'endcase' ), case_generate_item: $ => choice( seq(sep1(',', $.constant_expression), ':', $.generate_block), seq('default', optional(':'), $.generate_block) ), generate_block: $ => choice( $._generate_item, seq( optseq($.generate_block_identifier, ':'), 'begin', optseq(':', $.generate_block_identifier), repeat($._generate_item), 'end', optseq(':', $.generate_block_identifier) ) ), _generate_item: $ => choice( $.module_or_generate_item, $.interface_or_generate_item, $._checker_or_generate_item ), /* A.5 UDP declaration and instantiation */ /* A.5.1 UDP declaration */ udp_nonansi_declaration: $ => seq( repeat($.attribute_instance), 'primitive', $._udp_identifier, '(', $.udp_port_list, ')', ';' ), udp_ansi_declaration: $ => seq( repeat($.attribute_instance), 'primitive', $._udp_identifier, '(', $.udp_declaration_port_list, ')', ';' ), udp_declaration: $ => choice( seq( $.udp_nonansi_declaration, $.udp_port_declaration, repeat($.udp_port_declaration), $._udp_body, 'endprimitive', optseq(':', $._udp_identifier) ), seq($.udp_ansi_declaration, $._udp_body, 'endprimitive', optseq(':', $._udp_identifier)), seq('extern', $.udp_nonansi_declaration), seq('extern', $.udp_ansi_declaration), seq( repeat($.attribute_instance), 'primitive', $._udp_identifier, '(', '.*', ')', ';', repeat($.udp_port_declaration), $._udp_body, 'endprimitive', optseq(':', $._udp_identifier) ) ), /* A.5.2 UDP ports */ udp_port_list: $ => seq( $.output_port_identifier, ',', sep1(',', $.input_port_identifier) ), udp_declaration_port_list: $ => seq( $.udp_output_declaration, ',', sep1(',', $.udp_input_declaration) ), udp_port_declaration: $ => seq( choice( $.udp_output_declaration, $.udp_input_declaration, $.udp_reg_declaration ), ';' ), udp_output_declaration: $ => seq( repeat($.attribute_instance), 'output', choice( $.port_identifier, seq('reg', $.port_identifier, optseq('=', $.constant_expression)) ) ), udp_input_declaration: $ => seq( repeat($.attribute_instance), 'input', $.list_of_udp_port_identifiers ), udp_reg_declaration: $ => seq( repeat($.attribute_instance), 'reg', $._variable_identifier ), /* A.5.3 UDP body */ _udp_body: $ => choice($.combinational_body, $.sequential_body), combinational_body: $ => seq( 'table', repeat1($.combinational_entry), 'endtable' ), combinational_entry: $ => seq($.level_input_list, ':', $.output_symbol, ';'), sequential_body: $ => seq( optional($.udp_initial_statement), 'table', repeat1($.sequential_entry), 'endtable' ), udp_initial_statement: $ => seq( 'initial', $.output_port_identifier, '=', $.init_val, ';' ), init_val: $ => choice( "1'b0", "1'b1", "1'bx", "1'bX", "1'B0", "1'B1", "1'Bx", "1'BX", "1", "0" ), sequential_entry: $ => seq( $._seq_input_list, ':', $._current_state, ':', $.next_state, ';' ), _seq_input_list: $ => choice($.level_input_list, $.edge_input_list), level_input_list: $ => repeat1($.level_symbol), edge_input_list: $ => seq(repeat($.level_symbol), $.edge_indicator, repeat($.level_symbol)), edge_indicator: $ => choice( seq('(', $.level_symbol, $.level_symbol, ')'), $.edge_symbol ), _current_state: $ => $.level_symbol, next_state: $ => choice($.output_symbol, '-'), output_symbol: $ => /[01xX]/, level_symbol: $ => /[01xX?bB]/, edge_symbol: $ => /[rRfFpPnN*]/, /* A.5.4 UDP instantiation */ udp_instantiation: $ => seq( $._udp_identifier, optional($.drive_strength), optional($.delay2), sep1(',', $.udp_instance), ';' ), udp_instance: $ => seq( optional($.name_of_instance), '(', $.output_terminal, ',', sep1(',', $.input_terminal), ')' ), // A.6 Behavioral statements // A.6.1 Continuous assignment and net alias statements continuous_assign: $ => seq( 'assign', choice( seq( optional($.drive_strength), optional($.delay3), $.list_of_net_assignments ), seq( optional($.delay_control), $.list_of_variable_assignments ) ), ';' ), list_of_net_assignments: $ => sep1(',', $.net_assignment), list_of_variable_assignments: $ => sep1(',', $.variable_assignment), net_alias: $ => prec.left(PREC.ASSIGN, seq( 'alias', $.net_lvalue, '=', sep1(',', seq('=', $.net_lvalue)), ';' )), net_assignment: $ => prec.left(PREC.ASSIGN, seq($.net_lvalue, '=', $.expression) ), // A.6.2 Procedural blocks and assignments initial_construct: $ => seq('initial', $.statement_or_null), always_construct: $ => seq($.always_keyword, $.statement), always_keyword: $ => choice( 'always', 'always_comb', 'always_latch', 'always_ff' ), final_construct: $ => seq('final', $.function_statement), blocking_assignment: $ => choice( prec.left(PREC.ASSIGN, seq( $.variable_lvalue, '=', $.delay_or_event_control, $.expression )), prec.left(PREC.ASSIGN, seq( $.nonrange_variable_lvalue, '=', $.dynamic_array_new )), // seq( // optional(choice( // seq($.implicit_class_handle, '.'), // $.class_scope, // $.package_scope // )), // $._hierarchical_variable_identifier // $.select, // '=', // $.class_new // ), $.operator_assignment ), operator_assignment: $ => prec.left(PREC.ASSIGN, seq($.variable_lvalue, $.assignment_operator, $.expression) ), assignment_operator: $ => choice( '=', '+=', '-=', '*=', '/=', '%=', '&=', '|=', '^=', '<<=', '>>=', '<<<=', '>>>=' ), nonblocking_assignment: $ => prec.left(PREC.ASSIGN, seq( $.variable_lvalue, '<=', optional($.delay_or_event_control), $.expression )), procedural_continuous_assignment: $ => choice( seq('assign', $.variable_assignment), seq('deassign', $.variable_lvalue), seq('force', $.variable_assignment), seq('force', $.net_assignment), seq('release', $.variable_lvalue), seq('release', $.net_lvalue) ), variable_assignment: $ => prec.left(PREC.ASSIGN, seq( $.variable_lvalue, '=', $.expression )), // A.6.3 Parallel and sequential blocks action_block: $ => choice( $.statement_or_null, seq(optional($.statement), 'else', $.statement_or_null) ), seq_block: $ => seq( 'begin', optseq(':', $._block_identifier), repeat($.block_item_declaration), repeat($.statement_or_null), 'end', optseq(':', $._block_identifier) ), par_block: $ => seq( 'fork', optseq(':', $._block_identifier), repeat($.block_item_declaration), repeat($.statement_or_null), $.join_keyword, optseq(':', $._block_identifier) ), join_keyword: $ => choice('join', 'join_any', 'join_none'), // A.6.4 Statements statement_or_null: $ => choice( $.statement, seq(repeat($.attribute_instance), ';') ), statement: $ => seq( optseq($._block_identifier, ':'), repeat($.attribute_instance), $.statement_item ), statement_item: $ => choice( seq($.blocking_assignment, ';'), seq($.nonblocking_assignment, ';'), seq($.procedural_continuous_assignment, ';'), $.case_statement, $.conditional_statement, seq($.inc_or_dec_expression, ';'), // $.subroutine_call_statement, $.disable_statement, $.event_trigger, $.loop_statement, $.jump_statement, $.par_block, $.seq_block, $.procedural_timing_control_statement, $.wait_statement, $._procedural_assertion_statement, seq($.clocking_drive, ';'), // $.randsequence_statement, $.randcase_statement, $.expect_property_statement ), function_statement: $ => $.statement, function_statement_or_null: $ => choice( $.function_statement, seq(repeat($.attribute_instance), ';') ), variable_identifier_list: $ => sep1(',', $._variable_identifier), // A.6.5 Timing control statements procedural_timing_control_statement: $ => seq( $._procedural_timing_control, $.statement_or_null // statement_or_null1 ), delay_or_event_control: $ => choice( $.delay_control, $.event_control, seq('repeat', '(', $.expression, ')', $.event_control) ), delay_control: $ => seq('#', choice( $.delay_value, seq('(', $.mintypmax_expression, ')') )), event_control: $ => choice( seq('@', $._hierarchical_event_identifier), seq('@', '(', $.event_expression, ')'), '@*', seq('@', '(', '*', ')'), seq('@', $.ps_or_hierarchical_sequence_identifier) ), event_expression: $ => choice( // reordered : brake recursion prec.left(seq($.event_expression, 'or', $.event_expression)), prec.left(seq($.event_expression, ',', $.event_expression)), seq( optional($.edge_identifier), $.expression ) // reordered : help parser // seq( // optional($.edge_identifier), // $.expression, // optseq('iff', $.expression) // ), // seq( // $.sequence_instance, // optseq('iff', $.expression) // ), // seq('(', $.event_expression, ')') ), // event_expression_2: $ => choice( // reordered : help parser // seq($.edge_identifier, $.expression), // reordered : help parser // seq( // optional($.edge_identifier), // $.expression, // optseq('iff', $.expression) // ), // // seq( // // $.sequence_instance, // // optseq('iff', $.expression) // // ), // seq('(', $.event_expression, ')') // ), _procedural_timing_control: $ => choice( $.delay_control, $.event_control, $.cycle_delay ), jump_statement: $ => choice( seq('return', optional($.expression), ';'), seq('break', ';'), seq('continue', ';') ), wait_statement: $ => choice( seq('wait', '(', $.expression, ')', $.statement_or_null), seq('wait', 'fork', ';'), seq('wait_order', '(', sep1(',', $.hierarchical_identifier), ')', $.action_block) ), event_trigger: $ => choice( seq('->', $._hierarchical_event_identifier, ';'), seq('->>', optional($.delay_or_event_control), $._hierarchical_event_identifier, ';') ), disable_statement: $ => choice( seq('disable', $._hierarchical_task_identifier, ';'), seq('disable', $._hierarchical_block_identifier, ';'), seq('disable', 'fork', ';') ), // A.6.6 Conditional statements conditional_statement: $ => prec.left(seq( optional($.unique_priority), 'if', '(', $.cond_predicate, ')', $.statement_or_null, // repseq('else', 'if', '(', $.cond_predicate, ')', $.statement_or_null), optseq('else', $.statement_or_null) )), unique_priority: $ => choice('unique', 'unique0', 'priority'), cond_predicate: $ => psep1(PREC.PARENT, '&&&', $._expression_or_cond_pattern), // FIXME precedence _expression_or_cond_pattern: $ => choice( $.expression, $.cond_pattern ), cond_pattern: $ => prec.left(PREC.MATCHES, seq($.expression, 'matches', $.pattern)), // A.6.7 Case statements case_statement: $ => seq( optional($.unique_priority), seq( $.case_keyword, '(', $.case_expression, ')', choice( repeat1($.case_item), seq('matches', repeat1($.case_pattern_item)), seq('inside', repeat1($.case_inside_item)) // only case ) ), 'endcase' ), case_keyword: $ => choice('case', 'casez', 'casex'), case_expression: $ => $.expression, case_item: $ => choice( seq(sep1(',', $.case_item_expression), ':', $.statement_or_null), seq('default', optional(':'), $.statement_or_null) ), case_pattern_item: $ => choice( seq($.pattern, optseq('&&&', $.expression), ':', $.statement_or_null), seq('default', optional(':'), $.statement_or_null) ), case_inside_item: $ => choice( seq($.open_range_list, ':', $.statement_or_null), seq('default', optional(':'), $.statement_or_null) ), case_item_expression: $ => $.expression, randcase_statement: $ => seq( 'randcase', $.randcase_item, repeat($.randcase_item), 'endcase' ), randcase_item: $ => seq($.expression, ':', $.statement_or_null), open_range_list: $ => sep1(',', $.open_value_range), open_value_range: $ => $.value_range, // A.6.7.1 Patterns pattern: $ => choice( seq('.', $._variable_identifier), '.*', $.constant_expression, seq('tagged', $.member_identifier, optional($.pattern)), seq('\'{', sep1(',', $.pattern), '}'), seq('\'{', sep1(',', seq($.member_identifier, ':', $.pattern)), '}') ), assignment_pattern: $ => seq( '\'{', choice( sep1(',', $.expression), // sep1(',', seq($._structure_pattern_key, ':', $.expression)), sep1(',', seq($._array_pattern_key, ':', $.expression)), seq($.constant_expression, '{', sep1(',', $.expression), '}') ), '}' ), _structure_pattern_key: $ => choice( $.member_identifier, $.assignment_pattern_key ), _array_pattern_key: $ => choice( $.constant_expression, $.assignment_pattern_key ), assignment_pattern_key: $ => choice( $._simple_type, 'default' ), assignment_pattern_expression: $ => seq( optional($._assignment_pattern_expression_type), $.assignment_pattern ), _assignment_pattern_expression_type: $ => choice( $.ps_type_identifier, // $.ps_parameter_identifier, $.integer_atom_type, $.type_reference ), constant_assignment_pattern_expression: $ => $.assignment_pattern_expression, assignment_pattern_net_lvalue: $ => seq( '\'{', sep1(',', $.net_lvalue), '}' ), assignment_pattern_variable_lvalue: $ => seq( '\'{', sep1(',', $.variable_lvalue), '}' ), // A.6.8 Looping statements loop_statement: $ => choice( seq('forever', $.statement_or_null), seq('repeat', '(', $.expression, ')', $.statement_or_null), seq('while', '(', $.expression, ')', $.statement_or_null), seq( 'for', '(', optional($.for_initialization), ';', optional($.expression), ';', optional($.for_step), ')', $.statement_or_null ), seq('do', $.statement_or_null, 'while', '(', $.expression, ')', ';'), seq( 'foreach', '(', $.ps_or_hierarchical_array_identifier, '[', optional($.loop_variables1), ']', ')', $.statement ) ), for_initialization: $ => choice( $.list_of_variable_assignments, sep1(',', $.for_variable_declaration) ), for_variable_declaration: $ => seq( optional('var'), $.data_type, sep1(',', seq( $._variable_identifier, '=', $.expression )) ), for_step: $ => sep1(',', $._for_step_assignment), _for_step_assignment: $ => choice( $.operator_assignment, $.inc_or_dec_expression, $.function_subroutine_call ), loop_variables1: $ => seq( $.index_variable_identifier, repseq(',', optional($.index_variable_identifier)) ), // A.6.9 Subroutine call statements subroutine_call_statement: $ => choice( seq($.subroutine_call, ';'), seq('void\'', '(', $.function_subroutine_call, ')', ';') ), // A.6.10 Assertion statements _assertion_item: $ => choice( $.concurrent_assertion_item, $.deferred_immediate_assertion_item ), deferred_immediate_assertion_item: $ => seq( optseq( $._block_identifier, ':' ), $._deferred_immediate_assertion_statement ), _procedural_assertion_statement: $ => choice( $._concurrent_assertion_statement, $._immediate_assertion_statement, $.checker_instantiation ), _immediate_assertion_statement: $ => choice( $._simple_immediate_assertion_statement, $._deferred_immediate_assertion_statement ), _simple_immediate_assertion_statement: $ => choice( $.simple_immediate_assert_statement, $.simple_immediate_assume_statement, $.simple_immediate_cover_statement ), simple_immediate_assert_statement: $ => seq( 'assert', '(', $.expression, ')', $.action_block ), simple_immediate_assume_statement: $ => seq( 'assume', '(', $.expression, ')', $.action_block ), simple_immediate_cover_statement: $ => seq( 'cover', '(', $.expression, ')', $.statement_or_null ), _deferred_immediate_assertion_statement: $ => choice( $.deferred_immediate_assert_statement, $.deferred_immediate_assume_statement, $.deferred_immediate_cover_statement ), deferred_immediate_assert_statement: $ => seq( 'assert', choice('#0', 'final'), '(', $.expression, ')', $.action_block ), deferred_immediate_assume_statement: $ => seq( 'assume', choice('#0', 'final'), '(', $.expression, ')', $.action_block ), deferred_immediate_cover_statement: $ => seq( 'cover', choice('#0', 'final'), '(', $.expression, ')', $.statement_or_null ), /* A.6.11 Clocking block */ clocking_declaration: $ => choice( seq( optional('default'), 'clocking', optional($.clocking_identifier), $.clocking_event, ';', repeat($.clocking_item), 'endclocking', optseq(':', $.clocking_identifier) ), seq( 'global', 'clocking', optional($.clocking_identifier), $.clocking_event, ';', 'endclocking', optseq(':', $.clocking_identifier) ) ), clocking_event: $ => seq('@', choice( $._identifier, seq('(', $.event_expression, ')') )), clocking_item: $ => choice( seq('default', $.default_skew, ';'), seq($.clocking_direction, $.list_of_clocking_decl_assign, ';'), seq(repeat($.attribute_instance), $._assertion_item_declaration) ), default_skew: $ => choice( seq('input', $.clocking_skew), seq('output', $.clocking_skew), seq('input', $.clocking_skew, 'output', $.clocking_skew) ), clocking_direction: $ => choice( seq('input', optional($.clocking_skew)), seq('output', optional($.clocking_skew)), seq('input', optional($.clocking_skew), 'output', optional($.clocking_skew)), seq('inout') ), list_of_clocking_decl_assign: $ => sep1(',', $.clocking_decl_assign), clocking_decl_assign: $ => seq($._signal_identifier, optseq('=', $.expression)), clocking_skew: $ => choice( seq($.edge_identifier, optional($.delay_control)), $.delay_control ), clocking_drive: $ => prec.left(PREC.ASSIGN, seq($.clockvar_expression, '<=', optional($.cycle_delay), $.expression) ), cycle_delay: $ => prec.left(seq('##', choice( $.integral_number, $._identifier, seq('(', $.expression, ')') ))), clockvar: $ => $.hierarchical_identifier, clockvar_expression: $ => seq( $.clockvar, optional($.select1) ), // A.6.12 Randsequence // randsequence_statement = randsequence ( [ production_identifier ] ) // production { production } // endsequence // production // = [ data_type_or_void ] production_identifier // [ ( tf_port_list ) ] : rs_rule { | rs_rule } ; // rs_rule = rs_production_list [ := weight_specification [ rs_code_block ] ] // rs_production_list = // rs_prod { rs_prod } // | rand join [ ( expression ) ] production_item // production_item { production_item } // weight_specification = // integral_number // | ps_identifier // | ( expression ) // rs_code_block = { { data_declaration } { statement_or_null } } // rs_prod = // production_item // | rs_code_block // | rs_if_else // | rs_repeat // | rs_case // production_item = production_identifier [ ( list_of_arguments ) ] // rs_if_else = if ( expression ) production_item [ else production_item ] // rs_repeat = repeat ( expression ) production_item // rs_case = case ( case_expression ) rs_case_item { rs_case_item } endcase // rs_case_item = // case_item_expression { , case_item_expression } : production_item ; // | default [ : ] production_item ; // A.7 Specify section // A.7.1 Specify block declaration specify_block: $ => seq('specify', repeat($._specify_item), 'endspecify'), _specify_item: $ => choice( $.specparam_declaration, $.pulsestyle_declaration, $.showcancelled_declaration, $.path_declaration, $._system_timing_check ), pulsestyle_declaration: $ => seq( choice('pulsestyle_onevent', 'pulsestyle_ondetect'), $.list_of_path_outputs, ';' ), showcancelled_declaration: $ => seq( choice('showcancelled', 'noshowcancelled'), $.list_of_path_outputs, ';' ), // A.7 Specify section // A.7.1 Specify block declaration // A.7.2 Specify path declarations path_declaration: $ => seq( choice( $.simple_path_declaration, $.edge_sensitive_path_declaration, $.state_dependent_path_declaration ), ';' ), simple_path_declaration: $ => seq( choice($.parallel_path_description, $.full_path_description), '=', $.path_delay_value ), parallel_path_description: $ => seq( '(', $.specify_input_terminal_descriptor, optional($.polarity_operator), '=>', $.specify_output_terminal_descriptor, ')' ), full_path_description: $ => seq( '(', $.list_of_path_inputs, optional($.polarity_operator), '*>', $.list_of_path_outputs, ')' ), list_of_path_inputs: $ => sep1(',', $.specify_input_terminal_descriptor), list_of_path_outputs: $ => sep1(',', $.specify_output_terminal_descriptor), // A.7.3 Specify block terminals specify_input_terminal_descriptor: $ => seq( $.input_identifier, optseq('[', $._constant_range_expression, ']') ), specify_output_terminal_descriptor: $ => seq( $.output_identifier, optseq('[', $._constant_range_expression, ']') ), input_identifier: $ => choice( $.input_port_identifier, $.inout_port_identifier, seq($.interface_identifier, '.', $.port_identifier) // FIXME glue dot? ), output_identifier: $ => choice( $.output_port_identifier, $.inout_port_identifier, seq($.interface_identifier, '.', $.port_identifier) ), /* A.7.4 Specify path delays */ path_delay_value: $ => choice( $.list_of_path_delay_expressions, seq('(', $.list_of_path_delay_expressions, ')') ), list_of_path_delay_expressions: $ => sep1(',', $.path_delay_expression), // list_of_path_delay_expressions: $ => choice( // $.t_path_delay_expression, // seq($.trise_path_delay_expression, ',', $.tfall_path_delay_expression), // seq( // $.trise_path_delay_expression, ',', $.tfall_path_delay_expression, ',', // $.tz_path_delay_expression // ), // seq( // $.t01_path_delay_expression, ',', $.t10_path_delay_expression, ',', // $.t0z_path_delay_expression, ',', $.tz1_path_delay_expression, ',', // $.t1z_path_delay_expression, ',', $.tz0_path_delay_expression // ), // seq( // $.t01_path_delay_expression, ',', $.t10_path_delay_expression, ',', // $.t0z_path_delay_expression, ',', $.tz1_path_delay_expression, ',', // $.t1z_path_delay_expression, ',', $.tz0_path_delay_expression, ',', // $.t0x_path_delay_expression, ',', $.tx1_path_delay_expression, ',', // $.t1x_path_delay_expression, ',', $.tx0_path_delay_expression, ',', // $.txz_path_delay_expression, ',', $.tzx_path_delay_expression // ) // ), // // t_path_delay_expression: $ => alias($.path_delay_expression, $.t_path_delay_expression), // trise_path_delay_expression: $ => alias($.path_delay_expression, $.trise_path_delay_expression), // tfall_path_delay_expression: $ => alias($.path_delay_expression, $.tfall_path_delay_expression), // tz_path_delay_expression: $ => alias($.path_delay_expression, $.tz_path_delay_expression), // t01_path_delay_expression: $ => alias($.path_delay_expression, $.t01_path_delay_expression), // t10_path_delay_expression: $ => alias($.path_delay_expression, $.t10_path_delay_expression), // t0z_path_delay_expression: $ => alias($.path_delay_expression, $.t0z_path_delay_expression), // tz1_path_delay_expression: $ => alias($.path_delay_expression, $.tz1_path_delay_expression), // t1z_path_delay_expression: $ => alias($.path_delay_expression, $.t1z_path_delay_expression), // tz0_path_delay_expression: $ => alias($.path_delay_expression, $.tz0_path_delay_expression), // t0x_path_delay_expression: $ => alias($.path_delay_expression, $.t0x_path_delay_expression), // tx1_path_delay_expression: $ => alias($.path_delay_expression, $.tx1_path_delay_expression), // t1x_path_delay_expression: $ => alias($.path_delay_expression, $.t1x_path_delay_expression), // tx0_path_delay_expression: $ => alias($.path_delay_expression, $.tx0_path_delay_expression), // txz_path_delay_expression: $ => alias($.path_delay_expression, $.txz_path_delay_expression), // tzx_path_delay_expression: $ => alias($.path_delay_expression, $.tzx_path_delay_expression), path_delay_expression: $ => $.constant_mintypmax_expression, edge_sensitive_path_declaration: $ => seq( choice( $.parallel_edge_sensitive_path_description, $.full_edge_sensitive_path_description ), '=', $.path_delay_value ), parallel_edge_sensitive_path_description: $ => seq( '(', optional($.edge_identifier), $.specify_input_terminal_descriptor, optional($.polarity_operator), '=>', '(', $.specify_output_terminal_descriptor, optional($.polarity_operator), ':', $.data_source_expression, ')', ')' ), full_edge_sensitive_path_description: $ => seq( '(', optional($.edge_identifier), $.list_of_path_inputs, optional($.polarity_operator), '*>', '(', $.list_of_path_outputs, optional($.polarity_operator), ':', $.data_source_expression, ')', ')' ), data_source_expression: $ => $.expression, edge_identifier: $ => choice('posedge', 'negedge', 'edge'), state_dependent_path_declaration: $ => choice( seq('if', '(', $.module_path_expression, ')', $.simple_path_declaration), seq('if', '(', $.module_path_expression, ')', $.edge_sensitive_path_declaration), seq('ifnone', $.simple_path_declaration) ), polarity_operator: $ => choice('+', '-'), /* A.7.5 System timing checks */ /* A.7.5.1 System timing check commands */ _system_timing_check: $ => choice( $.$setup_timing_check, $.$hold_timing_check, $.$setuphold_timing_check, $.$recovery_timing_check, $.$removal_timing_check, $.$recrem_timing_check, $.$skew_timing_check, $.$timeskew_timing_check, $.$fullskew_timing_check, $.$period_timing_check, $.$width_timing_check, $.$nochange_timing_check ), $setup_timing_check: $ => seq( '$setup', '(', $.data_event, ',', $.reference_event, ',', $.timing_check_limit, optseq(',', optional($.notifier)), ')', ';' ), $hold_timing_check: $ => seq( '$hold', '(', $.reference_event, ',', $.data_event, ',', $.timing_check_limit, optseq(',', optional($.notifier)), ')', ';' ), $setuphold_timing_check: $ => seq( '$setuphold', '(', $.reference_event, ',', $.data_event, ',', $.timing_check_limit, ',', $.timing_check_limit, optseq( ',', optional($.notifier), optseq( ',', optional($.timestamp_condition), optseq( ',', optional($.timecheck_condition), optseq( ',', optional($.delayed_reference), optseq( ',', optional($.delayed_data) ) ) ) ) ), ')', ';' ), $recovery_timing_check: $ => seq( '$recovery', '(', $.reference_event, ',', $.data_event, ',', $.timing_check_limit, optseq(',', optional($.notifier)), ')', ';' ), $removal_timing_check: $ => seq( '$removal', '(', $.reference_event, ',', $.data_event, ',', $.timing_check_limit, optseq(',', optional($.notifier)), ')', ';' ), $recrem_timing_check: $ => seq( '$recrem', '(', $.reference_event, ',', $.data_event, ',', $.timing_check_limit, ',', $.timing_check_limit, optseq( ',', optional($.notifier), optseq(',', optional($.timestamp_condition), optseq(',', optional($.timecheck_condition)), optseq( ',', optional($.delayed_reference), optseq(',', optional($.delayed_data)) ) ) ), ')', ';' ), $skew_timing_check: $ => seq( '$skew', '(', $.reference_event, ',', $.data_event, ',', $.timing_check_limit, optseq(',', optional($.notifier)), ')', ';' ), $timeskew_timing_check: $ => seq( '$timeskew', '(', $.reference_event, ',', $.data_event, ',', $.timing_check_limit, optseq(',', optional($.notifier), optseq(',', optional($.event_based_flag), optseq(',', optional($.remain_active_flag)) ) ), ')', ';' ), $fullskew_timing_check: $ => seq( '$fullskew', '(', $.reference_event, ',', $.data_event, ',', $.timing_check_limit, ',', $.timing_check_limit, optseq(',', optional($.notifier), optseq(',', optional($.event_based_flag), optseq(',', optional($.remain_active_flag)) ) ), ')', ';' ), $period_timing_check: $ => seq( '$period', '(', $.controlled_reference_event, ',', $.timing_check_limit, optseq(',', optional($.notifier)), ')', ';' ), $width_timing_check: $ => seq( '$width', '(', $.controlled_reference_event, ',', $.timing_check_limit, ',', $.threshold, optseq(',', optional($.notifier)), ')', ';' ), $nochange_timing_check: $ => seq( '$nochange', '(', $.reference_event, ',', $.data_event, ',', $.start_edge_offset, ',', $.end_edge_offset, optseq(',', optional($.notifier)), ')', ';' ), // A.7.5.2 System timing check command arguments timecheck_condition: $ => $.mintypmax_expression, controlled_reference_event: $ => alias($.controlled_timing_check_event, $.controlled_reference_event), data_event: $ => $.timing_check_event, delayed_data: $ => seq( $.terminal_identifier, optional($.constant_mintypmax_expression) ), delayed_reference: $ => seq( $.terminal_identifier, optional($.constant_mintypmax_expression) ), end_edge_offset: $ => $.mintypmax_expression, event_based_flag: $ => $.constant_expression, notifier: $ => $._variable_identifier, reference_event: $ => $.timing_check_event, remain_active_flag: $ => $.constant_mintypmax_expression, timestamp_condition: $ => $.mintypmax_expression, start_edge_offset: $ => $.mintypmax_expression, threshold: $ => $.constant_expression, timing_check_limit: $ => $.expression, // A.7.5.3 System timing check event definitions timing_check_event: $ => seq( optional($.timing_check_event_control), $._specify_terminal_descriptor, optseq('&&&', $.timing_check_condition) ), controlled_timing_check_event: $ => seq( $.timing_check_event_control, $._specify_terminal_descriptor, optseq('&&&', $.timing_check_condition) ), timing_check_event_control: $ => choice( 'posedge', 'negedge', 'edge', $.edge_control_specifier ), _specify_terminal_descriptor: $ => choice( $.specify_input_terminal_descriptor, $.specify_output_terminal_descriptor ), edge_control_specifier: $ => seq( 'edge', '[', sep1(',', $.edge_descriptor), ']' ), // Note: Embedded spaces are illegal. edge_descriptor: $ => choice( '01', '10', /[xXzZ][01]/, /[01][xXzZ]/ ), timing_check_condition: $ => choice( $.scalar_timing_check_condition, seq('(', $.scalar_timing_check_condition, ')') ), scalar_timing_check_condition: $ => choice( $.expression, seq('~', $.expression), seq($.expression, '==', $.scalar_constant), seq($.expression, '===', $.scalar_constant), seq($.expression, '!=', $.scalar_constant), seq($.expression, '!==', $.scalar_constant) ), scalar_constant: $ => choice( '1\'b0', '1\'b1', '1\'B0', '1\'B1', '\'b0', '\'b1', '\'B0', '\'B1', '1', '0' ), // A.8 Expressions // A.8.1 Concatenations concatenation: $ => seq( '{', psep1(PREC.CONCAT, ',', $.expression), '}' ), constant_concatenation: $ => seq( '{', psep1(PREC.CONCAT, ',', $.constant_expression), '}' ), constant_multiple_concatenation: $ => prec.left(PREC.CONCAT, seq( '{', $.constant_expression, $.constant_concatenation, '}' )), module_path_concatenation: $ => seq( '{', psep1(PREC.CONCAT, ',', $.module_path_expression), '}' ), module_path_multiple_concatenation: $ => prec.left(PREC.CONCAT, seq( '{', $.constant_expression, $.module_path_concatenation, '}' )), multiple_concatenation: $ => prec.left(PREC.CONCAT, seq( '{', $.expression, $.concatenation, '}' )), streaming_concatenation: $ => prec.left(PREC.CONCAT, seq( '{', $.stream_operator, optional($.slice_size), $.stream_concatenation, '}' )), stream_operator: $ => choice('>>', '<<'), slice_size: $ => choice($._simple_type, $.constant_expression), stream_concatenation: $ => prec.left(PREC.CONCAT, seq( '{', sep1(',', $.stream_expression), '}' )), stream_expression: $ => seq($.expression, optseq('with', '[', $.array_range_expression, ']')), array_range_expression: $ => seq( $.expression, optional(choice( seq( ':', $.expression), seq('+:', $.expression), seq('-:', $.expression) )) ), empty_unpacked_array_concatenation: $ => seq('{', '}'), /* A.8.2 Subroutine calls */ constant_function_call: $ => $.function_subroutine_call, tf_call: $ => prec.left(seq( $._hierarchical_tf_identifier, // FIXME // $.ps_or_hierarchical_tf_identifier, repeat($.attribute_instance), optional($.list_of_arguments_parent) )), system_tf_call: $ => prec.left(seq( $.system_tf_identifier, optional(choice( $.list_of_arguments_parent, seq( '(', choice( seq($.data_type, optseq(',', $.expression)), prec.left(seq( sep1(',', $.expression), optseq(',', optional($.clocking_event)) )) ), ')' ) )) )), subroutine_call: $ => choice( $.tf_call, $.system_tf_call, $.method_call, seq(optseq('std', '::'), $.randomize_call) ), function_subroutine_call: $ => $.subroutine_call, list_of_arguments: $ => choice( // seq( // sep1(',', optional($.expression)), // repseq(',', '.', $._identifier, '(', optional($.expression), ')') // ), sep1(',', seq('.', $._identifier, '(', optional($.expression), ')')) ), list_of_arguments_parent: $ => seq( '(', choice( sep1(',', $.expression), // sep1(',', optional($.expression)), // FIXME seq( repseq(',', '.', $._identifier, '(', optional($.expression), ')') ), sep1(',', seq(',', '.', $._identifier, '(', optional($.expression), ')')) ), ')' ), method_call: $ => seq($._method_call_root, '.', $.method_call_body), method_call_body: $ => choice( prec.left(seq( $.method_identifier, repeat($.attribute_instance), optional($.list_of_arguments_parent) )), $._built_in_method_call ), _built_in_method_call: $ => choice( $.array_manipulation_call, $.randomize_call ), array_manipulation_call: $ => prec.left(seq( $.array_method_name, repeat($.attribute_instance), optional($.list_of_arguments_parent), optseq('with', '(', $.expression, ')') )), randomize_call: $ => prec.left(seq( 'randomize', repeat($.attribute_instance), optseq( '(', optional(choice( $.variable_identifier_list, 'null' )), ')' ), optseq( 'with', optseq( '(', optional($.identifier_list), ')' ), $.constraint_block ) )), _method_call_root: $ => choice($.primary, $.implicit_class_handle), array_method_name: $ => choice( $.method_identifier, 'unique', 'and', 'or', 'xor' ), // A.8.3 Expressions inc_or_dec_expression: $ => choice( seq($.inc_or_dec_operator, repeat($.attribute_instance), $.variable_lvalue), seq($.variable_lvalue, repeat($.attribute_instance), $.inc_or_dec_operator) ), conditional_expression: $ => prec.right(PREC.CONDITIONAL, seq( $.cond_predicate, '?', repeat($.attribute_instance), $.expression, ':', $.expression )), constant_expression: $ => choice( $.constant_primary, prec.left(PREC.UNARY, seq( $.unary_operator, repeat($.attribute_instance), $.constant_primary )), constExprOp($, PREC.ADD, choice('+', '-')), constExprOp($, PREC.MUL, choice('*', '/', '%')), constExprOp($, PREC.EQUAL, choice('==', '!=', '===', '!==', '==?', '!=?')), constExprOp($, PREC.LOGICAL_AND, '&&'), constExprOp($, PREC.LOGICAL_OR, '||'), constExprOp($, PREC.POW, '**'), constExprOp($, PREC.RELATIONAL, choice('<', '<=', '>', '>=')), constExprOp($, PREC.AND, '&'), constExprOp($, PREC.OR, '|'), constExprOp($, PREC.XOR, choice('^', '^~', '~^')), constExprOp($, PREC.SHIFT, choice('>>', '<<', '>>>', '<<<')), constExprOp($, PREC.IMPLICATION, choice('->', '<->')), prec.right(PREC.CONDITIONAL, seq( $.constant_expression, '?', repeat($.attribute_instance), $.constant_expression, ':', $.constant_expression )) ), constant_mintypmax_expression: $ => seq( $.constant_expression, optseq(':', $.constant_expression, ':', $.constant_expression) ), constant_param_expression: $ => choice( $.constant_mintypmax_expression, $.data_type, '$' ), param_expression: $ => choice( $.mintypmax_expression, $.data_type, '$' ), _constant_range_expression: $ => choice( $.constant_expression, $._constant_part_select_range ), _constant_part_select_range: $ => choice( $.constant_range, $.constant_indexed_range ), constant_range: $ => seq($.constant_expression, ':', $.constant_expression), constant_indexed_range: $ => seq( $.constant_expression, choice('+:', '-:'), $.constant_expression ), expression: $ => choice( $.primary, prec.left(PREC.UNARY, seq( $.unary_operator, repeat($.attribute_instance), $.primary )), prec.left(PREC.UNARY, $.inc_or_dec_expression), prec.left(PREC.PARENT, seq('(', $.operator_assignment, ')')), exprOp($, PREC.ADD, choice('+', '-')), exprOp($, PREC.MUL, choice('*', '/', '%')), exprOp($, PREC.EQUAL, choice('==', '!=', '===', '!==', '==?', '!=?')), exprOp($, PREC.LOGICAL_AND, '&&'), exprOp($, PREC.LOGICAL_OR, '||'), exprOp($, PREC.POW, '**'), exprOp($, PREC.RELATIONAL, choice('<', '<=', '>', '>=')), exprOp($, PREC.AND, '&'), exprOp($, PREC.OR, '|'), exprOp($, PREC.XOR, choice('^', '^~', '~^')), exprOp($, PREC.SHIFT, choice('>>', '<<', '>>>', '<<<')), exprOp($, PREC.IMPLICATION, choice('->', '<->')), $.conditional_expression, $.inside_expression, $.tagged_union_expression ), tagged_union_expression: $ => prec.left(seq( 'tagged', $.member_identifier, optional($.expression) )), inside_expression: $ => prec.left(PREC.RELATIONAL, seq( $.expression, 'inside', '{', $.open_range_list, '}' )), value_range: $ => choice( $.expression, seq('[', $.expression, ':', $.expression, ']') ), mintypmax_expression: $ => seq( $.expression, optseq(':', $.expression, ':', $.expression) ), module_path_conditional_expression: $ => seq( $.module_path_expression, '?', repeat($.attribute_instance), $.module_path_expression, ':', $.module_path_expression ), module_path_expression: $ => choice( $.module_path_primary // seq($.unary_module_path_operator, repeat($.attribute_instance), $.module_path_primary), // seq( // $.module_path_expression, // $.binary_module_path_operator, // repeat($.attribute_instance), // $.module_path_expression // ), // $.module_path_conditional_expression ), module_path_mintypmax_expression: $ => seq( $.module_path_expression, optseq( ':', $.module_path_expression, ':', $.module_path_expression ) ), _part_select_range: $ => choice( $.constant_range, $.indexed_range ), indexed_range: $ => seq( $.expression, choice('+:', '-:'), $.constant_expression ), _genvar_expression: $ => $.constant_expression, /* A.8.4 Primaries */ // FIXME FIXME FIXME constant_primary: $ => choice( $.primary_literal, seq($.ps_parameter_identifier, optional($.constant_select1)), // seq($.specparam_identifier, optseq('[', $._constant_range_expression, ']')), // $.genvar_identifier, // seq($.formal_port_identifier, optional($.constant_select1)), // seq(optional(choice($.package_scope, $.class_scope)), $.enum_identifier), seq($.constant_concatenation, optseq('[', $._constant_range_expression, ']')), seq($.constant_multiple_concatenation, optseq('[', $._constant_range_expression, ']')), // $.constant_function_call, // $._constant_let_expression, seq('(', $.constant_mintypmax_expression, ')'), // $.constant_cast, // // $.constant_assignment_pattern_expression, $.type_reference, 'null' ), module_path_primary: $ => choice( $._number, $._identifier, $.module_path_concatenation, $.module_path_multiple_concatenation, $.function_subroutine_call, seq('(', $.module_path_mintypmax_expression, ')') ), primary: $ => choice( $.primary_literal, seq( optional(choice($.class_qualifier, $.package_scope)), $.hierarchical_identifier, optional($.select1) ), $.empty_unpacked_array_concatenation, seq($.concatenation, optseq('[', $.range_expression, ']')), seq($.multiple_concatenation, optseq('[', $.range_expression, ']')), $.function_subroutine_call, $.let_expression, seq('(', $.mintypmax_expression, ')'), $.cast, $.assignment_pattern_expression, $.streaming_concatenation, $.sequence_method_call, 'this', '$', 'null' ), class_qualifier: $ => seq( optseq('local', '::'), choice( // TODO optional? seq($.implicit_class_handle, '.'), $.class_scope ) ), range_expression: $ => choice( $.expression, $._part_select_range ), // primary_literal: $ => choice( $._number, $.time_literal, $.unbased_unsized_literal, $.string_literal, $.simple_text_macro_usage ), time_literal: $ => choice( seq($.unsigned_number, $.time_unit), seq($.fixed_point_number, $.time_unit) ), time_unit: $ => choice('s', 'ms', 'us', 'ns', 'ps', 'fs'), string_literal: $ => seq( '"', repeat(choice( token.immediate(/[^\\"]+/), // EXTENDS Verilog spec with escape sequences token.immediate(seq('\\', /./)), token.immediate(seq('\\', '\n')) )), '"' ), implicit_class_handle: $ => choice( prec.left(seq('this', optseq('.', 'super'))), 'super' ), bit_select1: $ => prec.left(PREC.PARENT, repeat1(seq( // reordered -> non empty '[', $.expression, ']') )), select1: $ => choice( // reordered -> non empty prec.left(PREC.PARENT, seq( // 1xx repseq('.', $.member_identifier, optional($.bit_select1)), '.', $.member_identifier, optional($.bit_select1), optseq('[', $._part_select_range, ']') )), prec.left(PREC.PARENT, seq( // 01x // $.bit_select1, optseq('[', $._part_select_range, ']') )), prec.left(PREC.PARENT, seq( // 001 // // seq('[', $._part_select_range, ']') )) ), nonrange_select1: $ => choice( // reordered -> non empty prec.left(PREC.PARENT, seq( // 1x repseq('.', $.member_identifier, optional($.bit_select1)), '.', $.member_identifier, optional($.bit_select1) )), $.bit_select1 ), constant_bit_select1: $ => repeat1(prec.left(PREC.PARENT, seq( // reordered -> non empty '[', $.constant_expression, ']' ))), constant_select1: $ => choice( // reordered -> non empty seq( '[', repseq($.constant_expression, ']', '['), choice($.constant_expression, $._constant_part_select_range), ']' ) ), // constant_select1: $ => choice( // reordered -> non empty // // seq( // // repseq('.', $.member_identifier, optional($.constant_bit_select1))), // // '.', $.member_identifier, // // optional($.constant_bit_select1), // // optseq('[', $._constant_part_select_range, ']') // // ), // seq( // $.constant_bit_select1, // optseq('[', $._constant_part_select_range, ']') // ), // seq('[', $._constant_part_select_range, ']'), // ), constant_cast: $ => seq($.casting_type, '\'', '(', $.constant_expression, ')'), _constant_let_expression: $ => $.let_expression, cast: $ => seq($.casting_type, '\'', '(', $.expression, ')'), // A.8.5 Expression left-side values net_lvalue: $ => choice( seq( $.ps_or_hierarchical_net_identifier, optional($.constant_select1) ), prec.left(PREC.CONCAT, seq('{', sep1(',', $.net_lvalue), '}')), seq( optional($._assignment_pattern_expression_type), $.assignment_pattern_net_lvalue ) ), variable_lvalue: $ => choice( prec.left(PREC.PARENT, seq( optional(choice( seq($.implicit_class_handle, '.'), $.package_scope )), $._hierarchical_variable_identifier, optional($.select1) )), prec.left(PREC.CONCAT, seq('{', sep1(',', $.variable_lvalue), '}')), prec.left(PREC.ASSIGN, seq( optional($._assignment_pattern_expression_type), $.assignment_pattern_variable_lvalue )), $.streaming_concatenation ), nonrange_variable_lvalue: $ => prec.left(PREC.PARENT, seq( optional(choice( seq($.implicit_class_handle, '.'), $.package_scope )), $._hierarchical_variable_identifier, optional($.nonrange_select1) )), // A.8.6 Operators unary_operator: $ => choice( '+', '-', '!', '~', '&', '~&', '|', '~|', '^', '~^', '^~' ), inc_or_dec_operator: $ => choice('++', '--'), // unary_module_path_operator = '~&' / // '~|' / // '~^' / // '^~' / // $('!'![ != ]) / // $('~'!'=') / // $('&'!'=') / // $('|'!'=') / // $('^'!'=') // // binary_module_path_operator = $('=='!'=') / // $('!='!'=') / // '&&' / // '||' / // $('&'!'=') / // $('|'!'=') / // $('^'!'=') / // '^~' / // '~^' /* A.8.7 Numbers */ _number: $ => choice($.integral_number, $.real_number), integral_number: $ => choice( $.decimal_number, $.octal_number, $.binary_number, $.hex_number ), decimal_number: $ => choice( $.unsigned_number, token(seq( optseq(/[1-9][0-9_]*/, /\s*/), /'[sS]?[dD]/, /\s*/, /[0-9][0-9_]*/ )), token(seq( optseq(/[1-9][0-9_]*/, /\s*/), /'[sS]?[dD]/, /\s*/, /[xXzZ?][_]*/ )) ), binary_number: $ => token(seq( optseq(/[1-9][0-9_]*/, /\s*/), /'[sS]?[bB]/, /\s*/, /[01xXzZ?][01xXzZ?_]*/ )), octal_number: $ => token(seq( optseq(/[1-9][0-9_]*/, /\s*/), /'[sS]?[oO]/, /\s*/, /[0-7xXzZ?][0-7xXzZ?_]*/ )), hex_number: $ => token(seq( optseq(/[1-9][0-9_]*/, /\s*/), /'[sS]?[hH]/, /\s*/, /[0-9a-fA-FxXzZ?][0-9a-fA-FxXzZ?_]*/ )), // NOTE: Embedded spaces are illegal. non_zero_unsigned_number: $ => token(/[1-9][0-9_]*/), real_number: $ => choice( $.fixed_point_number, token(/[0-9][0-9_]*(\.[0-9][0-9_]*)?[eE][+-]?[0-9][0-9_]*/) ), fixed_point_number: $ => token(/[0-9][0-9_]*\.[0-9][0-9_]*/), unsigned_number: $ => token(/[0-9][0-9_]*/), // The apostrophe ( ' ) in unbased_unsized_literal shall not be followed by white_space. unbased_unsized_literal: $ => choice('\'0', '\'1', /'[xXzZ]/), /* A.9 General */ /* A.9.1 Attributes */ attribute_instance: $ => seq('(*', sep1(',', $.attr_spec), '*)'), attr_spec: $ => seq($._attr_name, optseq('=', $.constant_expression)), _attr_name: $ => $._identifier, /* A.9.2 Comments */ // comment: $ => one_line_comment | block_comment // one_line_comment: $ => // comment_text \n // block_comment: $ => /* comment_text */ // comment_text: $ => { Any_ASCII_character } // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890 // from: https://github.com/tree-sitter/tree-sitter-c/blob/master/grammar.js comment: $ => token(choice( seq('//', /.*/), seq( '/*', /[^*]*\*+([^/*][^*]*\*+)*/, '/' ) )), /* A.9.3 Identifiers */ _array_identifier: $ => $._identifier, _block_identifier: $ => $._identifier, _bin_identifier: $ => $._identifier, c_identifier: $ => /[a-zA-Z_][a-zA-Z0-9_]*/, cell_identifier: $ => alias($._identifier, $.cell_identifier), checker_identifier: $ => alias($._identifier, $.checker_identifier), class_identifier: $ => alias($._identifier, $.class_identifier), class_variable_identifier: $ => $._variable_identifier, clocking_identifier: $ => alias($._identifier, $.clocking_identifier), config_identifier: $ => alias($._identifier, $.config_identifier), const_identifier: $ => alias($._identifier, $.const_identifier), constraint_identifier: $ => alias($._identifier, $.constraint_identifier), covergroup_identifier: $ => alias($._identifier, $.covergroup_identifier), // covergroup_variable_identifier = _variable_identifier cover_point_identifier: $ => alias($._identifier, $.cover_point_identifier), cross_identifier: $ => alias($._identifier, $.cross_identifier), dynamic_array_variable_identifier: $ => alias($._variable_identifier, $.dynamic_array_variable_identifier), enum_identifier: $ => alias($._identifier, $.enum_identifier), escaped_identifier: $ => seq('\\', /[^\s]*/), formal_identifier: $ => alias($._identifier, $.formal_identifier), formal_port_identifier: $ => alias($._identifier, $.formal_port_identifier), function_identifier: $ => alias($._identifier, $.function_identifier), generate_block_identifier: $ => alias($._identifier, $.generate_block_identifier), genvar_identifier: $ => alias($._identifier, $.genvar_identifier), _hierarchical_array_identifier: $ => $.hierarchical_identifier, _hierarchical_block_identifier: $ => $.hierarchical_identifier, _hierarchical_event_identifier: $ => $.hierarchical_identifier, hierarchical_identifier: $ => prec.left(seq( optseq('$root', '.'), repseq($._identifier, optional($.constant_bit_select1), '.'), $._identifier )), _hierarchical_net_identifier: $ => $.hierarchical_identifier, _hierarchical_parameter_identifier: $ => $.hierarchical_identifier, _hierarchical_property_identifier: $ => $.hierarchical_identifier, _hierarchical_sequence_identifier: $ => $.hierarchical_identifier, _hierarchical_task_identifier: $ => $.hierarchical_identifier, _hierarchical_tf_identifier: $ => $.hierarchical_identifier, _hierarchical_variable_identifier: $ => $.hierarchical_identifier, _identifier: $ => choice( $.simple_identifier, $.escaped_identifier ), index_variable_identifier: $ => alias($._identifier, $.index_variable_identifier), interface_identifier: $ => alias($._identifier, $.interface_identifier), interface_instance_identifier: $ => alias($._identifier, $.interface_instance_identifier), inout_port_identifier: $ => alias($._identifier, $.inout_port_identifier), input_port_identifier: $ => alias($._identifier, $.input_port_identifier), instance_identifier: $ => alias($._identifier, $.instance_identifier), library_identifier: $ => alias($._identifier, $.library_identifier), member_identifier: $ => alias($._identifier, $.member_identifier), method_identifier: $ => alias($._identifier, $.method_identifier), modport_identifier: $ => alias($._identifier, $.modport_identifier), _module_identifier: $ => $._identifier, _net_identifier: $ => $._identifier, _net_type_identifier: $ => $._identifier, output_port_identifier: $ => alias($._identifier, $.output_port_identifier), package_identifier: $ => alias($._identifier, $.package_identifier), package_scope: $ => choice( seq($.package_identifier, '::'), seq('$unit', '::') ), parameter_identifier: $ => alias($._identifier, $.parameter_identifier), port_identifier: $ => alias($._identifier, $.port_identifier), production_identifier: $ => alias($._identifier, $.production_identifier), program_identifier: $ => alias($._identifier, $.program_identifier), property_identifier: $ => alias($._identifier, $.property_identifier), ps_class_identifier: $ => seq( optional($.package_scope), $.class_identifier ), ps_covergroup_identifier: $ => seq( optional($.package_scope), $.covergroup_identifier ), ps_checker_identifier: $ => seq( optional($.package_scope), $.checker_identifier ), ps_identifier: $ => seq( optional($.package_scope), $._identifier ), ps_or_hierarchical_array_identifier: $ => seq( optional(choice( seq($.implicit_class_handle, '.'), $.class_scope, $.package_scope )), $._hierarchical_array_identifier ), ps_or_hierarchical_net_identifier: $ => choice( prec.left(PREC.PARENT, seq(optional($.package_scope), $._net_identifier)), $._hierarchical_net_identifier ), ps_or_hierarchical_property_identifier: $ => choice( seq(optional($.package_scope), $.property_identifier), $._hierarchical_property_identifier ), ps_or_hierarchical_sequence_identifier: $ => choice( seq(optional($.package_scope), $._sequence_identifier), $._hierarchical_sequence_identifier ), ps_or_hierarchical_tf_identifier: $ => choice( seq(optional($.package_scope), $.tf_identifier), $._hierarchical_tf_identifier ), ps_parameter_identifier: $ => choice( seq( optional(choice( $.package_scope, $.class_scope )), $.parameter_identifier ), seq( repseq( $.generate_block_identifier, optseq('[', $.constant_expression, ']'), '.' ), $.parameter_identifier ) ), ps_type_identifier: $ => seq( optional(choice( seq('local', '::'), $.package_scope, $.class_scope )), $._type_identifier ), _sequence_identifier: $ => $._identifier, _signal_identifier: $ => $._identifier, // A simple_identifier or c_identifier shall // start with an alpha or underscore ( _ ) character, // shall have at least one character, and shall not have any spaces. simple_identifier: $ => /[a-zA-Z_][a-zA-Z0-9_$]*/, specparam_identifier: $ => alias($._identifier, $.specparam_identifier), // The $ character in a system_tf_identifier shall // not be followed by white_space. A system_tf_identifier shall not be escaped. system_tf_identifier: $ => /\$[a-zA-Z0-9_$]+/, task_identifier: $ => alias($._identifier, $.task_identifier), tf_identifier: $ => alias($._identifier, $.tf_identifier), terminal_identifier: $ => alias($._identifier, $.terminal_identifier), topmodule_identifier: $ => alias($._identifier, $.topmodule_identifier), _type_identifier: $ => $._identifier, _udp_identifier: $ => $._identifier, _variable_identifier: $ => $._identifier /* A.9.4 White space */ // white_space: $ => space | tab | newline | eof}; }; module.exports = grammar({ name: 'verilog', word: $ => $.simple_identifier, rules: rules, extras: $ => [/\s/, $.comment], inline: $ => [ $.hierarchical_identifier, $._hierarchical_net_identifier, $._hierarchical_variable_identifier, $._hierarchical_tf_identifier, $._hierarchical_sequence_identifier, $._hierarchical_property_identifier, $._hierarchical_block_identifier, $._hierarchical_task_identifier, $.ps_or_hierarchical_net_identifier, $.ps_or_hierarchical_tf_identifier, $.ps_or_hierarchical_sequence_identifier, $.ps_or_hierarchical_property_identifier, $.ps_class_identifier, $.ps_covergroup_identifier, $.ps_parameter_identifier, $.ps_type_identifier, $.ps_checker_identifier, $.parameter_identifier, $.class_identifier, $.covergroup_identifier, $.enum_identifier, $.formal_port_identifier, $.genvar_identifier, $.specparam_identifier, $.tf_identifier, $._type_identifier, $._net_type_identifier, $._variable_identifier, $._udp_identifier, $.package_identifier, $.dynamic_array_variable_identifier, $.class_variable_identifier, $.interface_instance_identifier, $.interface_identifier, $._module_identifier, $.let_identifier, $.sequence_identifier, $._net_identifier, $.program_identifier, $.checker_identifier, $.member_identifier, $.port_identifier, $._block_identifier, $.instance_identifier, $.property_identifier, // $.input_port_identifier, // $.output_port_identifier, // $.inout_port_identifier, // $.input_identifier, // $.output_identifier, $.cover_point_identifier, $.cross_identifier ], conflicts: $ => [ [$.constant_primary, $.primary], [$.primary, $.implicit_class_handle], [$.primary, $.constant_function_call], [$.primary, $.param_expression], [$.primary, $._constant_let_expression], [$.primary, $.queue_dimension], [$._module_common_item, $._checker_or_generate_item], [$._module_common_item, $._checker_generate_item], [$.dpi_function_import_property, $.dpi_task_import_property], [$.package_or_generate_item_declaration, $.checker_or_generate_item_declaration], [$._module_or_generate_item_declaration, $.checker_or_generate_item_declaration], [$.module_or_generate_item, $.interface_or_generate_item], [$.method_call_body, $.array_method_name], [$.constraint_set, $.empty_unpacked_array_concatenation], [$.interface_declaration, $._non_port_interface_item], [$.program_declaration, $.non_port_program_item], [$.list_of_ports, $.list_of_port_declarations], [$.mintypmax_expression, $.expression_or_dist], [$.class_constructor_declaration, $.implicit_class_handle], [$.statement_or_null, $.action_block], // [$.port_reference, $.ansi_port_declaration], [$.port, $.ansi_port_declaration], [$.net_port_header1, $.variable_port_header], [$.ansi_port_declaration, $._variable_dimension], [$.module_declaration, $._non_port_module_item], [$._expression_or_cond_pattern, $.tagged_union_expression], [$.pattern, $.tagged_union_expression], [$.mintypmax_expression, $._covergroup_expression], [$.concatenation, $._covergroup_expression], [$.concatenation, $.stream_expression], [$.delay2, $.delay_control], [$.delay3, $.delay_control], [$.delay_control, $.param_expression], [$.delay2, $.delay_control, $.param_expression], [$.property_spec, $.property_expr], [$.property_expr, $.sequence_expr], [$.select1, $.bit_select1], [$.select1, $.nonrange_select1], // [$.class_method, $.constraint_prototype_qualifier], [$.class_method, $.method_qualifier], // [$.bind_target_scope, $.bind_target_instance], [$.class_type, $.package_scope], [$.data_type_or_implicit1, $._var_data_type], [$.list_of_port_identifiers, $.list_of_variable_identifiers], [$.list_of_port_identifiers, $.list_of_variable_port_identifiers], [$.list_of_interface_identifiers, $.net_decl_assignment], [$.class_type, $.tf_port_item1, $.data_type], [$.net_port_type1, $.interface_port_header, $.data_type, $.class_type], [$.net_port_type1, $.data_type, $.class_type], [$.list_of_port_identifiers, $._variable_dimension], [$.property_expr, $._sequence_actual_arg], [$.event_control, $._hierarchical_event_identifier, $._sequence_identifier], [$.event_control, $._hierarchical_event_identifier], [$.sequence_list_of_arguments, $.let_list_of_arguments], [$.input_identifier, $.output_identifier], [$.constant_primary, $.path_delay_expression], [$.unary_operator, $.scalar_timing_check_condition], [$.mintypmax_expression, $.scalar_timing_check_condition], [$.delayed_data, $.delayed_reference], [$.system_tf_call, $.list_of_arguments_parent], [$.class_item_qualifier, $.lifetime], [$._property_qualifier, $.method_qualifier], [$.class_property, $.data_type_or_implicit1], [$.mintypmax_expression, $.list_of_arguments_parent], [$.module_path_primary, $.tf_call], [$.package_declaration, $._package_item], [$.deferred_immediate_assertion_item, $.generate_block_identifier, $.concurrent_assertion_item], [$.variable_lvalue, $.clockvar], [$.combinational_entry, $._seq_input_list], ] .concat(combi([ $.constant_primary, $.primary, $.let_expression, $.tf_call, $.select_expression, ])) .concat(combi([ $.constant_primary, // $._simple_type, $.primary, $.variable_lvalue, $.net_lvalue, $.port_reference, $.sequence_instance, $.let_expression, // $.pattern, $.tf_call, // $.terminal_identifier, // $.select_expression, $.generate_block_identifier, $._sequence_identifier, $._assignment_pattern_expression_type, $.list_of_arguments_parent, $.module_path_primary, $.data_type, $.class_type, ])) .concat(combi([ $.primary, // + $.sequence_instance, // + $.let_expression, // ++ $.tf_call, // ++ $.terminal_identifier, // ++ $._sequence_identifier, // + ])) .concat(combi([ $.variable_lvalue, $.net_lvalue, ])) .concat(combi([ $.constant_primary, $._simple_type, $.primary, $.generate_block_identifier, ])) .concat(combi([ $.module_instantiation, $.net_declaration, $.net_type_declaration, $.interface_port_declaration, $.interface_instantiation, $.program_instantiation, $.udp_instantiation, $.checker_instantiation, $.data_type, $.class_type, ])) .concat(combi([ $.variable_lvalue, $.nonrange_variable_lvalue, $._method_call_root, $.class_qualifier ])) .concat(combi([ $.variable_decl_assignment, $.packed_dimension, $._variable_dimension ])) .concat(combi([ $.constant_primary, $._simple_type, $._assignment_pattern_expression_type, $.class_qualifier, $.data_type, ])) .concat(combi([ $._constant_range_expression, // $.constant_bit_select1, $.constant_select1, $.unpacked_dimension, ])) .concat(combi([ $.packed_dimension, $.unpacked_dimension, $._constant_part_select_range, $._part_select_range ])) .concat(combi([ $.inout_port_identifier, $.input_port_identifier, $.output_port_identifier ])) .concat(combi([ $.named_port_connection, $.hierarchical_instance, $.checker_instantiation ])) .concat(combi([ $.named_port_connection, $.ordered_port_connection, $._sequence_actual_arg, $.expression_or_dist, $.let_actual_arg, $.list_of_arguments_parent, $.event_expression, ])) .concat(combi([ $.primary, $.module_path_primary, $.constant_function_call, $.primary_literal, ])) }); /* eslint camelcase: 0 */ /* eslint no-undef: 0 */ /* eslint no-unused-vars: 0 */