Skip to content

Instantly share code, notes, and snippets.

@tadzik
Created March 6, 2011 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tadzik/857788 to your computer and use it in GitHub Desktop.
Save tadzik/857788 to your computer and use it in GitHub Desktop.
$ cat JSON_Timy.pm
module JSON_Timy;
grammar JSON_Timy_Grammar {
rule TOP { ^[ <object> | <array> ]$ }
rule object { '{' ~ '}' <pairlist> }
rule pairlist { [ <pair> ** [ \, ] ]? }
rule pair { <string> ':' <value> }
rule array { '[' ~ ']' [ <value> ** [ \, ] ]? }
proto token value { <...> };
token value:sym<number> {
'-'?
[ 0 | <[1..9]> <[0..9]>* ]
[ \. <[0..9]>+ ]?
[ <[eE]> [\+|\-]? <[0..9]>+ ]?
}
token value:sym<true> { <sym> };
token value:sym<false> { <sym> };
token value:sym<null> { <sym> };
token value:sym<object> { <object> };
token value:sym<array> { <array> };
token value:sym<string> { <string> }
token string {
\" ~ \" [ <str> | \\ <str_escape> ]*
}
token str {
[
<!before \t>
<!before \n>
<!before \\>
<!before \">
.
]+
# <-["\\\t\n]>+
}
token str_escape {
<["\\/bfnrt]> | u <xdigit>**4
}
}
class JSON_Timy_Actions {
has $!array_time = 0;
has $!string_time = 0;
has $!value_time = 0;
has $!str_time = 0;
has $!str_escape_time = 0;
method summary {
say "timings:";
say :$!array_time;
say :$!string_time;
say :$!str_escape_time;
}
method TOP($/) {
make $/.values.[0].ast;
};
method object($/) {
# RAKUDO
# the .item works around RT #78510
make $<pairlist>.ast.hash.item;
}
method pairlist($/) {
# the .item works around RT #78510
make $<pair>>>.ast.flat.item;
}
method pair($/) {
make $<string>.ast => $<value>.ast;
}
method array($/) {
my $t = pir::time__N;
my $r = [$<value>>>.ast];
$!array_time += pir::time__N - $t;
make $r;
}
method string($/) {
my $t = pir::time__N;
my $r = join '', $/.caps>>.value>>.ast;
$!string_time += pir::time__N - $t;
make $r;
}
method value:sym<number>($/) { make eval $/.Str }
method value:sym<string>($/) { make $<string>.ast }
method value:sym<true>($/) { make Bool::True }
method value:sym<false>($/) { make Bool::False }
method value:sym<null>($/) { make Any }
method value:sym<object>($/) { make $<object>.ast }
method value:sym<array>($/) { make $<array>.ast }
method str($/) { make ~$/ }
method str_escape($/) {
my $t = pir::time__N;
my $r;
if $<xdigit> {
$r = chr(:16($<xdigit>.join));
} else {
my %h = '\\' => "\\",
'/' => "/",
'b' => "\b",
'n' => "\n",
't' => "\t",
'f' => "\f",
'r' => "\r",
'"' => "\"";
$r = %h{~$/};
}
$!str_escape_time += pir::time__N - $t;
make $r;
}
}
sub from-json($text) is export {
my $a = JSON_Timy_Actions.new();
my $o = JSON_Timy_Grammar.parse($text, :actions($a));
$a.summary;
return $o.ast;
}
# vim: ft=perl6
##############################################
$ perl6
> use JSON_Timy; say time; my $list = from-json slurp '/home/tadzik/.panda/projects.json'; say time
rtype not set
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment