Code Parsing

I've added some code parsing features to the Standard Libraries.

http://www.oehive.org/project/lib

Below is a sample for parsing queries -


/**
 * test-slibpro.p -
 *
 * (c) Copyright ABC Alon Blich Consulting Tech, Ltd.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see .
 *
 *  Contact information
 *  Email: alonblich@gmail.com
 *  Phone: +972-54-218-8086
 */

{slib/slibpro.i}

{slib/sliberr.i}



define var cQuery               as char no-undo.
define var cRecordPhraseList    as char no-undo.
define var cQueryTuning         as char no-undo.
define var lBreak               as log no-undo.
define var cByExpList           as char no-undo.
define var cByDescendList       as char no-undo.
define var lIndexedReposition   as log no-undo.
define var cMaxRows             as char no-undo.

define var cRecordPhrase        as char no-undo.
define var cJoin                as char no-undo.
define var cBuffer              as char no-undo.
define var cFields              as char no-undo.
define var cExcept              as char no-undo.
define var lLeft                as log no-undo.
define var lOuterJoin           as log no-undo.
define var cOf                  as char no-undo.
define var cWhere               as char no-undo.
define var cUseIndex            as char no-undo.
define var cLock                as char no-undo.
define var lNoPrefetch          as log no-undo.
define var i                    as int no-undo.

define var cError               as char no-undo.
define var cErrorMsg            as char no-undo.
define var cStackTrace          as char no-undo.



{slib/err_try}:

    run pro_parseQueryPhrase(

        input   "for each  pt_mstr ~n" +
                "    where pt_part >= '1' ~n" +
                "      and pt_desc1 begins 't' ~n" +
                "    use-index pt_part ~n" +
                "    no-lock, ~n" +

                "    last  sod_det fields (sod_nbr sod_line sod_part) ~n" +
                "    where sod_part = pt_part ~n" +
                "    outer-join ~n" +
                "    exclusive ~n" +

                "    break ~n" +
                "    by pt_prod_line desc~n" +
                "    by pt_part ~n",

        output  cQuery,
        output  cRecordPhraseList,
        output  cQueryTuning,
        output  lBreak,
        output  cByExpList,
        output  cByDescendList,
        output  lIndexedReposition,
        output  cMaxRows ).

    display
        cQuery                                  label "query"               format "x(50)"
        cQueryTuning                            label "query-tuning"        format "x(50)"
        lBreak                                  label "break"
        replace( cByExpList, chr(1), "," )      label "by"                  format "x(50)"
        replace( cByDescendList, chr(1), "," )  label "by descend"          format "x(50)"
        lIndexedReposition                      label "indexed-reposition"
        cMaxRows                                label "max-rows"            format "x(50)"
    with 1 columns 1 down width 80.



    repeat i = 1 to num-entries( cRecordPhraseList, chr(1) ):

        cRecordPhrase = entry( i, cRecordPhraseList, chr(1) ).

        run pro_parseRecordPhrase(
            input   cRecordPhrase,
            output  cJoin,
            output  cBuffer,
            output  cFields,
            output  cExcept,
            output  lLeft,
            output  lOuterJoin,
            output  cOf,
            output  cWhere,
            output  cUseIndex,
            output  cLock,
            output  lNoPrefetch ).

        display
            cJoin                           label "join"            format "x(50)"
            cBuffer                         label "buffer"          format "x(50)"
            replace( cFields, chr(1), "," ) label "fields"          format "x(50)"
            replace( cExcept, chr(1), "," ) label "except"          format "x(50)"
            lLeft                           label "left"
            lOuterJoin                      label "outer-join"
            cOf                             label "of"              format "x(50)"
            cWhere                          label "where"           format "x(50)"
            cUseIndex                       label "use-index"       format "x(50)"
            cLock                           label "lock"            format "x(50)"
            lNoPrefetch                     label "no-prefetch"
        with 1 columns 1 down width 80.

    end. /* 1 to num-entries */

{slib/err_catch cError cErrorMsg cStackTrace}:

    message
        cErrorMsg
        skip(1)
        cStackTrace
    view-as alert-box.

{slib/err_end}.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
alonb's picture

in case anyone would like to

in case anyone would like to take a closer look ...

the 2 main functions that make up the slibpro.p code parsing are ...

pro_parseWordList( )

pro_parseKeywordPhraseList( )

i'd be happy to start a discussion on code parsing and answer any questions, if i can.


tamhas's picture

Wouldn't one want to use

Wouldn't one want to use proparse for more reliable parsing?


alonb's picture

you probably wouldn't use

you probably wouldn't use proparse from your 4gl program because proparse is a java program.

you'd probably use proparse on your programs but not in your programs.

some cases you might like to parse code in your programs are -

i recently needed to parse a query object to get the explicit sorting.

i've used code parsing in the slibxlsx.p to parse vba formulas and change cell references.

in regards to architecture -

you could write a query on a logical dataset in the business logic layer that can be converted in the data layer to the actual tables (and even be optimized according to the filter).

i've played with something like that for the query optimizer project i did.

imho that's probably the biggest problem that we've been talking about in the oeri. that is, no true business logic and data access layer separation.

i believe we can do that with code parsing.


tamhas's picture

ProLint is an ABL program

ProLint is an ABL program which uses Proparse ... no reason not to build on that and have the accuracy and generality which Proparse can provide.

In terms of the BL and DA separation, isn't something like ABL2UML going to get you much more toward what you need?


john's picture

Re: code parsing

alonb wrote:
you probably wouldn't use proparse from your 4gl program because proparse is a java program

Proparse is also compiled to a .Net DLL, and used from ABL programs like Prolint.


alonb's picture

proparse is far more

proparse is far more powerful then the few code parsing procedures i have.

but because more then half my applications run on unix and because it's completely 4gl and light weight it's relatively easy to setup.

i would use it for mostly quick and simple parsing that are also done at run-time like getting the sort by from a query or something similar.

i think that run-time query transformation similar in idea to sql views is both doable and useful.

with a few changes you could also use it with other languages. i've used it for parsing vba in the slibxlsx.p utility.

anyway it's out there if anyone wants to use it or just have a look.


alonb's picture

Thomas are you going to be

Thomas are you going to be in EMEA PUG in Germany November 18 ??

I'd be really interested to meet you in person.