def char_options_to_regex(r: Antlr4Rule):
    """
    '0' | '1' -> [01]
    """
    def match_replace_fn(o):
        if isinstance(o, Antlr4Selection):
            char_symb_to_replace = []
            for orig_c in o:
                c = orig_c
                if isinstance(c, Antlr4Sequence):
                    if len(c) > 1:
                        continue
                    else:
                        c = c[0]
                if isinstance(c, Antlr4Symbol) and c.is_terminal and len(
                        c.symbol) == 1:
                    char_symb_to_replace.append((orig_c, c))
            if len(char_symb_to_replace) > 1:
                # build an regex out of them
                # and replace them by the regex
                for c, _ in char_symb_to_replace:
                    o.remove(c)

                re_str = "[%s]" % ("".join(
                    [c._escaped() for _, c in char_symb_to_replace]))
                re = Antlr4Symbol(re_str, True, is_regex=True)
                if len(o):
                    o.append(re)
                else:
                    return Antlr4Sequence([
                        re,
                    ])

    replace_item_by_sequence(r, match_replace_fn)
예제 #2
0
def remove_any_visuals(rules):
    def match_replace_fn(o):
        if isinstance(o, (Antlr4Indent, Antlr4Newline)):
            return Antlr4Sequence([])

    for r in rules:
        replace_item_by_sequence(r.body, match_replace_fn)
예제 #3
0
def rm_ambiguity(rules):
    rule = rule_by_name(rules, "variable_decl_assignment")
    to_repl = Antlr4parser().from_str("( ASSIGN class_new )?")

    def match_replace_fn(o):
        if o == to_repl:
            return o.body

    replace_item_by_sequence(rule, match_replace_fn)
예제 #4
0
def fix_dpi_import_export(rules):
    C_IDENTIFIER = Antlr4Symbol("C_IDENTIFIER", False)

    def match_replace_fn(o):
        if o == C_IDENTIFIER:
            return Antlr4Selection(
                [C_IDENTIFIER,
                 Antlr4Symbol("ESCAPED_IDENTIFIER", False)])

    r = rule_by_name(rules, "dpi_import_export")
    replace_item_by_sequence(r.body, match_replace_fn)
예제 #5
0
    def optimize(self, rules):
        for r in rules:
            if r.optimalizer_keep_out:
                continue
            first = True
            while first or self.modified:
                self.modified = False
                first = False
                replace_item_by_sequence(r, self.match_replace_fn)

            if r.is_lexer_rule():
                char_options_to_regex(r)
예제 #6
0
def rm_semi_from_cross_body_item(rules):
    """
    Because SEMI is already part of cross_body_item
    """
    rule = rule_by_name(rules, "cross_body")
    semi = Antlr4Symbol("SEMI", False)

    def match_replace_fn(o):
        if o == semi:
            return Antlr4Sequence([])

    replace_item_by_sequence(rule.body[0], match_replace_fn)
예제 #7
0
def add_interface_class_declaration(rules):
    """
    Because interface_class_definition is not used anywhere
    (is missing in specified rules)
    """
    intf = Antlr4Symbol("interface_class_declaration", False)
    cls = Antlr4Symbol("class_declaration", False)

    def match_replace_fn(o):
        if o == cls:
            return Antlr4Selection([o, deepcopy(intf)])

    for rule in rules:
        replace_item_by_sequence(rule, match_replace_fn)
예제 #8
0
def add_predicated_for_CLONE_ID_after_obj(rules, target_lang):
    c_id = Antlr4parser().from_str("( COLON identifier )?")
    la1 = target_lang.LA(1)

    def match_replace_fn(o: iAntlr4GramElem):
        if o == c_id:
            return Antlr4Selection([
                    o.body,
                    Antlr4Sequence([
                        Antlr4Symbol("{%s != COLON}?" % la1, True, True),
                    ])
                    ])

    for r in rules:
        replace_item_by_sequence(r.body, match_replace_fn)
