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
|
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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.