Re: passing text by reference and other questions...
[email protected] (Marco Baringer)
| Newsgroups | perl.recdescent |
|---|---|
| Message-ID | <[email protected]> |
hmm, i was looking at the archives and it seems the text of my message
got lost...interesting....
i'm resending the message which was supposed to accompany those
patches.
note: this is long....
<original message>
assuming $parser is the Parse::RecDescent object and $text is the
source text:
1) if i pass $text by reference ($parser->start_rule( \$text )) then
any text consumed is removed from the beginning of $text, even if
this does not lead to a complete match. is this the way it's
supposed to work?
example:
$grammar = q{ start_rule : 'foo' 'bar' }
$text = ' foo would never eat in a bar '
when i do $parser->start_rule(\$text) even though this fails to match
any rules $text is now: ' would never eat in a bar '.
2) can i have a grammar which does not define the structure of my
entire text and yet still have it match in thoses places of the
text where it could match?
example:
$grammar = q { start_rule : 'french' 'fries' }
$text = " i like french fries ";
if i pass $text to $parser->start_rule it will not match because,
rightfully so, ' i' does not start any rule, however since i have to
basically do this i currently have the hurendously (sp?) inefficent:
my $rest_buffer = $text;
my $seen_buffer = "";
while ($rest_buffer ne '') {
$parser->start_rule( $rest_buffer );
$seen_buffer = substr($rest_buffer, 0, 1);
$rest_buffer = substr($rest_buffer, 1);
}
$text = $seen_buffer;
(i can't even skip ahead by white space since white space is important
to me, and while in this case i could just look for those points
starting with 'french' in the general case i do not know what the
grammar looks like, so this isn't possible)
i'd appreciate any suggestions.
3) i needed the <perl_codeblock> directive to allow me to pass the
delimiters to Text::Balaned::extract_codeblock, i have attached a
patch to RecDesecent.pm which allows this in the form of
<perl_codeblock:[delimiters]>. however, since i don't _really_
understand RecDesecent.pm it's kindof ugly (i think a
<bracketed:[delimiters]) directive would be better, but i couldn't
get that to work. again, any comments/suggestions would be
appreciated.
4) Since i'm assuming Mr. Conway is listening: [this isn't realted to
Parse::RecDescent]
i needed to be able to unhide the source code Filter::Simple
"whites out" when you use the FILTER_ONLY code => sub { }, so am
attaching a patch which adds a function Filter::Simple::show which
fills the place holders back in. an inverse hide function would be
usefull, but i haven't gotten around to it yet. the 5 line patch is
attached to this email. while i'm at it, is there a filtering stuff
mailing list?
</original message>
[last night i was doing some more stuff and i came across the following
"problem":]
5) i need to be able to initialize some global variables every time i
try to parse some text. my start rule is called macro and i have it
defined as:
macro : { $Macro::Grammar::new_grammar = init_grammar(); }
'macro'
template
generator
{ stuff(); }
the problem is that whnever i have that first action i get lot's of
errors about an undefined sub rule "1". i tried having the action
return all kinds of different things (via $return and the last
value), is was thinking that maybe i needed to return "" or a valid
token, however i could not get rid of that error. i've read through
the docs a few (thousand) times and while all the example do show
actions as the last element/token (what's the propoer terminology
here?) in a rule i looked at the compiled parser (via
Parse::RecDescent::Precompile) and i saw that the action is getting
do'd but then it would seem that the parser tries with the next
token, no error statements (actually, no other statements at all if
$::RD_TRACE is undef). so, what am i missing?
i don't know if this will help or not, but here's what i'm trying to
do:
i want to be able to put
macro { aif <cond:code_block ()> }
{ "if (my \$it = ($cond))" }
in my perl files and have any perl code which matches the rule
(Parse::RecDescent::skip = '') :
macro : 'aif' /\s*/ <perl_codeblock:()>
be transformed into the text:
if (my $it = (<whatever matched the <perl_codeblock:()>>))
i'm currently doing this by having my parser create a parser for the
macro.
if you can read this the message got through and we're all shiny happy
people.
--
-Marco
Ring the bells that still can ring.
Forget the perfect offering.
There's a crack in everything.
It's how the light gets in.
-Isonard Cohen