#!/usr/bin/env raku
grammar Bencode {
token TOP { <elem> {make $<elem>.made} }
token elem {
| <integer> {make $<integer>.Int}
| <list> {make $<list><elem>.List.map(*.made)}
| <dictionnary> {make %($<dictionnary><entry>.map({$_<key>.Str,$_<value>.made}).flat)}
| <string> {make $<string>.Str}
}
token integer { i <(\-?\d+)> e }
token string { $<len> = \d+ ':' <(. ** {$<len>})> }
token list { l <( <elem>* )> e }
token dictionnary { d <( $<entry> = (<key=string> <value=elem>)* )> e }
}
say Bencode.parse("i33e").made;
say Bencode.parse("i-32e").made;
say Bencode.parse("0:").made;
say Bencode.parse("6:foobar").made;
say Bencode.parse("le").made;
say Bencode.parse("li34ei23ee").made;
say Bencode.parse("de").made;
say Bencode.parse("d3:fooi33e3:bari-2ee").made;