예제 #9
0
def remove_ambiguous_else_from_if_else_constructs(rules, target_lang):
    kw_else = Antlr4Symbol("KW_ELSE", False)
    la1 = target_lang.LA(1)

    def match_replace_fn(o: iAntlr4GramElem):
        if isinstance(o, Antlr4Option) and isinstance(o.body, Antlr4Sequence):
            if o.body[0] == kw_else:
                return Antlr4Selection([
                    o.body,
                    Antlr4Sequence([
                        Antlr4Symbol("{%s != KW_ELSE}?" % la1, True, True),
                    ])
                    ])

    for r in rules:
        replace_item_by_sequence(r.body, match_replace_fn)
예제 #10
0
def move_iteration_up_in_parse_tree(rules, rule_name):
    r = rule_by_name(rules, rule_name)

    # remove ()* from the rule body
    if isinstance(r.body, Antlr4Sequence):
        assert len(r.body) == 1, r.body
        r.body = r.body[0]
    assert isinstance(r.body, Antlr4Iteration) and not r.body.positive
    r.body = r.body.body

    # wrap rule appearence in ()*
    r_symb = Antlr4Symbol(rule_name, False)

    def match_replace_fn(o):
        if o == r_symb:
            return Antlr4Iteration(o, positive=False)

    for r in rules:
        replace_item_by_sequence(r.body, match_replace_fn)
예제 #11
0
def fix_SYSTEM_TF_IDENTIFIER(rules):
    kws = collect_keywords(rules)
    SYSTEM_TF_IDENTIFIER = Antlr4Symbol("SYSTEM_TF_IDENTIFIER", False)
    any_system_tf_identifier = Antlr4Symbol("any_system_tf_identifier", False)

    def match_replace_fn(o):
        if o == SYSTEM_TF_IDENTIFIER:
            return deepcopy(any_system_tf_identifier)

    for rule in rules:
        replace_item_by_sequence(rule, match_replace_fn)

    rules.append(
        Antlr4Rule(
            "any_system_tf_identifier",
            Antlr4Selection([
                SYSTEM_TF_IDENTIFIER, *[
                    Antlr4Symbol(kw.replace("$", "KW_DOLAR_").upper(), False)
                    for kw in kws if kw.startswith("$")
                ]
            ])))
예제 #12
0
def fix_implications(rules):
    """
    :note: variants of implications are as a independent tokens, otherwise lexer parses it as -= > instead of - =>
    """
    any_impl_rule = Antlr4Rule(
        "any_implication",
        Antlr4parser().from_str("IMPLIES | IMPLIES_P | IMPLIES_N"))
    orig = Antlr4parser().from_str("( polarity_operator )? IMPLIES")

    def apply_rewrite(o):
        if isinstance(o, Antlr4Sequence):
            found_i = None
            for i, o2 in enumerate(o):
                if o2.eq_relaxed(orig[0]) and o[i + 1].eq_relaxed(orig[1]):
                    found_i = i
                    break
            if found_i is not None:
                del o[found_i + 1]
                o[found_i] = Antlr4Symbol(any_impl_rule.name, False)

    for r in rules:
        replace_item_by_sequence(r, apply_rewrite)

    rules.append(any_impl_rule)
