diff options
| author | Adam Russell <ac.russell@live.com> | 2019-07-21 02:56:19 -0400 |
|---|---|---|
| committer | Adam Russell <ac.russell@live.com> | 2019-07-21 02:56:19 -0400 |
| commit | 2a16112bdf6da59fdc5eb0333e99083e549e0dbf (patch) | |
| tree | f77a559e7969fd44bb66dd254178f4878baf937c /challenge-017 | |
| parent | 79f066fe8b36e3112158e777d7ada16feaf66cda (diff) | |
| download | perlweeklychallenge-club-2a16112bdf6da59fdc5eb0333e99083e549e0dbf.tar.gz perlweeklychallenge-club-2a16112bdf6da59fdc5eb0333e99083e549e0dbf.tar.bz2 perlweeklychallenge-club-2a16112bdf6da59fdc5eb0333e99083e549e0dbf.zip | |
solutions for challenge 017
Diffstat (limited to 'challenge-017')
| -rw-r--r-- | challenge-017/adam-russell/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-017/adam-russell/perl5/UrlGrammar.output | 214 | ||||
| -rw-r--r-- | challenge-017/adam-russell/perl5/UrlGrammar.pm | 272 | ||||
| -rw-r--r-- | challenge-017/adam-russell/perl5/UrlGrammar.yp | 69 | ||||
| -rw-r--r-- | challenge-017/adam-russell/perl5/UrlParser.pm | 272 | ||||
| -rw-r--r-- | challenge-017/adam-russell/perl5/ch-1.pl | 17 | ||||
| -rw-r--r-- | challenge-017/adam-russell/perl5/ch-2.pl | 12 | ||||
| -rw-r--r-- | challenge-017/adam-russell/perl5/url_viz.pl | 5 |
8 files changed, 862 insertions, 0 deletions
diff --git a/challenge-017/adam-russell/blog.txt b/challenge-017/adam-russell/blog.txt new file mode 100644 index 0000000000..b210bbc33c --- /dev/null +++ b/challenge-017/adam-russell/blog.txt @@ -0,0 +1 @@ +https://adamcrussell.livejournal.com/5707.html diff --git a/challenge-017/adam-russell/perl5/UrlGrammar.output b/challenge-017/adam-russell/perl5/UrlGrammar.output new file mode 100644 index 0000000000..759308ef30 --- /dev/null +++ b/challenge-017/adam-russell/perl5/UrlGrammar.output @@ -0,0 +1,214 @@ +Rules: +------ +0: $start -> url $end +1: url -> scheme colondoubleslash userpassword host port path query fragment +2: url -> scheme colondoubleslash host path query fragment +3: url -> scheme colondoubleslash host path fragment +4: url -> scheme colondoubleslash host path +5: url -> scheme colondoubleslash host +6: colondoubleslash -> '://' +7: scheme -> SCHEME +8: userpassword -> USERPASSWORD +9: host -> HOST +10: port -> PORT +11: path -> PATH +12: query -> QUERY +13: fragment -> FRAGMENT + +States: +------- +State 0: + + $start -> . url $end (Rule 0) + + SCHEME shift, and go to state 3 + + scheme go to state 1 + url go to state 2 + +State 1: + + url -> scheme . colondoubleslash userpassword host port path query fragment (Rule 1) + url -> scheme . colondoubleslash host path query fragment (Rule 2) + url -> scheme . colondoubleslash host path fragment (Rule 3) + url -> scheme . colondoubleslash host path (Rule 4) + url -> scheme . colondoubleslash host (Rule 5) + + '://' shift, and go to state 4 + + colondoubleslash go to state 5 + +State 2: + + $start -> url . $end (Rule 0) + + $end shift, and go to state 6 + +State 3: + + scheme -> SCHEME . (Rule 7) + + $default reduce using rule 7 (scheme) + +State 4: + + colondoubleslash -> '://' . (Rule 6) + + $default reduce using rule 6 (colondoubleslash) + +State 5: + + url -> scheme colondoubleslash . userpassword host port path query fragment (Rule 1) + url -> scheme colondoubleslash . host path query fragment (Rule 2) + url -> scheme colondoubleslash . host path fragment (Rule 3) + url -> scheme colondoubleslash . host path (Rule 4) + url -> scheme colondoubleslash . host (Rule 5) + + HOST shift, and go to state 8 + USERPASSWORD shift, and go to state 9 + + host go to state 7 + userpassword go to state 10 + +State 6: + + $start -> url $end . (Rule 0) + + $default accept + +State 7: + + url -> scheme colondoubleslash host . path query fragment (Rule 2) + url -> scheme colondoubleslash host . path fragment (Rule 3) + url -> scheme colondoubleslash host . path (Rule 4) + url -> scheme colondoubleslash host . (Rule 5) + + PATH shift, and go to state 11 + + $default reduce using rule 5 (url) + + path go to state 12 + +State 8: + + host -> HOST . (Rule 9) + + $default reduce using rule 9 (host) + +State 9: + + userpassword -> USERPASSWORD . (Rule 8) + + $default reduce using rule 8 (userpassword) + +State 10: + + url -> scheme colondoubleslash userpassword . host port path query fragment (Rule 1) + + HOST shift, and go to state 8 + + host go to state 13 + +State 11: + + path -> PATH . (Rule 11) + + $default reduce using rule 11 (path) + +State 12: + + url -> scheme colondoubleslash host path . query fragment (Rule 2) + url -> scheme colondoubleslash host path . fragment (Rule 3) + url -> scheme colondoubleslash host path . (Rule 4) + + FRAGMENT shift, and go to state 14 + QUERY shift, and go to state 15 + + $default reduce using rule 4 (url) + + fragment go to state 16 + query go to state 17 + +State 13: + + url -> scheme colondoubleslash userpassword host . port path query fragment (Rule 1) + + PORT shift, and go to state 18 + + port go to state 19 + +State 14: + + fragment -> FRAGMENT . (Rule 13) + + $default reduce using rule 13 (fragment) + +State 15: + + query -> QUERY . (Rule 12) + + $default reduce using rule 12 (query) + +State 16: + + url -> scheme colondoubleslash host path fragment . (Rule 3) + + $default reduce using rule 3 (url) + +State 17: + + url -> scheme colondoubleslash host path query . fragment (Rule 2) + + FRAGMENT shift, and go to state 14 + + fragment go to state 20 + +State 18: + + port -> PORT . (Rule 10) + + $default reduce using rule 10 (port) + +State 19: + + url -> scheme colondoubleslash userpassword host port . path query fragment (Rule 1) + + PATH shift, and go to state 11 + + path go to state 21 + +State 20: + + url -> scheme colondoubleslash host path query fragment . (Rule 2) + + $default reduce using rule 2 (url) + +State 21: + + url -> scheme colondoubleslash userpassword host port path . query fragment (Rule 1) + + QUERY shift, and go to state 15 + + query go to state 22 + +State 22: + + url -> scheme colondoubleslash userpassword host port path query . fragment (Rule 1) + + FRAGMENT shift, and go to state 14 + + fragment go to state 23 + +State 23: + + url -> scheme colondoubleslash userpassword host port path query fragment . (Rule 1) + + $default reduce using rule 1 (url) + + +Summary: +-------- +Number of rules : 14 +Number of terminals : 9 +Number of non-terminals : 10 +Number of states : 24 diff --git a/challenge-017/adam-russell/perl5/UrlGrammar.pm b/challenge-017/adam-russell/perl5/UrlGrammar.pm new file mode 100644 index 0000000000..60aeb9ff38 --- /dev/null +++ b/challenge-017/adam-russell/perl5/UrlGrammar.pm @@ -0,0 +1,272 @@ +#################################################################### +# +# This file was generated using Parse::Yapp version 1.21. +# +# Don't edit this file, use source file instead. +# +# ANY CHANGE MADE HERE WILL BE LOST ! +# +#################################################################### +package UrlGrammar; +use vars qw ( @ISA ); +use strict; + +@ISA= qw ( Parse::Yapp::Driver ); +use Parse::Yapp::Driver; + + + +sub new { + my($class)=shift; + ref($class) + and $class=ref($class); + + my($self)=$class->SUPER::new( yyversion => '1.21', + yystates => +[ + {#State 0 + ACTIONS => { + 'SCHEME' => 3 + }, + GOTOS => { + 'scheme' => 1, + 'url' => 2 + } + }, + {#State 1 + ACTIONS => { + "://" => 4 + }, + GOTOS => { + 'colondoubleslash' => 5 + } + }, + {#State 2 + ACTIONS => { + '' => 6 + } + }, + {#State 3 + DEFAULT => -7 + }, + {#State 4 + DEFAULT => -6 + }, + {#State 5 + ACTIONS => { + 'HOST' => 8, + 'USERPASSWORD' => 9 + }, + GOTOS => { + 'host' => 7, + 'userpassword' => 10 + } + }, + {#State 6 + DEFAULT => 0 + }, + {#State 7 + ACTIONS => { + 'PATH' => 11 + }, + DEFAULT => -5, + GOTOS => { + 'path' => 12 + } + }, + {#State 8 + DEFAULT => -9 + }, + {#State 9 + DEFAULT => -8 + }, + {#State 10 + ACTIONS => { + 'HOST' => 8 + }, + GOTOS => { + 'host' => 13 + } + }, + {#State 11 + DEFAULT => -11 + }, + {#State 12 + ACTIONS => { + 'QUERY' => 15, + 'FRAGMENT' => 14 + }, + DEFAULT => -4, + GOTOS => { + 'fragment' => 16, + 'query' => 17 + } + }, + {#State 13 + ACTIONS => { + 'PORT' => 18 + }, + GOTOS => { + 'port' => 19 + } + }, + {#State 14 + DEFAULT => -13 + }, + {#State 15 + DEFAULT => -12 + }, + {#State 16 + DEFAULT => -3 + }, + {#State 17 + ACTIONS => { + 'FRAGMENT' => 14 + }, + GOTOS => { + 'fragment' => 20 + } + }, + {#State 18 + DEFAULT => -10 + }, + {#State 19 + ACTIONS => { + 'PATH' => 11 + }, + GOTOS => { + 'path' => 21 + } + }, + {#State 20 + DEFAULT => -2 + }, + {#State 21 + ACTIONS => { + 'QUERY' => 15 + }, + GOTOS => { + 'query' => 22 + } + }, + {#State 22 + ACTIONS => { + 'FRAGMENT' => 14 + }, + GOTOS => { + 'fragment' => 23 + } + }, + {#State 23 + DEFAULT => -1 + } +], + yyrules => +[ + [#Rule 0 + '$start', 2, undef + ], + [#Rule 1 + 'url', 8, undef + ], + [#Rule 2 + 'url', 6, undef + ], + [#Rule 3 + 'url', 5, undef + ], + [#Rule 4 + 'url', 4, undef + ], + [#Rule 5 + 'url', 3, undef + ], + [#Rule 6 + 'colondoubleslash', 1, undef + ], + [#Rule 7 + 'scheme', 1, +sub +#line 13 "perl5/UrlGrammar.yp" +{ print "SCHEME:\t\t" . $_[1] . "\n" } + ], + [#Rule 8 + 'userpassword', 1, +sub +#line 16 "perl5/UrlGrammar.yp" +{ my @a = split(/:/, $_[1]); print "USER:\t\t" . $a[0] . "\nPASSWORD:\t" . $a[1] . "\n" } + ], + [#Rule 9 + 'host', 1, +sub +#line 19 "perl5/UrlGrammar.yp" +{ $_[1] =~ s/@//; print "HOST:\t\t" . $_[1] . "\n" } + ], + [#Rule 10 + 'port', 1, +sub +#line 22 "perl5/UrlGrammar.yp" +{ $_[1] =~ s/://; print "PORT:\t\t" . $_[1] . "\n" } + ], + [#Rule 11 + 'path', 1, +sub +#line 25 "perl5/UrlGrammar.yp" +{ print "PATH:\t\t" . $_[1] . "\n" } + ], + [#Rule 12 + 'query', 1, +sub +#line 28 "perl5/UrlGrammar.yp" +{ my $query = substr($_[1], 1); print "QUERY:\t\t$query\n" } + ], + [#Rule 13 + 'fragment', 1, +sub +#line 31 "perl5/UrlGrammar.yp" +{ my $fragment = substr($_[1], 1); print "FRAGMENT:\t$fragment\n" } + ] +], + @_); + bless($self,$class); +} + +#line 34 "perl5/UrlGrammar.yp" + + +sub lexer{ + my($parser) = @_; + $parser->YYData->{INPUT} or return('', undef); + $parser->YYData->{INPUT} =~ s/^[ \t]//; + ## + # send tokens to parser + ## + for($parser->YYData->{INPUT}){ + s/^(http|https|ftp|jdbc)// and return ("SCHEME", $1); + s/^(:\/\/)// and return ("://", $1); + s/^(:[0-9]*)// and return ("PORT", $1); + s/^([a-zA-Z]*:[a-zA-Z]*)// and return ("USERPASSWORD", $1); + s/^(\/[\/a-zA-Z]*)// and return ("PATH", $1); + s/^(\?{1}[a-zA-z=a-zA-Z]*)// and return ("QUERY", $1); + s/^(#{1}[a-zA-Z]*[0-9]*)// and return ("FRAGMENT", $1); + s/^(@?\/{0}[a-zA-z]*)// and return ("HOST", $1); + } +} + +sub error{ + exists $_[0]->YYData->{ERRMSG} + and do{ + print $_[0]->YYData->{ERRMSG}; + return; + }; + print "syntax error\n"; +} + +sub parse{ + my($self, $input) = @_; + $self->YYData->{INPUT} = $input; + my $result = $self->YYParse(yylex => \&lexer, yyerror => \&error); + return $result; +} + +1; diff --git a/challenge-017/adam-russell/perl5/UrlGrammar.yp b/challenge-017/adam-russell/perl5/UrlGrammar.yp new file mode 100644 index 0000000000..7c493c9a7b --- /dev/null +++ b/challenge-017/adam-russell/perl5/UrlGrammar.yp @@ -0,0 +1,69 @@ +%token '://' SCHEME USERPASSWORD HOST PORT PATH QUERY FRAGMENT +%% +url: scheme colondoubleslash userpassword host port path query fragment + | scheme colondoubleslash host path query fragment + | scheme colondoubleslash host path fragment + | scheme colondoubleslash host path + | scheme colondoubleslash host +; + +colondoubleslash: '://' +; + +scheme: SCHEME { print "SCHEME:\t\t" . $_[1] . "\n" } +; + +userpassword: USERPASSWORD { my @a = split(/:/, $_[1]); print "USER:\t\t" . $a[0] . "\nPASSWORD:\t" . $a[1] . "\n" } +; + +host: HOST { $_[1] =~ s/@//; print "HOST:\t\t" . $_[1] . "\n" } +; + +port: PORT { $_[1] =~ s/://; print "PORT:\t\t" . $_[1] . "\n" } +; + +path: PATH { print "PATH:\t\t" . $_[1] . "\n" } +; + +query: QUERY { my $query = substr($_[1], 1); print "QUERY:\t\t$query\n" } +; + +fragment: FRAGMENT { my $fragment = substr($_[1], 1); print "FRAGMENT:\t$fragment\n" } +; + +%% + +sub lexer{ + my($parser) = @_; + $parser->YYData->{INPUT} or return('', undef); + $parser->YYData->{INPUT} =~ s/^[ \t]//; + ## + # send tokens to parser + ## + for($parser->YYData->{INPUT}){ + s/^(http|https|ftp|jdbc)// and return ("SCHEME", $1); + s/^(:\/\/)// and return ("://", $1); + s/^(:[0-9]*)// and return ("PORT", $1); + s/^([a-zA-Z]*:[a-zA-Z]*)// and return ("USERPASSWORD", $1); + s/^(\/[\/a-zA-Z]*)// and return ("PATH", $1); + s/^(\?{1}[a-zA-z=a-zA-Z]*)// and return ("QUERY", $1); + s/^(#{1}[a-zA-Z]*[0-9]*)// and return ("FRAGMENT", $1); + s/^(@?\/{0}[a-zA-z]*)// and return ("HOST", $1); + } +} + +sub error{ + exists $_[0]->YYData->{ERRMSG} + and do{ + print $_[0]->YYData->{ERRMSG}; + return; + }; + print "syntax error\n"; +} + +sub parse{ + my($self, $input) = @_; + $self->YYData->{INPUT} = $input; + my $result = $self->YYParse(yylex => \&lexer, yyerror => \&error); + return $result; +} diff --git a/challenge-017/adam-russell/perl5/UrlParser.pm b/challenge-017/adam-russell/perl5/UrlParser.pm new file mode 100644 index 0000000000..53dfebfda6 --- /dev/null +++ b/challenge-017/adam-russell/perl5/UrlParser.pm @@ -0,0 +1,272 @@ +#################################################################### +# +# This file was generated using Parse::Yapp version 1.21. +# +# Don't edit this file, use source file instead. +# +# ANY CHANGE MADE HERE WILL BE LOST ! +# +#################################################################### +package UrlParser; +use vars qw ( @ISA ); +use strict; + +@ISA= qw ( Parse::Yapp::Driver ); +use Parse::Yapp::Driver; + + + +sub new { + my($class)=shift; + ref($class) + and $class=ref($class); + + my($self)=$class->SUPER::new( yyversion => '1.21', + yystates => +[ + {#State 0 + ACTIONS => { + 'SCHEME' => 2 + }, + GOTOS => { + 'scheme' => 3, + 'url' => 1 + } + }, + {#State 1 + ACTIONS => { + '' => 4 + } + }, + {#State 2 + DEFAULT => -7 + }, + {#State 3 + ACTIONS => { + "://" => 6 + }, + GOTOS => { + 'colondoubleslash' => 5 + } + }, + {#State 4 + DEFAULT => 0 + }, + {#State 5 + ACTIONS => { + 'HOST' => 10, + 'USERPASSWORD' => 8 + }, + GOTOS => { + 'host' => 7, + 'userpassword' => 9 + } + }, + {#State 6 + DEFAULT => -6 + }, + {#State 7 + ACTIONS => { + 'PATH' => 11 + }, + DEFAULT => -5, + GOTOS => { + 'path' => 12 + } + }, + {#State 8 + DEFAULT => -8 + }, + {#State 9 + ACTIONS => { + 'HOST' => 10 + }, + GOTOS => { + 'host' => 13 + } + }, + {#State 10 + DEFAULT => -9 + }, + {#State 11 + DEFAULT => -11 + }, + {#State 12 + ACTIONS => { + 'FRAGMENT' => 16, + 'QUERY' => 17 + }, + DEFAULT => -4, + GOTOS => { + 'fragment' => 15, + 'query' => 14 + } + }, + {#State 13 + ACTIONS => { + 'PORT' => 19 + }, + GOTOS => { + 'port' => 18 + } + }, + {#State 14 + ACTIONS => { + 'FRAGMENT' => 16 + }, + GOTOS => { + 'fragment' => 20 + } + }, + {#State 15 + DEFAULT => -3 + }, + {#State 16 + DEFAULT => -13 + }, + {#State 17 + DEFAULT => -12 + }, + {#State 18 + ACTIONS => { + 'PATH' => 11 + }, + GOTOS => { + 'path' => 21 + } + }, + {#State 19 + DEFAULT => -10 + }, + {#State 20 + DEFAULT => -2 + }, + {#State 21 + ACTIONS => { + 'QUERY' => 17 + }, + GOTOS => { + 'query' => 22 + } + }, + {#State 22 + ACTIONS => { + 'FRAGMENT' => 16 + }, + GOTOS => { + 'fragment' => 23 + } + }, + {#State 23 + DEFAULT => -1 + } +], + yyrules => +[ + [#Rule 0 + '$start', 2, undef + ], + [#Rule 1 + 'url', 8, undef + ], + [#Rule 2 + 'url', 6, undef + ], + [#Rule 3 + 'url', 5, undef + ], + [#Rule 4 + 'url', 4, undef + ], + [#Rule 5 + 'url', 3, undef + ], + [#Rule 6 + 'colondoubleslash', 1, undef + ], + [#Rule 7 + 'scheme', 1, +sub +#line 13 "perl5/UrlGrammar.yp" +{ print "SCHEME:\t\t" . $_[1] . "\n" } + ], + [#Rule 8 + 'userpassword', 1, +sub +#line 16 "perl5/UrlGrammar.yp" +{ my @a = split(/:/, $_[1]); print "USER:\t\t" . $a[0] . "\nPASSWORD:\t" . $a[1] . "\n" } + ], + [#Rule 9 + 'host', 1, +sub +#line 19 "perl5/UrlGrammar.yp" +{ $_[1] =~ s/@//; print "HOST:\t\t" . $_[1] . "\n" } + ], + [#Rule 10 + 'port', 1, +sub +#line 22 "perl5/UrlGrammar.yp" +{ $_[1] =~ s/://; print "PORT:\t\t" . $_[1] . "\n" } + ], + [#Rule 11 + 'path', 1, +sub +#line 25 "perl5/UrlGrammar.yp" +{ print "PATH:\t\t" . $_[1] . "\n" } + ], + [#Rule 12 + 'query', 1, +sub +#line 28 "perl5/UrlGrammar.yp" +{ my $query = substr($_[1], 1); print "QUERY:\t\t$query\n" } + ], + [#Rule 13 + 'fragment', 1, +sub +#line 31 "perl5/UrlGrammar.yp" +{ my $fragment = substr($_[1], 1); print "FRAGMENT:\t$fragment\n" } + ] +], + @_); + bless($self,$class); +} + +#line 34 "perl5/UrlGrammar.yp" + + +sub lexer{ + my($parser) = @_; + $parser->YYData->{INPUT} or return('', undef); + $parser->YYData->{INPUT} =~ s/^[ \t]//; + ## + # send tokens to parser + ## + for($parser->YYData->{INPUT}){ + s/^(http|https|ftp|jdbc)// and return ("SCHEME", $1); + s/^(:\/\/)// and return ("://", $1); + s/^(:[0-9]*)// and return ("PORT", $1); + s/^([a-zA-Z]*:[a-zA-Z]*)// and return ("USERPASSWORD", $1); + s/^(\/[\/a-zA-Z]*)// and return ("PATH", $1); + s/^(\?{1}[a-zA-z=a-zA-Z]*)// and return ("QUERY", $1); + s/^(#{1}[a-zA-Z]*[0-9]*)// and return ("FRAGMENT", $1); + s/^(@?\/{0}[a-zA-z]*)// and return ("HOST", $1); + } +} + +sub error{ + exists $_[0]->YYData->{ERRMSG} + and do{ + print $_[0]->YYData->{ERRMSG}; + return; + }; + print "syntax error\n"; +} + +sub parse{ + my($self, $input) = @_; + $self->YYData->{INPUT} = $input; + my $result = $self->YYParse(yylex => \&lexer, yyerror => \&error); + return $result; +} + +1; diff --git a/challenge-017/adam-russell/perl5/ch-1.pl b/challenge-017/adam-russell/perl5/ch-1.pl new file mode 100644 index 0000000000..24237d86ec --- /dev/null +++ b/challenge-017/adam-russell/perl5/ch-1.pl @@ -0,0 +1,17 @@ +use strict; +use warnings; +## +# Create a script to demonstrate Ackermann function. +## + +sub A{ + my($m, $n) = @_; + return $n + 1 if($m == 0); + return A($m - 1, 1) if($m > 0 && $n == 0); + return A($m - 1, A($m, $n - 1)) if ($m > 0 && $n > 0); +} + +MAIN:{ + my $ackermann = A(1,2); + print "$ackermann\n"; +} diff --git a/challenge-017/adam-russell/perl5/ch-2.pl b/challenge-017/adam-russell/perl5/ch-2.pl new file mode 100644 index 0000000000..a9ce9edb9b --- /dev/null +++ b/challenge-017/adam-russell/perl5/ch-2.pl @@ -0,0 +1,12 @@ +use strict; +use warnings; +## +# Create a script to parse URL and print the components of URL. +## +use UrlParser; +use constant URL => q|jdbc://user:password@localhost:3306/pwc?profile=true#h1|; + +MAIN:{ + my $parser = new UrlParser(); + $parser->parse(URL); +} diff --git a/challenge-017/adam-russell/perl5/url_viz.pl b/challenge-017/adam-russell/perl5/url_viz.pl new file mode 100644 index 0000000000..a9f4dfefb2 --- /dev/null +++ b/challenge-017/adam-russell/perl5/url_viz.pl @@ -0,0 +1,5 @@ +use GraphViz::Parse::Yapp; + +# Pass in a file generated via yapp -v +my $g = GraphViz::Parse::Yapp->new("perl5/UrlGrammar.output"); +print $g->as_png; |
