]> git.ipfire.org Git - thirdparty/automake.git/commitdiff
Automatic conversion of bison graph to parsing table.
authorVishal Gupta <vishalgupta7972@gmail.com>
Thu, 31 May 2018 19:01:16 +0000 (00:31 +0530)
committerVishal Gupta <vishalgupta7972@gmail.com>
Thu, 31 May 2018 19:01:16 +0000 (00:31 +0530)
* Converter.pl: Converts graph generated by bison (automake.dot) to table
  used by the parser.
* Makefile: Executes the parser on input.txt file. build target builds the
  grammar and executes Converter.pl
* Lexer.pm: Return "newline" as token instead of "\n".
* automake.y, automake.png: Updated to handle "newline" token.

lib/Automake/Parser/Converter.pl [new file with mode: 0644]
lib/Automake/Parser/Lexer.pm
lib/Automake/Parser/Makefile [new file with mode: 0644]
lib/Automake/Parser/ParserTable.pm
lib/Automake/Parser/automake.png
lib/Automake/Parser/automake.y
lib/Automake/Parser/parser.pl

diff --git a/lib/Automake/Parser/Converter.pl b/lib/Automake/Parser/Converter.pl
new file mode 100644 (file)
index 0000000..70c06b9
--- /dev/null
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+use strict;
+
+#Input data for conversion
+my $data;
+open ( $data , "< automake.dot" );
+
+#Storing parser table
+my @table;
+
+#Stores labels of nodes.
+my @labels;
+
+my $acceptstate = 0;
+
+while( <$data> )
+{
+       if(m/label=\"(.*)\"/)
+       {
+               my $token = $1;
+               if(m/(\d+) -> (\d+)/)
+               {
+                       if($token eq "\$end")
+                       {
+                               $table[ $1 ]{ end } = $2;
+                       }
+                       else
+                       {
+                               $table[ $1 ]{ $token } = $2;
+                       }
+               }
+               elsif(m/State (\d+)\\n/)
+               {
+                       $labels[ $1 ] = $token;
+               }
+       }
+       elsif(m/(\d+) -> "\d+R(\d+)"/)
+       {
+               my $state_number = $1;
+               my $production_number = $2;
+               $labels[$state_number] =~ m/$production_number (.+): (.+)\.\\l/;
+               if($1 eq "\$accept")
+               {
+                       $table[ $state_number ] = {};
+                       $acceptstate = $state_number;
+               }
+               else
+               {
+                       $table[ $state_number ]{ reduce } = [scalar( split( /\s+/ , $2 )) , " \\&$1" ];
+               }
+       }
+}
+
+#Output file
+my $ptable;
+open ( $ptable , ">ParserTable.pm" );
+
+print $ptable "package ParserTable;\n\nuse Exporter;\nuse Tree;\n\nour \@ISA=qw(Exporter);\nour \@Export=qw(\@table \$accept);\n\nour \$accept=$acceptstate;\n\n";
+
+my @data;
+
+for my $href ( @table )
+{
+       my @hashval;
+       for my $key ( keys %$href )
+       {
+               if($key eq "reduce")
+               {
+                       push @hashval , sprintf( "$key => [%s]",join(", ",@{ $href -> { $key } }));
+               }
+               else
+               {
+                       push @hashval, sprintf( "$key => %s",$href -> { $key });
+               }
+       }
+       push @data, sprintf( "{%s}" , join(", " , @hashval ));
+}
+
+print $ptable sprintf( "our \@table=(\n\t\t%s\n);" , join ( ",\n\t\t" , @data ));
\ No newline at end of file
index ed8129a5dabb3b5ec75301f6ff64c55c26fec582..8eff3151c6c2bb94d4c86cc1239e2ebaf5e1e086 100644 (file)
@@ -34,10 +34,14 @@ sub lex($)
                        push @tokens, [$1];
                        $rhs = 1;
                }
