aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2024-03-11 00:08:54 +0000
committerGitHub <noreply@github.com>2024-03-11 00:08:54 +0000
commit53352cd10d20641ed86e145ce85ba551452e4fc3 (patch)
tree8643035400e2e190b8b4df261aece9cdc0bb8542
parent63411f3da2658c18e7ed1bb9104d7ade421bd206 (diff)
parent0e01eaf0f3199e33e8a947991b96290321b42d67 (diff)
downloadperlweeklychallenge-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.txt1
-rw-r--r--challenge-259/adam-russell/perl/Ch2.pm222
-rw-r--r--challenge-259/adam-russell/perl/ch-1.pl33
-rw-r--r--challenge-259/adam-russell/perl/ch-2.pl33
-rw-r--r--challenge-259/adam-russell/perl/ch-2.yp68
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;
+}