예제 #13
0
def rm_option_from_eps_rules(p):
    already_eps_rules = [
        "tf_port_list",
        "data_type_or_implicit",
        "list_of_arguments",
        "let_list_of_arguments",
        "list_of_port_connections",
        "list_of_checker_port_connections",
        "sequence_list_of_arguments",
        "property_list_of_arguments",
    ]
    # because it already can be eps
    for r in already_eps_rules:
        rm_option_on_rule_usage(p.rules, r)

    # fix optinality on datatypes
    r = rule_by_name(p.rules, "implicit_data_type")
    # : (signing)? (packed_dimension)*
    # ->
    # : signing (packed_dimension)*
    # | (packed_dimension)+
    # ;
    r.body = Antlr4parser().from_str("signing ( packed_dimension )* | ( packed_dimension )+")

    _inline_rules(p.rules, ["variable_port_header", "net_port_header", "interface_port_header"])
    # make data_type_or_implicit optional 
    for r in p.rules:
        to_optional = [
            "port",
            "function_data_type_or_implicit",
            "var_data_type",
            "property_formal_type",
            "let_formal_type",
            "net_port_type"]
        if r.name not in ["sequence_formal_type",
                          "let_formal_type", ]:
            to_optional.append("data_type_or_implicit")
        if r.name not in ["data_type_or_implicit", "function_data_type_or_implicit"]:
            to_optional.append("implicit_data_type")
        if r.name != "property_formal_type":
            to_optional.append("sequence_formal_type")

        def match_replace_fn(o):
            if isinstance(o, Antlr4Symbol) and o.symbol in to_optional:
                return Antlr4Option(o)

        replace_item_by_sequence(r, match_replace_fn)

        if r.name == "net_port_type":
            # net_port_type:
            #       ( net_type )? data_type_or_implicit 
            #       | identifier 
            #       | KW_INTERCONNECT implicit_data_type;
            r.body[1] = Antlr4parser().from_str("data_type_or_implicit")
            r.body[0] = Antlr4parser().from_str("net_type ( data_type_or_implicit )?")

    port = rule_by_name(p.rules, "port")
    #      ( port_expression )? 
    #  | DOT identifier LPAREN ( port_expression )? RPAREN;
    port.body[0] = Antlr4Symbol("port_expression", False)
    # var_data_type: data_type | KW_VAR data_type_or_implicit;
    # var_data_type = rule_by_name(p.rules, "var_data_type")
    # var_data_type.body = Antlr4parser().from_str("KW_VAR ( data_type_or_implicit )? | data_type_or_implicit")

    pa = Antlr4parser()
    data_declaration = rule_by_name(p.rules, "data_declaration")
    assert data_declaration.body[0].eq_relaxed(
       pa.from_str("""( KW_CONST )? ( KW_VAR )? ( lifetime )? ( data_type_or_implicit )? 
                                    list_of_variable_decl_assignments SEMI"""))
    data_declaration.body[0] = pa.from_str("""( KW_CONST )? ( KW_VAR ( lifetime )?  ( data_type_or_implicit )? | ( lifetime )? data_type_or_implicit )   
                                    list_of_variable_decl_assignments SEMI""")