-               elsif(s/^(:|\n|_)//o)
+               elsif(s/^(:|_)//o)
                {
                        push @tokens, [$1];
                }
+               elsif(s/^\n//o)
+               {
+                       push @tokens, ["newline"];
+               }
                elsif(s/^(\r| )//o)
                {
                }
diff --git a/lib/Automake/Parser/Makefile b/lib/Automake/Parser/Makefile
new file mode 100644 (file)
index 0000000..fe9e435
--- /dev/null
@@ -0,0 +1,20 @@
+
+all: execute
+
+execute: Lexer.pm Tree.pm ParserTable.pm parser.pl
+       ./Parser.pl
+       unflatten -f -l 5 -c 6 -o ast1.gv ast.gv
+       dot -Tpng ast1.gv > ast.png
+       rm ast1.gv
+       
+build: buildGrammer buildTree
+
+buildGrammer: automake.y
+       bison --graph automake.y
+       rm automake.tab.c
+       unflatten -f -l 5 -c 6 -o automake1.dot automake.dot
+       dot -Tpng automake1.dot > automake.png
+       rm automake1.dot
+
+buildTree: automake.dot Converter.pl
+       ./Converter.pl
\ No newline at end of file
index f918f0519c94a51665ff830946f8f3c193c27fca..5d0404a4c6691697c5bfbee1fec4bd9df32b3eb7 100644 (file)
@@ -3,46 +3,40 @@ package ParserTable;
 use Exporter;
 use Tree;
 
-our @ISA = qw(Exporter);
-our @Export = qw(@table $accept);
+our @ISA=qw(Exporter);
+our @Export=qw(@table $accept);
 
-#Stores the state number where the input is accepted
 our $accept=9;
 
-# Stores the state diagram. Its an array of hashes. Each index corresponds 
-# to ith state. Every key in hash corresponds to a token, value corresponds 
-# to next state. reduce key specifies the reduction of token. Its an array 
-# consisting of number of elements to be reduced and a reference to a function 
-# to create a node.
 our @table=(
-               {value => 1, input => 2, stmts => 3, stmt => 4, lhs => 5, optionlist => 6},
-               {":" => 7, "_" => 8},
+               {value => 1, stmts => 3, stmt => 4, lhs => 5, optionlist => 6, input => 2},
+               {':' => 7, '_' => 8},
                {end => 9},
-               {value => 1, lhs => 5, optionlist => 6, stmt => 10, reduce => [1, \&input]}, #input : stmts
-               {"\n" => 11},
-               {"=" => 12},
-               {value => 13, PROGRAMS => 14, LIBRARIES => 15, LTLIBRARIES => 16, LISP => 17, PYTHON => 18, JAVA => 19, SCRIPTS => 20, DATA => 21, HEADERS => 22, MASN => 23, TEXINFOS => 24, primaries => 25},
+               {reduce => [1,  \&input], optionlist => 6, lhs => 5, stmt => 10, value => 1},
+               {newline => 11},
+               {'=' => 12},
+               {HEADERS => 22, LTLIBRARIES => 16, value => 13, PROGRAMS => 14, LIBRARIES => 15, SCRIPTS => 20, MASN => 23, primaries => 25, TEXINFOS => 24, DATA => 21, JAVA => 19, PYTHON => 18, LISP => 17},
                {rhs => 26},
-               {reduce => [2, \&optionlist]}, #optionlist : value '_'
+               {reduce => [2,  \&optionlist]},
                {},
-               {"\n" => 27},
-               {reduce => [2, \&stmts]}, #stmts : stmt '\n'
+               {newline => 27},
+               {reduce => [2,  \&stmts]},
                {rhs => 28},
-               {"_" =>29, reduce => [1, \&primaries]}, #primaries : value
-               {reduce => [1, \&primaries]}, #primaries : PROGRAMS
-               {reduce => [1, \&primaries]}, #primaries : LIBRARIES
-               {reduce => [1, \&primaries]}, #primaries : LTLIBRARIES
-               {reduce => [1, \&primaries]}, #primaries : LISP
-               {reduce => [1, \&primaries]}, #primaries : PYTHON
-               {reduce => [1, \&primaries]}, #primaries : JAVA
-               {reduce => [1, \&primaries]}, #primaries : SCRIPTS
-               {reduce => [1, \&primaries]}, #primaries : DATA
-               {reduce => [1, \&primaries]}, #primaries : HEADERS
-               {reduce => [1, \&primaries]}, #primaries : MASN
-               {reduce => [1, \&primaries]}, #primaries : TEXINFOS
-               {reduce => [2, \&lhs]}, #lhs : optionlist primaries
-               {reduce => [3, \&stmt]}, #stmt : value ':' rhs
-               {reduce => [3, \&stmts]}, #stmts : stmts stmt '\n'
-               {reduce => [3, \&stmt]}, #stmt : lhs '=' rhs 
-               {reduce => [3, \&optionlist]} #optionlist : optionlist value '_'
-               ); 
\ No newline at end of file
+               {reduce => [1,  \&primaries], '_' => 29},
+               {reduce => [1,  \&primaries]},
+               {reduce => [1,  \&primaries]},
+               {reduce => [1,  \&primaries]},
+               {reduce => [1,  \&primaries]},
+               {reduce => [1,  \&primaries]},
+               {reduce => [1,  \&primaries]},
+               {reduce => [1,  \&primaries]},
+               {reduce => [1,  \&primaries]},
+               {reduce => [1,  \&primaries]},
+               {reduce => [1,  \&primaries]},
+               {reduce => [1,  \&primaries]},
+               {reduce => [2,  \&lhs]},
+               {reduce => [3,  \&stmt]},
+               {reduce => [3,  \&stmts]},
+               {reduce => [3,  \&stmt]},
+               {reduce => [3,  \&optionlist]}
+);
\ No newline at end of file
index c95bbb20a9c686861028c6333381e61fef69a51c..f9a8700242e82d33c2c9d7aa840cc1117de44a5f 100644 (file)
Binary files a/lib/Automake/Parser/automake.png and b/lib/Automake/Parser/automake.png differ
index 9d18adfade6fa27dca329817a11e3fd662c3ef5c..a75adce1cf7b0310eae2087f5d94ea5a956218fe 100644 (file)
@@ -1,9 +1,9 @@
-%token value rhs PROGRAMS LIBRARIES LTLIBRARIES LISP PYTHON JAVA SCRIPTS DATA HEADERS MASN TEXINFOS
+%token value rhs PROGRAMS LIBRARIES LTLIBRARIES LISP PYTHON JAVA SCRIPTS DATA HEADERS MASN TEXINFOS newline
 %%
 
 input : stmts ;
-stmts : stmt '\n'
-               | stmts stmt '\n'
+stmts : stmt newline
+               | stmts stmt newline
 stmt  : lhs '=' rhs  
                | value ':' rhs 
 lhs   : optionlist primaries
index 0163224dee1ca6dfc17917a5823d5943c084bfc0..00555d2208ed720e50ea549477ed9bcc2206ee0d 100644 (file)
@@ -6,12 +6,14 @@ use ParserTable;
 
 my $debug = 0;
 
-open ( data, "<input.txt" );
+#Input file for conversion
+my $data;
+open ( $data, "<input.txt" );
 
 #Stores the list of tokens generated by lexer.
 my @tokens; 
 
-while ( <data> )
+while ( <$data> )
 {
        push @tokens, lex($_);
 }