This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade to Devel::PPPort 3.10_01
[perl5.git] / regen_perly.pl
index 67f763f..f3b3f59 100644 (file)
@@ -11,6 +11,7 @@
 #              #line directives plus adding a #ifdef PERL_CORE
 #
 # perly.tab    the parser table C definitions extracted from the bison output
+#              plus an extra table generated by this script.
 #
 # perly.act    the action case statements extracted from the bison output
 #
@@ -87,6 +88,8 @@ close CTMPFILE;
 
 my ($actlines, $tablines) = extract($clines);
 
+$tablines .= make_opval_tab($y_file, $tablines);
+
 chmod 0644, $act_file;
 open ACTFILE, ">$act_file" or die "can't open $act_file: $!\n";
 print ACTFILE $actlines;
@@ -102,7 +105,8 @@ chmod 0444, $tab_file;
 unlink $tmpc_file;
 
 # Wrap PERL_CORE round the symbol definitions. Also,  the
-# C<#line 123 "perlytmp.h"> gets picked up by make depend, so change it.
+# C<#line 30 "perly.y"> confuses the Win32 resource compiler and the
+# C<#line 188 "perlytmp.h"> gets picked up by make depend, so remove them.
 
 open TMPH_FILE, $tmph_file or die "Can't open $tmph_file: $!\n";
 chmod 0644, $h_file;
@@ -114,7 +118,7 @@ while (<TMPH_FILE>) {
        print H_FILE "#endif /* PERL_CORE */\n";
        $endcore_done = 1;
     }
-    s/"perlytmp.h"/"perly.h"/;
+    next if /^#line \d+ ".*"/;
     print H_FILE $_;
 }
 close TMPH_FILE;
@@ -150,7 +154,7 @@ sub extract {
        switch \s* \( \s* \w+ \s* \) \s* { \s*
        (
            case \s* \d+ \s* : \s*
-           \#line [^\n]+"perly\.y"
+           \#line [^\n]+"\Q$y_file\E"
            .*?
        )
        }
@@ -169,6 +173,45 @@ sub extract {
     return $actlines. "\n", $tablines. "\n";
 }
 
+# read a .y file and extract a list of all the token names and
+# non-terminal names that are declared to be of type opval
+# then scan the string $tablines for the table yytname which gives
+# the token index of each token/non-terminal, then use this to
+# create a new table, indexed by token number, which indicates
+# whether that token is of type opval.
+#
+# ie given
+# %token <opval> A B
+# %type  <opval> C D
+#
+# and yytname[] = { "A" "B", "C", "D", "E", "F" };
+#
+# then return
+# static const int yy_is_opval[] = { 1, 1, 1, 1, 0, 0 }
+
+sub make_opval_tab {
+    my ($y_file, $tablines) = @_;
+    my %tokens;
+    open my $fh, '<', $y_file or die "Can't open $y_file: $!\n";
+    while (<$fh>) {
+       next unless s/^%(token|type)\s+<opval>\s+//;
+       $tokens{$_} =1 for (split ' ', $_);
+    }
+
+    $tablines =~ /^\Qstatic const char *const yytname[] =\E\n
+           {\n
+           (.*?)
+           ^};
+           /xsm
+       or die "Can't extract yytname[] from table string\n";
+    my $fields = $1;
+    $fields =~ s/"([^"]+)"/$tokens{$1}||0/ge;
+    return 
+       "/* which symbols are of type opval */\n" .
+       "static const int yy_is_opval[] =\n{\n" . $fields . "\n};\n";
+}
+
+
 sub my_system {
     system(@_);
     if ($? == -1) {