From 5aebec2cc6dfdf969493a392053cfcf2ba4ddbbe Mon Sep 17 00:00:00 2001 From: Vishal Gupta Date: Sat, 4 Aug 2018 17:56:37 +0530 Subject: Updated include directive and added test cases. After parsing the file given in the include directive, the tree generated is printed to standard input using Data::Dumper and this is evaled in the program having include directive. As a result the tree gets appended to the parent AST. --- lib/Automake/Parser/Lexer.pm | 10 ++++++- lib/Automake/Parser/Tree.pm | 43 +++++++++++++++++++----------- lib/Automake/Parser/input.txt | 3 --- lib/Automake/Parser/parser.pl | 26 +++++++++++++++--- lib/Automake/Parser/t/app/Makefile.am | 2 +- lib/Automake/Parser/t/app/app/Makefile.am | 1 + lib/Automake/Parser/t/app/app3/Makefile.am | 1 - lib/Automake/Parser/t/app1/Makefile.am | 3 ++- lib/Automake/Parser/t/app2/Makefile.am | 3 ++- lib/Automake/Parser/t/app3/Makefile.am | 1 + lib/Automake/Parser/t/app3/app/Makefile.am | 2 ++ lib/Automake/Parser/t/fragment.txt | 3 +++ 12 files changed, 71 insertions(+), 27 deletions(-) delete mode 100644 lib/Automake/Parser/input.txt create mode 100644 lib/Automake/Parser/t/app/app/Makefile.am delete mode 100644 lib/Automake/Parser/t/app/app3/Makefile.am create mode 100644 lib/Automake/Parser/t/app3/Makefile.am create mode 100644 lib/Automake/Parser/t/app3/app/Makefile.am create mode 100644 lib/Automake/Parser/t/fragment.txt diff --git a/lib/Automake/Parser/Lexer.pm b/lib/Automake/Parser/Lexer.pm index 5a206769e..61255d0ad 100644 --- a/lib/Automake/Parser/Lexer.pm +++ b/lib/Automake/Parser/Lexer.pm @@ -6,7 +6,7 @@ our @ISA = qw(Exporter); our @EXPORT = qw(lex); # Store end token. -my @end_tok = ["end"]; +my @end_tok = [ "end" ]; # lex(string,multiline) # Takes as input a string of line and multiline variable deciding whether @@ -84,6 +84,13 @@ sub lex($) push @tokens, [ "newline" ] unless $multiline; $_ = undef; } + elsif( $include ) + { + push @tokens, [ "value" , $1] if m/^\s+(.+)/; + push @tokens, [ "newline" ]; + $include = 0; + last; + } elsif( s/^##.*\n$//o ) { } @@ -104,6 +111,7 @@ sub lex($) elsif( s/^(PROGRAMS|LIBRARIES|LTLIBRARIES|LISP|PYTHON|JAVA|SCRIPTS|DATA|HEADERS|MASN|TEXINFOS|if|else|endif|include)//o) { push @tokens, [$1]; + $include = 1 if ( $1 eq 'include' ); } elsif( s/^([a-zA-Z0-9_]+)//o ) { diff --git a/lib/Automake/Parser/Tree.pm b/lib/Automake/Parser/Tree.pm index e6e9c9836..69153ff5b 100644 --- a/lib/Automake/Parser/Tree.pm +++ b/lib/Automake/Parser/Tree.pm @@ -3,19 +3,24 @@ package Tree; use Exporter; our @ISA = qw(Exporter); -our @EXPORT = qw(input stmts stmt automakerule makerule conditional ifblock -optionalelse optionalcond optionalrhs optionalcomments lhs rhs commentlist primaries +our @EXPORT = qw(basedir input stmts stmt automakerule makerule conditional ifblock +optionalelse optionalcond optionalrhs optionalcomments includerule lhs rhs commentlist primaries optionlist traverse printgraph recursesubdirs); +# Stores whether subdir directive is used or not. If used array +# consist of subdirectories. my $isSubdir = 0 , @subdirnodes = (); +# Stores the value recieved by Parser.pl +our $basedir; + # Grammar Rule : (1) input => stmts # Create a node having child as stmts. sub input($) { my ( $val ) = @_; my %node = ( name => input, childs => [ $val ] ); - push @{$node{childs}}, subdirNode() if $#subdirnodes > -1; + push @{ $node{ childs } }, subdirNode() if $#subdirnodes > -1; return \%node; } @@ -44,7 +49,7 @@ sub stmts($$;$) } else { - push @{$val1 -> { childs }}, $val2; + push @{ $val1 -> { childs } }, $val2; return $val1; } } @@ -70,7 +75,7 @@ sub automakerule($$$$;$) { my ( $val1, $val2, $val3, $val4, $val5 ) = @_; my %node = (name => automakerule, childs => [ $val1 ]); - if($val2->[0] eq '=') + if($val2 -> [0] eq '=') { push @{ $node{ childs }}, $val3; push @{ $node{ childs }}, $val4 if $val4; @@ -89,7 +94,7 @@ sub automakerule($$$$;$) sub makerule($$$) { my ( $val1, $val2, $val3 ) = @_; - my %node = (name => makerule, childs => [ $val1,$val3 ]); + my %node = ( name => makerule, childs => [ $val1,$val3 ]); return \%node; } @@ -296,11 +301,19 @@ sub optionlist($$;$) } } +# Grammar Rule : (1) includerule : include value +# Create a node having the tree after parsing the included value. +# String recieved as standard input is evaled to generate corresponding +# tree. sub includerule($$) { my ( $val1, $val2 ) = @_; - print STDERR $val2; - my %node = (name => includerule, value => $val2); + my $VAL1; + my $file = $val2 -> [1]; + my $data = `parser.pl -include $basedir/$file`; + my %node = %{ eval( $data ) }; + $node{ name } = includerule; + $node{ file } = $val2; return \%node; } @@ -312,7 +325,7 @@ sub printgraph($) print "graph graphname {\n"; my ( $ref ) = @_; print "0 [label=\"Root\"];"; - traverse( $ref, 0); + traverse( $ref, 0 ); print "}\n"; } @@ -324,9 +337,9 @@ my $id = 0; # to Standard Output. Call all its child with Parent Id equal to current Node Id. sub traverse($$) { - my ( $ref,$parent ) = @_; + my ( $ref , $parent ) = @_; my %node = %$ref; - return if $node{empty}; + return if $node{ empty }; $id++; my $curr_id = $id; print "$parent--$id;\n"; @@ -355,12 +368,12 @@ sub traverse($$) } } -# recursesubdirs(Basedir, Reference) +# recursesubdirs( Tree Reference) # Recurse into sub directories to generate AST -sub recursesubdirs($$) +sub recursesubdirs($) { - my ( $basedir , $ref) = @_; - my %node= %$ref; + my ( $ref ) = @_; + my %node = %$ref; if( scalar @{ $node{childs} } == 2) { my $subdirRef = $node{childs} -> [1]; diff --git a/lib/Automake/Parser/input.txt b/lib/Automake/Parser/input.txt deleted file mode 100644 index 618da5261..000000000 --- a/lib/Automake/Parser/input.txt +++ /dev/null @@ -1,3 +0,0 @@ -bin_PROGRAMS = server client -server_SOURCES = server.c -client_SOURCES = client.c diff --git a/lib/Automake/Parser/parser.pl b/lib/Automake/Parser/parser.pl index b2384fab9..d81de0493 100644 --- a/lib/Automake/Parser/parser.pl +++ b/lib/Automake/Parser/parser.pl @@ -12,10 +12,20 @@ use Lexer; use Tree; use ParserTable; use File::Basename; +use Data::Dumper; + +# Checks if the parser is called on a file included using include +# directive in parent file. +my $isinclude = 0; +if( $ARGV[0] eq '-include' ) +{ + $isinclude = 1; + shift @ARGV; +} # Stores the relative path of the Makefile.am file with respect to # current working directory -my $basedir = File::Basename::dirname($ARGV[0]); +$Tree::basedir = File::Basename::dirname($ARGV[0]); # To enable debug mode, use 1 . Prints the parser stack at each # iteration @@ -34,9 +44,17 @@ while ( @stack ) { if($stack[-1] == $ParserTable::accept) { - print STDERR "Complete\n"; - printgraph( $stack[-4] ); - recursesubdirs( $basedir, $stack[-4] ); + if($isinclude) + { + # Dump the tree to standard output. + print Dumper( $stack[-4] ); + } + else + { + print STDERR "Complete\n"; + printgraph( $stack[-4] ); + recursesubdirs( $stack[-4] ); + } last; } while( !@tokens ) diff --git a/lib/Automake/Parser/t/app/Makefile.am b/lib/Automake/Parser/t/app/Makefile.am index 79468923b..c6d6bd097 100644 --- a/lib/Automake/Parser/t/app/Makefile.am +++ b/lib/Automake/Parser/t/app/Makefile.am @@ -1,2 +1,2 @@ bin_PROGRAMS=apple -SUBDIRS = app3 +SUBDIRS = app diff --git a/lib/Automake/Parser/t/app/app/Makefile.am b/lib/Automake/Parser/t/app/app/Makefile.am new file mode 100644 index 000000000..3e4f7cd15 --- /dev/null +++ b/lib/Automake/Parser/t/app/app/Makefile.am @@ -0,0 +1 @@ +bin_PROGRAMS=apple diff --git a/lib/Automake/Parser/t/app/app3/Makefile.am b/lib/Automake/Parser/t/app/app3/Makefile.am deleted file mode 100644 index 3e4f7cd15..000000000 --- a/lib/Automake/Parser/t/app/app3/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -bin_PROGRAMS=apple diff --git a/lib/Automake/Parser/t/app1/Makefile.am b/lib/Automake/Parser/t/app1/Makefile.am index 1566cc4be..3d1c248b0 100644 --- a/lib/Automake/Parser/t/app1/Makefile.am +++ b/lib/Automake/Parser/t/app1/Makefile.am @@ -1 +1,2 @@ -bin_PROGRAMS=apple \ No newline at end of file +bin_PROGRAMS=apple +apple_SOURCES=apple.c diff --git a/lib/Automake/Parser/t/app2/Makefile.am b/lib/Automake/Parser/t/app2/Makefile.am index 1566cc4be..3d1c248b0 100644 --- a/lib/Automake/Parser/t/app2/Makefile.am +++ b/lib/Automake/Parser/t/app2/Makefile.am @@ -1 +1,2 @@ -bin_PROGRAMS=apple \ No newline at end of file +bin_PROGRAMS=apple +apple_SOURCES=apple.c diff --git a/lib/Automake/Parser/t/app3/Makefile.am b/lib/Automake/Parser/t/app3/Makefile.am new file mode 100644 index 000000000..694ae2b1e --- /dev/null +++ b/lib/Automake/Parser/t/app3/Makefile.am @@ -0,0 +1 @@ +include app/Makefile.am diff --git a/lib/Automake/Parser/t/app3/app/Makefile.am b/lib/Automake/Parser/t/app3/app/Makefile.am new file mode 100644 index 000000000..faa681bd5 --- /dev/null +++ b/lib/Automake/Parser/t/app3/app/Makefile.am @@ -0,0 +1,2 @@ +bin_PROGRAMS = apple +apple_SOURCES = apple.c diff --git a/lib/Automake/Parser/t/fragment.txt b/lib/Automake/Parser/t/fragment.txt new file mode 100644 index 000000000..43285fa83 --- /dev/null +++ b/lib/Automake/Parser/t/fragment.txt @@ -0,0 +1,3 @@ +include app1/Makefile.am +include app2/Makefile.am +include app3/Makefile.am -- cgit v1.2.1