I am working to replace a format generator for financial reports which is dynamic based on format definitions.

In the past this was pure Perl/MySQL with mappings in the format definitions pointing either to MySQL table items or special perl functions to handle the data. Much of the calculations/login for report items were done by building MySQL statements with things such as +-*/ IFNULL IF CONCAT etc... Anything done in Perl was a special case that was coded by me rather than defined in the format editor.

The new format generator is to be more flexible. I am implementing an abstraction layer for the database so that I can just change a single mapping if a table changes rather than every format (really should have done that the first time around, sigh). I am also adding the possibility of other data sources, such as a system in another department we are able to call into.

In doing this, the old way of building everything into MySQL queries just isn't going to cut it, since some of this data won't be in MySQL and I don't want to put it into a temp table each time I run a report.

My thought, since the people making the format definitions are already familiar with the MySQL statement layout and basic functions they were using, is to parse this format into something that I can translate and use to do calculations in perl OR MySQL depending on where the data is coming from.

I need to build this into a logic engine that can be passed the data items and quickly generate the calculated value on a row by row basis.

So... that was the background... here is the real question. How would some of you go about this? I want to get it right this time around. Any help is appreciated.

My thoughts so far: I could write my own parser, but I was thinking it would be a good time to learn something like Parse::Recdescent or YAPP or something similar. I have never used any of these before and while I was looking I was having trouble figuring out how to do order of precedence.

Here are examples of what a statement might look like... Anthing in the form of {n} maps back to a data item in the abstraction. Some abstractions will have arguments (this is necessary since things like 1-n tables need some sort of wrapper to get the proper single field) they would look like {n(args)}.

1 + {3} * 5

#IF(test,then,else)
IF({3} > NOW()-INTERVAL 1 DAY, {3}, 'Some text')

                - Ant
                - Some of my best work - (1 2 3)


In reply to Parsing and executing a psuedo-language by suaveant

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.