Sunday, December 20, 2009

Infinite Loops

Well, I tried reformulating the line of music regex, and have what I think is a nice version, with one major catch. Here's the new regexes:
    regex element { <broken_rhythm> | <note> | <rest> | <gracing> }

regex barline { ':|:' | '|:' | '|' | ':|' | '::' }

regex bar { <element>+ <barline>? }

regex line_of_music { <barline> $$ | <barline>? <element>+ $$ }


As is, this passes without issues:
{
my $match = "g>ecgece/f/g/e/|" ~~ m/ <ABC::bar> /;
isa_ok $match, Match, 'bar recognized';
is $match<ABC::bar>, "g>ecgece/f/g/e/|", "Entire bar was matched";
is $match<ABC::bar><element>.map(~*), "g>e c g e c e/ f/ g/ e/", "Each element was matched";
is $match<ABC::bar><barline>, "|", "Barline was matched";
}

I think that's a suitably elegant test.

There's only one problem here. Real ABC allows for spaces between elements, which makes the ABC format much more legible. (I would like this code in the long run to be able to take an ABC tune, process it, and write it back out again, so ideally the code needs to carefully note the whitespace so it can be output again later.) But when I try to add <ws>+ alternative to the element regex, and try to parse a bar of music with a space or two in it, it appears to just hang.

This one has me utterly stumped; do any of the Perl 6 regex experts out there have a clue what could be going on?

Update: Still unable to make <ws> work for me, but had great luck with just using good old \s. So the code works now, but I'd still love an explanation...

Update to the Update: Argh, bar works but line_of_music still hangs. Dang it, I feel like I'm sooooooo close to getting this thing working....

Update^3: Ah, I simply had a completely broken line_of_music. I've got a simpler one working now.

No comments:

Post a Comment