by
Paul Perrin
Having worked in M for many years, I have
gradually built up a toolkit of useful utilities to help with development and support of M
systems. As a freelancer I work on various sites, and do not necessarily have access to
the equipment required to load software on to the clients machine. In this case I just
retype my utilities right into the system, along with any enhancements that may be useful
at that particular site.
One particularly useful bit of code is a
parser that scans M source code and breaks it down into individual commands -- this makes
it easy to locate calls to labels and other routines, identify operations on particular
variables etc... It could also form the basis of a language translator (convert your M to
C) or prepasser to enable you to add your own extensions to the M language.
A feature that I particularly like is that
because of the nature of M's syntax, the parser uses generic code for almost all commands
-- only requiring specific code for comment lines ';' and the arguments for the 'F'
command. The rest of the code is based on the structure of M being as follows.
A line is made up:
<optional
label><whitespace><optional dots/whitespace><commands>
Commands are made up:
<command name><colon and
optional post conditional><space><arguments><space or end of line>
Arguments are:
<argument><comma
<argument>
This code was used to generate an array
(CALLTREE) listing all the external calls made by various routines, it may not be perfect
but you can do what ever you like to improve it. It was written on ISM running under Unix
(but I think it is portable). It can be called as D PROC("^ROUTINE") -- if you
save it, you can even make it process itself.
Download and Installation
Click here to
download this routine.
After downloading the archive, unzip it to a
subdirectory. Use the Routine Restore command of your M implementation to upload it into
the UCI you want to work on.
Once loaded, you D ^PROC(<routine>),
where <routine> is the name of the program you want to parse. (Try out
D ^PROC("^PROC")).
The Source
PROC(RTN)�S $ZT="NXT"
�F L=1:1 X "S LIN=$T(+"_L_RTN_")" Q:LIN="" D
PARSE,TRAPCALL,SHANA
NXT�Q
PARSE�S ORIG=LIN
�S LBL=$$SKIPTO(.LIN," ")
�I LIN="" Q
�S LEV=$$SKIPOVER(.LIN,". ")
�S LEV=$L(LEV,".")
�K CMD
�F CMD=1:1 D Q:LIN=""
�.S (CMD(CMD,1),CMD(CMD,2),CMD(CMD,3))=""
�.S TMP=$$SKIPOVER(.LIN," ")
�.I $E(LIN)=";" D Q
�..S CMD(CMD,1)=";",CMD(CMD,3)=LIN,LIN=""
�.S CMD(CMD,1)=$$SKIPTO(.LIN," :",.TC)
�.I LIN="" Q
�.I TC=":" S CMD(CMD,2)=$$SKIPTO(.LIN," ")
�.I LIN="" Q
�.S CMD(CMD,3)=$$SKIPTO(.LIN," ")
�.S SLIN=CMD(CMD,3)
�.F SCMD=1:1 Q:SLIN="" D
�..I $E(CMD(CMD,1))="F" S CMD(CMD,3,SCMD,3)=$$SKIPTO(.SLIN,",",.TC)
�..I $E(CMD(CMD,1))'="F" S
CMD(CMD,3,SCMD,3)=$$SKIPTO(.SLIN,":,",.TC)
�..S CMD(CMD,3,SCMD,2)=""
�..I TC=":" S CMD(CMD,3,SCMD,2)=$$SKIPTO(.SLIN,",")
�.I SCMD=2,CMD(CMD,3,1,2)="" K CMD(CMD,3,1) Q
�.S CMD(CMD,3)=""
�Q
SKIPTO(SOUR,TERMCH,CH)
�N DEST,PC,QC
�S DEST="",(PC,QC)=0
�F D Q:SOUR="" Q:(PC=0)&(QC=0)&(TERMCH[CH)
�.S CH=$E(SOUR),SOUR=$E(SOUR,2,$L(SOUR))
�.I PC=0,QC=0,TERMCH[CH Q
�.I CH="""" S QC=1-QC
�.I QC=0 D
�..I CH="(" S PC=PC+1
�..I CH=")" S PC=PC-1
�.S DEST=DEST_CH
�Q DEST
SKIPOVER(SOUR,SKIPCH)
�N DEST,PC,QC
�S DEST="",(PC,QC)=0
�F Q:SKIPCH'[$E(SOUR) D Q:SOUR=""
�.I $E(SOUR)="""" S QC=1-QC
�.I QC=0 D
�..I $E(SOUR)="(" S PC=PC+1
�..I $E(SOUR)=")" S PC=PC-1
�.S DEST=DEST_$E(SOUR)
�.S SOUR=$E(SOUR,2,$L(SOUR))
�Q DEST
�;
�SHANA W "+",L,RTN," ",ORIG,!
�W LBL," (",LEV,")",!
�S (CMD,SCMD)=""
�F S CMD=$O(CMD(CMD)) Q:CMD="" D
�.W CMD(CMD,1)," - ",CMD(CMD,2)," - ",CMD(CMD,3),!
�.F S SCMD=$O(CMD(CMD,3,SCMD)) Q:SCMD="" D
�..W $J("",$L(CMD(CMD,1)))," -
",$J("",$L(CMD(CMD,2)))," - "
�..W CMD(CMD,3,SCMD,2)," - ",CMD(CMD,3,SCMD,3),!
�Q
TRAPCALL�S (CMD,SCMD)=""
�F S CMD=$O(CMD(CMD)) Q:CMD="" D
�.I "DG"'[$E(CMD(CMD,1)) Q
�.I CMD(CMD,3)["^" S CALLTREE(RTN,$P(CMD(CMD,3),"^",2))=""
Q
�.F S SCMD=$O(CMD(CMD,3,SCMD)) Q:SCMD="" D
�..S TO=CMD(CMD,3,SCMD,3)
�..I TO'["^" Q
�..S CALLTREE(RTN,$P(TO,"^",2))=""
�Q
Click here to
download this routine.
Contact Information |
| Paul Perrin is a freelance
programmer/consultant. He maintains the MTA UK&I's web page, and writes a regular
column in MTA UK&I's M Technology News called "News from the Net". e-mail: [email protected]
URL: http://www.admatic.com |
E&OE