<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/perl -w

use Parse::RecDescent;

#$RD_TRACE=1;

my $parser = Parse::RecDescent-&gt;new(&lt;&lt;'EOGRAMMAR');

	file: 		&lt;skip:''&gt; item(s)

	item: 		directive
	    | 		text

	directive: 	'&lt;%' &lt;skip:'\\s*'&gt; command arg(s?) m|/?%&gt;|
				{ $return = bless \%item, 'directive' }

	command: 	m|/?[a-z]\w*|i

	arg:		argname '=' string
				{ $return = \%item }
	   |		string
				{ $return = \%item }
	   |		data
				{ $return = \%item }

	argname:	/[a-z]\w*/i

	string:		'"' /[^\\"]*(\\.[^\\"]*)*/ '"'
				{ $return = $item[2] }

	data:		m|((?!/?%&gt;)\S)+|


	text: 		/((?!&lt;%).)+/s
				{ $return = bless \$item[1], 'text' }

EOGRAMMAR

my $data = join '', &lt;DATA&gt;;

my $info = $parser-&gt;file($data);

use Data::Dumper;

print Data::Dumper-&gt;Dump($info);

__DATA__

&lt;% If expr %&gt;
the if worked
&lt;% Else %&gt;
it didn't work
&lt;% /If %&gt;
   &gt;
&lt;% Include file="foo.txt" /%&gt;
   &gt;
&lt;% Run Function="myFunc" Attr="x" ...%&gt;
&lt;% Arg Name="row" %&gt;
&lt;TR&gt;&lt;TD&gt;Name&lt;/TD&gt;&lt;TD&gt;{name}&lt;/TD&gt;&lt;/TR&gt;
&lt;% /Arg %&gt;
&lt;% /Run %&gt;
</pre></body></html>