diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2024-03-11 00:08:54 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-11 00:08:54 +0000 |
| commit | 53352cd10d20641ed86e145ce85ba551452e4fc3 (patch) | |
| tree | 8643035400e2e190b8b4df261aece9cdc0bb8542 | |
| parent | 63411f3da2658c18e7ed1bb9104d7ade421bd206 (diff) | |
| parent | 0e01eaf0f3199e33e8a947991b96290321b42d67 (diff) | |
| download | perlweeklychallenge-club-53352cd10d20641ed86e145ce85ba551452e4fc3.tar.gz perlweeklychallenge-club-53352cd10d20641ed86e145ce85ba551452e4fc3.tar.bz2 perlweeklychallenge-club-53352cd10d20641ed86e145ce85ba551452e4fc3.zip | |
Merge pull request #9721 from adamcrussell/challenge-259
initial commit
| -rw-r--r-- | challenge-259/adam-russell/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-259/adam-russell/perl/Ch2.pm | 222 | ||||
| -rw-r--r-- | challenge-259/adam-russell/perl/ch-1.pl | 33 | ||||
| -rw-r--r-- | challenge-259/adam-russell/perl/ch-2.pl | 33 | ||||
| -rw-r--r-- | challenge-259/adam-russell/perl/ch-2.yp | 68 |
5 files changed, 357 insertions, 0 deletions
diff --git a/challenge-259/adam-russell/blog.txt b/challenge-259/adam-russell/blog.txt new file mode 100644 index 0000000000..4f89cfad6d --- /dev/null +++ b/challenge-259/adam-russell/blog.txt @@ -0,0 +1 @@ +http://www.rabbitfarm.com/cgi-bin/blosxom/perl/2024/03/10 diff --git a/challenge-259/adam-russell/perl/Ch2.pm b/challenge-259/adam-russell/perl/Ch2.pm new file mode 100644 index 0000000000..9bcf3c54d6 --- /dev/null +++ b/challenge-259/adam-russell/perl/Ch2.pm @@ -0,0 +1,222 @@ +#################################################################### +# +# 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 Ch2; +use vars qw ( @ISA ); +use strict; + +@ISA= qw ( Parse::Yapp::Driver ); +use Parse::Yapp::Driver; + +#line 7 "ch-2.yp" + + my %record = (fields => {}); + + +sub new { + my($class)=shift; + ref($class) + and $class=ref($class); + + my($self)=$class->SUPER::new( yyversion => '1.21', + yystates => +[ + {#State 0 + ACTIONS => { + 'START' => 2 + }, + GOTOS => { + 'file' => 1 + } + }, + {#State 1 + ACTIONS => { + '' => 3 + } + }, + {#State 2 + ACTIONS => { + 'WORD' => 4 + }, + GOTOS => { + 'id' => 5 + } + }, + {#State 3 + DEFAULT => 0 + }, + {#State 4 + DEFAULT => -2 + }, + {#State 5 + ACTIONS => { + 'WORD' => 6 + }, + GOTOS => { + 'field' => 8, + 'fields' => 7 + } + }, + {#State 6 + ACTIONS => { + "=" => 9 + } + }, + {#State 7 + ACTIONS => { + 'END' => 10, + 'WORD' => 6 + }, + GOTOS => { + 'field' => 11 + } + }, + {#State 8 + DEFAULT => -8 + }, + {#State 9 + ACTIONS => { + 'NUMBER' => 12, + 'QUOTE' => 13 + } + }, + {#State 10 + DEFAULT => -1 + }, + {#State 11 + DEFAULT => -9 + }, + {#State 12 + DEFAULT => -6 + }, + {#State 13 + ACTIONS => { + 'WORD' => 14 + }, + GOTOS => { + 'words' => 15 + } + }, + {#State 14 + DEFAULT => -3 + }, + {#State 15 + ACTIONS => { + 'ESCAPED_QUOTE' => 17, + 'WORD' => 16, + 'QUOTE' => 18 + } + }, + {#State 16 + DEFAULT => -4 + }, + {#State 17 + ACTIONS => { + 'WORD' => 19 + } + }, + {#State 18 + DEFAULT => -7 + }, + {#State 19 + ACTIONS => { + 'ESCAPED_QUOTE' => 20 + } + }, + {#State 20 + DEFAULT => -5 + } +], + yyrules => +[ + [#Rule 0 + '$start', 2, undef + ], + [#Rule 1 + 'file', 4, +sub +#line 12 "ch-2.yp" +{$record{name} = $_[2]; \%record;} + ], + [#Rule 2 + 'id', 1, undef + ], + [#Rule 3 + 'words', 1, undef + ], + [#Rule 4 + 'words', 2, undef + ], + [#Rule 5 + 'words', 4, undef + ], + [#Rule 6 + 'field', 3, +sub +#line 23 "ch-2.yp" +{$record{fields}->{$_[1]} = $_[3]} + ], + [#Rule 7 + 'field', 5, +sub +#line 24 "ch-2.yp" +{$record{fields}->{$_[1]} = $_[4]} + ], + [#Rule 8 + 'fields', 1, undef + ], + [#Rule 9 + 'fields', 2, undef + ] +], + @_); + bless($self,$class); +} + +#line 31 "ch-2.yp" + + +sub lexer{ + my($parser) = @_; + $parser->YYData->{INPUT} or return('', undef); + $parser->YYData->{INPUT} =~ s/^[ \t]//g; + ## + # send tokens to parser + ## + for($parser->YYData->{INPUT}){ + s/^([0-9]+)// and return ("NUMBER", $1); + s/^({%)// and return ("START", $1); + s/^(%})// and return ("END", $1); + s/^(\w+)// and return ("WORD", $1); + s/^(=)// and return ("=", $1); + s/^(")// and return ("QUOTE", $1); + s/^(\\")// and return ("ESCAPED_QUOTE", $1); + s/^(\\\\)// and return ("WORD", $1); + } +} + +sub error{ + exists $_[0]->YYData->{ERRMSG} + and do{ + print $_[0]->YYData->{ERRMSG}; + return; + }; + print "syntax error\n"; +} + +sub parse{ + my($self, $input) = @_; + $input =~ tr/\t/ /s; + $input =~ tr/ //s; + $self->YYData->{INPUT} = $input; + my $result = $self->YYParse(yylex => \&lexer, yyerror => \&error); + return $result; +} + +1; diff --git a/challenge-259/adam-russell/perl/ch-1.pl b/challenge-259/adam-russell/perl/ch-1.pl new file mode 100644 index 0000000000..1b9afb52c6 --- /dev/null +++ b/challenge-259/adam-russell/perl/ch-1.pl @@ -0,0 +1,33 @@ + + +use v5.38; +use Time::Piece; +use Time::Seconds; + + +sub count_days{ + my($start, $offset, $holidays) = @_; + $start = Time::Piece->strptime($start, q/%Y-%m-%d/); + my $t = $start; + my $end = $start; + { + $t += ONE_DAY; + unless( +$t->wday >= 6 + || +1 == grep {$t->strftime(q/%Y-%m-%d/) eq $_} @{$holidays} +){ + $end = $t; + $offset--; + } + redo if $offset > 0; + } + return $end->strftime(q/%Y-%m-%d/); +} + + +MAIN:{ + say count_days q/2018-06-28/, 3, [q/2018-07-03/]; + say count_days q/2018-06-28/, 3; +} + diff --git a/challenge-259/adam-russell/perl/ch-2.pl b/challenge-259/adam-russell/perl/ch-2.pl new file mode 100644 index 0000000000..0db641e913 --- /dev/null +++ b/challenge-259/adam-russell/perl/ch-2.pl @@ -0,0 +1,33 @@ + + +use v5.38; + +use Ch2; +use constant TEST0 => q/{% id field1="value1" field2="value2" field3=42 %}/; +use constant TEST1 => q/{% youtube title="Title \"quoted\" done" %}/; +use constant TEST2 => q/{% youtube title="Title with escaped backslash \\\\" %}/; + + +sub print_record{ + my($record) = @_; + say q/{/; + say qq/\tname => / . $record->{name}; + say qq/\tfields => {/; + for my $field (sort {$a cmp $b} keys %{$record->{fields}}){ + say qq/\t\t$field => / . q/ / . $record->{fields}->{$field}; + } + say qq/\t}/; + say q/}/; +} + + +MAIN:{ + my $parser = Ch2->new(); + say TEST0; + print_record($parser->parse(TEST0)); + say TEST1; + print_record($parser->parse(TEST1)); + say TEST2; + print_record($parser->parse(TEST2)); +} + diff --git a/challenge-259/adam-russell/perl/ch-2.yp b/challenge-259/adam-russell/perl/ch-2.yp new file mode 100644 index 0000000000..a63147bd66 --- /dev/null +++ b/challenge-259/adam-russell/perl/ch-2.yp @@ -0,0 +1,68 @@ +%token NUMBER +%token START +%token END +%token WORD +%token QUOTE +%token ESCAPED_QUOTE +%{ + my %record = (fields => {}); +%} +%% + +file: START id fields END {$record{name} = $_[2]; \%record;} +; + +id: WORD +; + +words: WORD + | words WORD + | words ESCAPED_QUOTE WORD ESCAPED_QUOTE +; + +field: WORD '=' NUMBER {$record{fields}->{$_[1]} = $_[3]} + | WORD '=' QUOTE words QUOTE {$record{fields}->{$_[1]} = $_[4]} +; + +fields: field + | fields field +; + +%% + +sub lexer{ + my($parser) = @_; + $parser->YYData->{INPUT} or return('', undef); + $parser->YYData->{INPUT} =~ s/^[ \t]//g; + ## + # send tokens to parser + ## + for($parser->YYData->{INPUT}){ + s/^([0-9]+)// and return ("NUMBER", $1); + s/^({%)// and return ("START", $1); + s/^(%})// and return ("END", $1); + s/^(\w+)// and return ("WORD", $1); + s/^(=)// and return ("=", $1); + s/^(")// and return ("QUOTE", $1); + s/^(\\")// and return ("ESCAPED_QUOTE", $1); + s/^(\\\\)// and return ("WORD", $1); + } +} + +sub error{ + exists $_[0]->YYData->{ERRMSG} + and do{ + print $_[0]->YYData->{ERRMSG}; + return; + }; + print "syntax error\n"; +} + +sub parse{ + my($self, $input) = @_; + $input =~ tr/\t/ /s; + $input =~ tr/ //s; + $self->YYData->{INPUT} = $input; + my $result = $self->YYParse(yylex => \&lexer, yyerror => \&error); + return $result; +} |
