I'm doing Advent of Code day 9:
You sit for a while and record part of the stream (your puzzle input). The characters represent groups - sequences that begin with
{and end with}. Within a group, there are zero or more other things, separated by commas: either another group or garbage. Since groups can contain other groups, a}only closes the most-recently-opened unclosed group - that is, they are nestable. Your puzzle input represents a single, large group which itself contains many smaller ones.Sometimes, instead of a group, you will find garbage. Garbage begins with
<and ends with>. Between those angle brackets, almost any character can appear, including{and}. Within garbage,<has no special meaning.In a futile attempt to clean up the garbage, some program has canceled some of the characters within it using
!: inside garbage, any character that comes after!should be ignored, including<,>, and even another!.
Of course, this screams out for a Perl 6 Grammar...
grammar Stream
{
rule TOP { ^ <group> $ }
rule group { '{' [ <group> || <garbage> ]* % ',' '}' }
rule garbage { '<' [ <garbchar> | <garbignore> ]* '>' }
token garbignore { '!' . }
token garbchar { <-[ !> ]> }
}
This seems to work fine on simple examples, but it goes wrong with two garbchars in a row:
say Stream.parse('{<aa>}');
gives Nil.
Grammar::Tracer is no help:
TOP
| group
| | group
| | * FAIL
| | garbage
| | | garbchar
| | | * MATCH "a"
| | * FAIL
| * FAIL
* FAIL
Nil
Multiple garbignores are no problem:
say Stream.parse('{<!!a!a>}');
gives:
「{<!!a!a>}」
group => 「{<!!a!a>}」
garbage => 「<!!a!a>」
garbignore => 「!!」
garbchar => 「a」
garbignore => 「!a」
Any ideas?