Created
March 6, 2011 22:24
-
-
Save tadzik/857788 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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