Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Need advice (module) to parse nested IF/ELSIF..

by taizica (Novice)
on Jan 28, 2004 at 15:22 UTC ( [id://324685]=perlquestion: print w/replies, xml ) Need Help??

taizica has asked for the wisdom of the Perl Monks concerning the following question:

Hello Perl Guru,
I really need your advice to find an existing module which can parse a text template with IF/ELSIF. For example, in a text, we can parse the following nested IF tags. Thank you very much in advance.

<%IF boys %>
   You can play football for the whole day.
   <%IF nice_boys %>
     You don't need to get permission from your teacher.
   <%ELSIF agreesive_boys%>
     Please respect others
   <%ELSE%>
     Please talk to me first
   <%ENDIF%>
<%ELSIF girls%>
   I suggest you to go to library
<%ELSE%>
   Stay here
<%ENDIF>
  • Comment on Need advice (module) to parse nested IF/ELSIF..

Replies are listed 'Best First'.
Re: Need advice (module) to parse nested IF/ELSIF..
by dragonchild (Archbishop) on Jan 28, 2004 at 15:46 UTC
    Sounds like you're writing a templating system. Maybe you should look at existing ones, like Template Toolkit, HTML::Template, Text::Template, Excel::Template, PDF::Template, etc.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      Sounds like you're writing a templating system

      Clippy, is that you? ;-)

      Seriously though, I'd second the Template Toolkit recommendation. You (the original poster) can use the START_TAG and END_TAG config options to set the start and end tags to "<%" and "%>", then just process the template.

      Here is the example from tt2's Config documentation:

      my $template = Template->new({ START_TAG => quotemeta('<+'), END_TAG => quotemeta('+>'), });
      Thanks to all for all the hints. I found the ScriptTemplate which possibly can do what I need.

      Best Regards
      Tai
Re: Need advice (module) to parse nested IF/ELSIF..
by ysth (Canon) on Jan 28, 2004 at 16:56 UTC
    Just saying you need to parse it isn't descriptive enough. What do you want to do? Substitute over the text in different levels? Put it all into some kind of tree structure?

    The most flexible solution is to use something like Parse::RecDescent.

Re: Need advice (module) to parse nested IF/ELSIF..
by l3nz (Friar) on Jan 28, 2004 at 18:05 UTC
    This is more a joke than a real solution, still might be useful. This builds a Perl routine via eval and then calls it from the content of your own page. It works more or less like a JSP compiler, turning the page data into native source code, and then compiling it via eval. If you add a thin layer of error control, this might be a viable solution.

    The routine it creates expects a hash containing true/false values (the same you will test in your page) and returns a string with the results.

    my $code = ""; my %H; while (<DATA>) { chomp; if ( /<%\s*if (.+?)\s*%>/i ) { $code .= " if (\$H{$1}) { \n"; } elsif ( /<%\s*elsif (.+?)\s*%>/i ) { $code .= "} elsif (\$H{$1}) { \n"; } elsif ( /<%\s*else\s*%>/i ) { $code .= "} else { \n "; } elsif ( /<%\s*endif\s*%>/i ) { $code .= "};\n "; } else { $code .= " \$r .= \"$_\";\n"; } } $code = "sub page_expr\n {\n my (%H) = \@_; my \$r = '';\n $code\n; re +turn \$r }; "; eval $code; $H{boys} = 1; $H{nice_boys} = 1; print page_expr( %H ); __DATA__ <%IF boys %> &nbspYou can play football for the whole day. <%IF nice_boys %> &nbspYou don't need to get permission from your teacher. <%ELSIF agreesive_boys%> &nbspPlease respect others <%ELSE%> &nbspPlease talk to me first <%ENDIF%> <%ELSIF girls%> &nbspI suggest you to go to library <%ELSE%> &nbspStay here <%ENDIF%>
    This creates dynamically this code (I reformatted it a bit just to make it more readable):
    sub page_expr {
     my (%H) = @_; my $r = '';
      if ($H{boys}) {
        $r .= "   You can play football for the whole day.";
        if ($H{nice_boys}) {
          $r .= "     You don't need to get .";
        } elsif ($H{agreesive_boys}) {
          $r .= "     Please respect others";
        } else {
          $r .= "     Please talk to me first";
        };
      } elsif ($H{girls}) {
       $r .= "   I suggest you to go to library";
      } else {
       $r .= "   Stay here";
      };
      return $r;
    };
    
    When run, this program prints:
       You can play football for the whole day.    
       You don't need to get permission from your teacher.
    
    
    Just my euro 0.02. Hope it helps.
    
    
    
    
    

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://324685]
Approved by kutsu
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2024-04-19 01:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found