Hi Richard,

Not a complete answer to your question;
just an observation about your grammar:

>  rule TOP        { ^ <statement>+ $ };
>
>  rule statement  { <id> '=' <endvalue>
>                  | { { self.panic($/, "Declaration syntax incorrect") } }
>                  };
>
>  rule endvalue   { <keyword> '(' ~ ')' <pairlist>
>                  | { self.panic($/, "Invalid declaration.") }
>                  }

That's more or less the equivalent of:

    sub TOP       {
                    die if !at_start_of_input();
                    loop { last unless try statement() };
                    die if !at_end_of_input();
                  }

    sub statement {
                    try { id(); match_literal('='); endvalue() }
                  or
                    die "Declaration syntax incorrect";
                  }

    sub endvalue  {
                    try { keyword(); match_literal('('); pairlist();
match_literal(')') }
                  or
                    die "Invalid declaration."
                  }

In which case, would you really have expected a call to TOP()
NOT to throw an exception from statement(), the first time statement()
couldn't match (as it inevitably won't if we're at the end of the input)???

If these were subroutines, I suspect you'd have written something
more like:

    sub statement {
                    try { id(); match_literal('='); endvalue() }
                  or

*                    !at_end_of_input()                        && die
"Declaration syntax incorrect"*
                  }

    sub endvalue  {
                    try { keyword(); match_literal('('); pairlist();
match_literal(')' }
                  or

*                    !at_end_of_input()                        && die
"Invalid declaration.";*
                  }

which, in a regex, would be something like:

   rule TOP        { ^ <statement>+ $ };

   rule statement  {
                     <id> '=' <endvalue>
                   |
*                     \S  **# ...means we found something else, so...*
*                     { self.panic($/, "Declaration syntax incorrect") }*
                   };

   rule endvalue   {
                     <keyword> '(' ~ ')' <pairlist>
                   |
*                     \S  **# ...means we found something else, so...*
*                     { self.panic($/, "Invalid declaration.") }*
                   }

Though, personally, I'd have been inclined to write it like this:

    rule TOP        { ^  <statement>+  *[ $ | <unexpected> ]*  }

    rule statement  { 'ID' '=' <endvalue> }

    rule endvalue   { 'keyword' '(' ~ ')' 'pairlist' }



*    rule unexpected { $<unexpected> = (\N+)                      {
self.panic($/,"Expected statement but found '$<unexpected>'")
}                    }*

In other words: after the statements, we're either at the end of the input,
or else we found something unexpected, so capture it and then report it.

HTH,

Damian

Reply via email to