[Petal] Modifiers and variables

Fergal Daly fergal at esatclear.ie
Thu Aug 19 12:18:50 BST 2004


On Thu, Aug 19, 2004 at 11:42:05AM +0100, Jean-Michel Hiver wrote:
> 
> >>I see. Well, I wouldn't adding a base class (i.e. Petal::Plugin) 
> >>which would be the recommended method to implement new modifiers, and 
> >>then cabling existing modifiers onto Petal::Plugin.
> >
> >I say, what a brilliant idea! :-) 
> 
> Which takes us to the problem of the syntax. We need to come up with a 
> sort of grammar for the parser in this base class. Any ideas?

You could get fancy and use something to generate a parser from a grammar, I
wrote a Parse::RecDescent grammar for an extended TALES last year but
there's a large overhead parsing like that every time the expression is
ecountered, it only makes sense if you are going to parse and compile it
along with the template then use the compiled version at run time.

What would be useful is to break out a parse_args routine (as in my patch)
or even a parse_one_arg routine. Make these handle an array of tokens. Add
wrapper versions that take a string, tokenise it, pass it in to one of the
above, these would be useful in modifiers.

parse_one_arg kind of exists already in that it's just hash lookup however
what you cannot easily do is handle something that looks

mod:some/expr some stuff for the mod to figure out

because the modifier cannot (in general) figure out where the first argument
ends.

So what you really need is a parse_one_arg which tries to use the start of
the string as an expression, consuming as much as possible but also gives
you back what it couldn't use. Then you could easily do

if: a then b elsif c then d else e

and parse it like

sub process
{
	my $arg = shift;

	$arg =~ s/^\s+//; # clear leading whitespace

	while(1)
	{
		my ($if, $arg) = parse_one_expr($arg);
		$args =~ s/^\s+//;
		my ($then, $arg) = parse_one_expr($arg);
		$args =~ s/^\s+//;

		if ($if)
		{
			return $then;
		}
		else
		{
			if ($arg =~ s/else\s+//)
			{
				return parse_one_arg($arg);
			}
			elsif ($arg =~ s/elsif\s+//)
			{
				# go round again
				next;
			}
			else
			{
				return undef;
			}
		}
	}
}

One problem with the above is that the "then" expression gets evealuated
even if the "if" expression is false, this is unavoidable because Petal
currently cannot parse without also evaluating,

F


More information about the Petal mailing list