In continuation of earlier discussions on ColdFusion-like template parser...

Over the holidays (Marry Christmas to you all by the way!), I was conversing with some monks (via email as well as at the monastery) who mentioned that I should hammer down concrete specs of my design for the final ColdFusion-like template parser. Pertaining to these suggestions (and eager to seek further help and facilitate greater dialogue), I thought to write this little 'design' document and post it on perlmonks for review/suggestions etc. Some concerns that I have with the current design is that if implemented as is, my parser module will require more resources depending on how deeply nested the source template is (speaking of tag nesting). I'm wondering if any monk would have useful suggestions in that regard?
--------------------------------------------------------- ColdFusion::Parser Main class that deals with opening template files, managing cache, and creating initial instance of the ColdFusion::ParseTree object to transform raw template text into a parse tree that could later be processed. Here's a quick outline of what this class does: 1. Read from a template file (or buffer etc.) 2. Initialize ColdFusion::ParseRules. 3. Initialize ColdFusion::ParseTree by passing it the ParseRules object along with template text (references). 4. Processes resultant parse tree (aka 'tag stack'). ColdFusion::ParseRules used by : ColdFusion::ParseTree created by: ColdFusion::Parser This class describes how a chunk of template text should be parsed. Various tags may have their own variations of this class specific to their needs. However, this is only a remote possibility. For the most part, there's going to be a signle instance of this class created inside ColdFusion::Parser and passed along (as a reference) to all 'child' objects. By deriving custom classes from this base class, one should be able to create his own variation of a template parser to handle various other templating formats (such as ASP etc.) Also, this class describes various tag<->object mappings. For example, a 'cfoutput' tag may be associated to 'ColdFusion::TAG::Output'. This mapping is looked up inside ColdFusion::ParseTree to determine which 'tag' object should be created to handle specific Coldfusion tag. ColdFusion::ParseTree used by : ColdFusion::Parser, ColdFusion::TAGS::* created by : ColdFusion::Parser, ColdFusion::TAGS::* uses : ColdFusion::ParseRules Munches on a chunk of a ColdFusion-like template producing a tag parse tree in the end. Here's it's parse logic in point form: 1. Search for first recognized tag (consulting ColdFusion::ParseRules object). 2. If found, create a new tag object tasked to handle this tag (based on tag<->object mapping supplied by the ColdFusion::ParseRules object). 3. Complete initializing the newly created tag object by searching for it's end tag (in the template text) and setting tag's body to whatever's found enclosed within the pair opening/closing tags. 4. Repeat until entire template is parsed. Note: the first instance of a ParseTree class (initialized inside Parser class) will thus create 1-st level of the parse tree. The task of completing entire tree rests on nested tags each of which will use ParseTree objects to transform their bodies into tag trees. Here's an example of how 1-st level parse tree might look like: Source template: --------------------- <HTML> <HEAD> </HEAD> <BODY> Hello World! Welcome, <cfoutput>#foo_name#</cfoutput>! <cfif bool eq 1> <cfif foo = bar> <cfif bar = foo> </cfif> </cfif> BOOL is true! <cfelse> BOOL is false! </cfif> </BODY> </HTML> --------------------- 1-st level parse tree: --------------------- 'parse_tree' => [ '<HTML>', '<HEAD>', '</HEAD>', '<BODY>Hello World! Welcome, ', bless({ 'property' => { 'single' => '0', 'nested' => '0', 'attributes' => [ 'query' ] }, 'body' => '<cfoutput>#foo_name#</cfoutput>!', 'attributes' => {} }, 'Template::Parser::TAG::Output' ), bless({ 'property' => { 'single' => '0', 'nested' => 1, 'attributes' => [] }, 'body' => '<cfif bool eq 1> <cfif foo = bar> <cfif bar = foo> </cfif> </cfif> BOOL is true! <cfelse> BOOL is false! </cfif>' }, 'Template::Parser::TAG::Control::If' ), '</BODY>', '</HTML>' ], ------------------------- * produced by 'rough' version of ColdFusion template par +ser. By observing this sample parse tree, you should notice t +wo tag objects 'handling' first (top level) occurance of <cfoutput> and <cfif> tags respectively. ---------------------------------------------------------

Any comments/suggestions? ;-)

PS: I'm hoping to make draft copies of my code available on my private ftp for you to look at and hack soon ;).

"There is no system but GNU, and Linux is one of its kernels." -- Confession of Faith

In reply to ColdFusion::Parser design by vladb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.