#!/usr/bin/perl use Parse::RecDescent; use Data::Dumper; $::RD_ERRORS = 1; #Parser dies when it encounters an error $::RD_WARN = 1; #Enable warnings - warn on unused rules &c. $::RD_HINT = 1; # Give out hints to help fix problems. our %DATA; #my $module_grammar = <<'END_OF_MODULE_GRAMMAR'; #start : start_module #start_module : '(module ' name module_values #module_values : '(' section | keypair ')' #section : '(' fp_text #keypair : '(' key value ')' #END_OF_MODULE_GRAMMAR my $net_grammer = <<'END_OF_NET_GRAMMER'; start : nets(s) nets : '(net ' node name ')' { $main::DATA{"NET"}{$item{'node'}} = $item{'name'}; print "$_\n" for @item{'node'}; } node : m/\d+/ name : m/\S+/ END_OF_NET_GRAMMER my $text; open ( BRD, ") { my $new_line = $_; chomp; $text = "$text $new_line"; } $text =~ s/\s+\(/\(/g; # remove white space in front of '(' $text =~ s/\(\s+/\(/g; # remove white space after '(' $text =~ s/\s+\)/\)/g; # remove white space in front of ')' $text =~ s/\)s+/\)/g; # remove white space after ')' # This takes tooooo long silly #$text =~ m/\(kicad_pcb\(version (\d+)\)\(host pcbnew \"(.*)\"\)\(general(.*)\)\(page (\S+)\)\(layers(.*)\)\(setup(.*)\)(\(net .*\))\(net_class/; #my $version = $1; #my $pcbnew_revision = $2; #my $section_general = $3; #my $page = $4; #my $section_layers = $5; #my $section_setup = $6; #my $netlist_map = $7; $text =~ m/^\(kicad_pcb\(version (\d+)\)(\(.*\))\)$/; my $version = $1; $text = $2; #print "D - $version\n"; $text =~ m/^\(host pcbnew \"(.*)\"\)(\(general.*\))$/; my $pcbnew_revision = $1; $text = $2; #print "D - $pcbnew_revision\n"; $text =~ m/^\(general(.*)\)(\(page .*\))$/; my $section_general = $1; $text = $2; $section_general =~ s/\)\(/\)\n\(/g; # put newline between ')(' #print "D - $section_general\n"; $text =~ m/^\(page (\S+)\)(\(layers.*\))$/; my $page = $1; $text = $2; #print "D - $page\n"; $text =~ m/^\(layers(\(.*\))\)(\(setup.*\))$/; my $section_layers = $1; $text = $2; $section_layers =~ s/\)\(/\)\n\(/g; # put newline between ')(' #print "D - $section_layers\n"; $text =~ m/^\(setup(.*\)\))\)(\(net .*\))$/; my $section_setup = $1; $text = $2; $section_setup =~ s/\)\(/\)\n\(/g; # put newline between ')(' #print "D - $section_setup\n"; $text =~ m/^(\(net .*\))(\(net_class.*)$/; my $netlist_map = $1; $text = $2; $netlist_map =~ s/\)\(/\)\n\(/g; # put newline between ')(' print "D - $netlist_map\n"; my $parser = Parse::RecDescent->new($net_grammar) or die "Bad grammar!\n"; defined $parser->start($netlist_map) or die "Text doesn't match"; foreach my $KEY (keys %($DATA{"NET"})) { print "$KEY\n"; } exit; #### >./parse_kicad_pcb.pl D - (net 0 "") (net 1 +9V) (net 2 /CLK) (net 3 /DO) (net 4 /Data_In) (net 5 /SCL) (net 6 /SDA) (net 7 /SET_Horz) (net 8 /SET_Vert) (net 9 /~Horz_ON) (net 10 /~RESET) (net 11 /~Vert_ON) (net 12 5V_ATTINY84P) (net 13 GND) (net 14 N-000001) (net 15 N-0000018) (net 16 N-0000019) (net 17 N-000002) (net 18 N-0000021) (net 19 N-0000024) (net 20 N-0000026) (net 21 N-0000027) (net 22 N-0000028) (net 23 N-0000029) (net 24 N-000003) (net 25 N-0000030) (net 26 N-0000031) (net 27 N-0000032) (net 28 N-0000034) (net 29 N-0000036) (net 30 N-0000037) (net 31 N-0000038) (net 32 N-0000039) (net 33 N-0000040) (net 34 N-0000041) (net 35 N-0000042) (net 36 N-0000043) (net 37 N-0000044) (net 38 N-0000045) (net 39 N-0000046) (net 40 N-0000047) (net 41 N-0000048) (net 42 N-0000049) (net 43 N-0000050) (net 44 N-000009) Unknown starting rule (Parse::RecDescent::namespace000001::start) called at ./parse_kicad_pcb.pl line 93.