# ------------------------------------------------- # 1. Basic building blocks # ------------------------------------------------- my $hex2 = qr/[0-9A-Fa-f]{2}/; # exactly 2 hex digits my $hex2p = qr/[0-9A-Fa-f]{2,}/; # 2 or more hex digits my $hexXp = qr/[0-9A-Fa-fXx]{1,4}/; # 1‑4 hex/X digits my $hexXp8 = qr/[0-9A-Fa-fXx]{1,8}/; # 1‑8 hex/X digits my $opt_h = qr/[Hh]?/; # optional trailing H/h my $quotes = qr/"[^"]*"/; # optional quoted literal # ------------------------------------------------- # 2. Re‑usable sub‑patterns # ------------------------------------------------- my $int = qr/\bINT\s?$hex2$opt_h/; # INT my $mem_addr = qr/\bMEM\s?$hexXp:$hexXp$opt_h/; # MEM : my $mem_long = qr/\bMEM\s?$hexXp8$opt_h/; # MEM my $port_rng = qr/\bPORT\s?$hexXp$opt_h\-$hexXp$opt_h/; # PORT my $port_one = qr/\bPORT\s?$hexXp$opt_h/; # PORT my $hash_ref = qr/\#[0-9A-Z][0-9]{4}\b/; # #<4 digits> my $ea_xhl = qr/\b(?:E?A[XHL])=$hex2p$opt_h/; # EA/XHL assignment my $reglist = qr/ (?:E?[ABCD][XHL]|E?[SD]I|E?[SB]P|[DESC]S)=$hex2p$opt_h /x; # a single register entry my $opt_reglist = qr/ (?:\/$reglist)+ /x; # one or more "/" entries # ------------------------------------------------- # 3. Full pattern with named captures # ------------------------------------------------- my $linking_re = qr/ # 1. INT with optional register list and optional quoted literal (? $int $opt_reglist? $quotes? ) | # 2. INT with only optional quoted literal (? $int $quotes? ) | # 3. EA/XHL with repeated register list and optional quoted literal (? $ea_xhl (?:\/$reglist)* $quotes? ) | # 4. Hash reference (e.g. #A1234) (? $hash_ref ) | # 5. MEM range (addr:addr) with optional quoted literal (? $mem_addr $quotes? ) | # 6. MEM single address with optional quoted literal (? $mem_long $quotes? ) | # 7. @‑reference (addr:addr) with optional quoted literal (? \@$hexXp:$hexXp$opt_h $quotes? ) | # 8. PORT range with optional quoted literal (? $port_rng $quotes? ) | # 9. PORT single value with optional quoted literal (? $port_one $quotes? ) /x; # ------------------------------------------------- # 4. Usage example # ------------------------------------------------- if ( $linking =~ $linking_re) { my %cap = %+; # hash of all named captures if ( $cap{int_full} ) { # handle INT with register list } elsif ( $cap{mem_range} ) { # handle MEM range } # …other branches as needed }