예제 #14
0
def optimize_class_scope(rules):
    p = Antlr4parser()
    to_replace0 = p.from_str("( package_scope | class_scope )? identifier")
    to_replace1 = p.from_str("( class_scope | package_scope )? identifier")

    package_or_class_scoped_id = Antlr4Rule("package_or_class_scoped_id", p.from_str(
        """( identifier ( parameter_value_assignment )? | KW_DOLAR_UNIT )
           ( DOUBLE_COLON identifier ( parameter_value_assignment )? )*"""))
    rules.append(package_or_class_scoped_id)

    def match_replace_fn_reduce_1_item_sequence(o):
        if isinstance(o, Antlr4Sequence) and len(o) == 1:
            return o[0]

    q0 = Antlr4Query(to_replace0)
    q1 = Antlr4Query(to_replace1)

    for r in rules:
        replace_item_by_sequence(r, match_replace_fn_reduce_1_item_sequence)
        # if r.name == "net_type_declaration":
        #     print(r.toAntlr4())
        m = q0.match(r.body)
        if not m:
            m = q1.match(r.body)
        if m:

            def apply_to_replace0_and_1(o):
                for match in m:
                    v = match.get(id(o), None)
                    if v is not None:
                        del match[id(o)]
                        if (v is to_replace0
                             or v is to_replace1
                             or (isinstance(v, Antlr4Symbol) and v.symbol == "identifier")):
                            return Antlr4Symbol(package_or_class_scoped_id.name, False)
                        else:
                            return Antlr4Sequence([])

            replace_item_by_sequence(r, apply_to_replace0_and_1)
            for _m in m:
                # assert that all matching items were replaced
                assert not _m
        #    print(r.toAntlr4())
        #    print(m)
        # else:
        #     if "package_scope | class_scope" in r.toAntlr4() or "class_scope | package_scope" in r.toAntlr4():
        #         print("not found " + r.toAntlr4())

    # class_qualifier:
    #   ( KW_LOCAL DOUBLE_COLON )? ( implicit_class_handle DOT 
    #                            | class_scope 
    #                            )?;
    # class_scope:
    #     ps_identifier ( parameter_value_assignment )? 
    #     ( DOUBLE_COLON identifier 
    #       ( parameter_value_assignment )?
    #     )* DOUBLE_COLON;
    # implicit_class_handle:
    #     KW_THIS ( DOT KW_SUPER )? 
    #      | KW_SUPER 
    # ;
    # package_scope:
    #  ( KW_DOLAR_UNIT 
    #    | identifier 
    #  ) DOUBLE_COLON;
    # hierarchical_identifier: ( KW_DOLAR_ROOT DOT )? ( identifier constant_bit_select DOT )* identifier;
    to_replace2 = p.from_str("( class_qualifier | package_scope )? hierarchical_identifier")
    package_or_class_scoped_path = Antlr4Rule("package_or_class_scoped_path", p.from_str("""
        ( KW_LOCAL DOUBLE_COLON )?
        ( 
          KW_DOLAR_ROOT
          | implicit_class_handle
          | ( 
              ( 
                  KW_DOLAR_UNIT  
                | identifier ( parameter_value_assignment )? 
              )
              ( DOUBLE_COLON identifier ( parameter_value_assignment )? )*
           )
        )
    """))
    package_or_class_scoped_hier_id_with_const_select = Antlr4Rule(
        "package_or_class_scoped_hier_id_with_const_select",
        p.from_str("""
            package_or_class_scoped_path
            ( constant_bit_select )* ( DOT identifier ( constant_bit_select )* )*
    """))

    # bit_select:
    #  LSQUARE_BR expression RSQUARE_BR;
    # select:
    #  ( DOT identifier 
    #   | bit_select 
    #   )* ( LSQUARE_BR part_select_range RSQUARE_BR )?;
    # part_select_range:
    #  constant_range 
    #   | indexed_range 
    #  ;
    # indexed_range:
    #  expression ( PLUS 
    #               | MINUS 
    #               ) COLON constant_expression;
    # constant_range:
    #  constant_expression COLON constant_expression;

    package_or_class_scoped_hier_id_with_select = Antlr4Rule(
        "package_or_class_scoped_hier_id_with_select",
        p.from_str("""
            package_or_class_scoped_path
            ( bit_select )* ( DOT identifier ( bit_select )* )*
            ( LSQUARE_BR expression ( PLUS | MINUS )? COLON constant_expression RSQUARE_BR )?
    """))
    rules.append(package_or_class_scoped_path)
    rules.append(package_or_class_scoped_hier_id_with_const_select)
    rules.append(package_or_class_scoped_hier_id_with_select)
    primary_no_cast_no_call = rule_by_name(rules, "primary_no_cast_no_call")
    m = Antlr4Query(to_replace2).match(primary_no_cast_no_call.body)

    def apply_to_replace2(o):
        for match in m:
            v = match.get(id(o), None)
            if v is not None:
                if (v is to_replace2
                        or (isinstance(v, Antlr4Symbol)
                            and v.symbol == "hierarchical_identifier")):
                    return Antlr4Symbol(package_or_class_scoped_hier_id_with_const_select.name, False)
                else:
                    return Antlr4Sequence([])

    replace_item_by_sequence(primary_no_cast_no_call, apply_to_replace2)

    _optimize_ps_type_identifier(rules)
    _optimize_ps_parameter_identifier(rules)
    rules.remove(rule_by_name(rules, "class_qualifier"))