prohaska@coors.DEC (08/20/85)
I have developed a preprocessor for writing DCL command procedures using control structures like if-then-else, while, for etc. It is similar to what RATFOR is for writing structured FORTRAN. The preprocessor is written in C. I posted the source to net.sources about a month ago. I am posting an excerpt from the documentation to net.decus. If there is enough interest, I'll post the source to net.decus. Or you can send me individual inquires for the source. Sohail Aslam ...decvax!decwrl!dec-rhea!dec-coors!prohaska Here's the excerpt. SDCL -- A Preprocessor for Structured DCL The command language under the VAX/VMS operating system is called Digital Command Language, or DCL. DCL provides a whole host of capabilities that allow the user not only execute simple commands but develop command procedures that can accomplish a complex task. DCL provides variables, conditional operators, an IF-THEN-command construct and a number of built-in functions. It is thus a small programming language. Unfortunately, the only control structure provided is the IF condition THEN a command By building a simple preprocessor, I have extended the control structure to include C like control structures, e.g, if-else, while, for, do-while etc. These structures can operate on a single command or a group of commands. The real motivation for wanting to have structured DCL came from the tradition set by RATFOR (RATional FORtran). For those of you not familiar with RATFOR, RATFOR allows one to write code in FORTRAN in a C like manner. DCL has similar deficiencies when it comes to writing command procedures. I just wanted to illustrate that one does not have to live with GOTO's and COMEFROM's in one's programming practices. It is rather trivial to develop a layer of structured environment on top of something that does not support it. Page 2 The language recognized, and thus parsed, by sdcl is very simple. Here it is BNF form: program : statement | program statement statement : if ( condition ) statement | if ( condition ) statement else statement | while ( condition ) statement | for ( intialize ; condition ; reinitialze ) statement | do statement while ( condition ) | break | next | { program } | other Here is a summary of sdcl usage. o The input file to sdcl is an ordinary text file containing sdcl statements. Unlike DCL, statements must not begin with a "$" sign. o Statements can be enclosed within {} to form the so-called compound statement. o The preprocessor looks at the first token of each statement to determine the type of statement so you should not preceed keywords with DCL labels e.g. "usage: if( p1 .eqs. ..". Statements that donot match one of the structured statements are classified as "other" and simply emitted. o Any sdcl source statement can be continued across more that one line by placing a "\" (backslash) just before the end of line. o In structured constructs, the "\" need not be used however, because sdcl can infer whether the constructs is complete or not by simply going across line boundaries until satisfied. So if the condition part is too long to fit on one line in an "if" statement, it can simply be continued on the next line. o Donot use the "-" (minus) as the continuation character in sdcl statements. o If a source line begins with a "#" sign, the pound sign is removed and rest of the line is emitted AS IS. This can be used to pass lines through sdcl untouched to DCL. Page 3 Here is a command procedure to give you a flavor of sdcl, /* Bun -- VMS DCL command procedure to bundle files into */ /* distribution package which can then be unbundled */ /* using UNIX shell. The output will be placed on the */ /* on the file given as the arg to this procedure */ if( p1 .eqs. "" ){ write sys$output\ "Usage: bundle outfile (outfile will receive bundle)" exit /* DCL exit */ } /* if the file exists, open it, otherwise create it */ open/write/err=out_err fout 'p1' exist := "TRUE" out_err: if( exist .nes. "TRUE" ){ create 'p1' open/write/err=give_up fout 'p1' } q := "'" for( rc = 0; ; ){ /* no condition, no reinit */ inquire infile "File? " if( infile .eqs. "" ) break /* time to wrapup */ open/read/err=infile_err inf 'infile' write fout "echo ''infile' 1>&2" write fout "cat >''infile' <<''q'END OF ''infile'''q'" rc = rc + 2 done = 0 while( done .eq. 0 ){ read/end=eof inf line write fout line rc = rc + 1 } eof: close inf write fout "END OF ''infile'" rc = rc + 1 next /* come here if trouble opening 'infile' */ infile_err: write sys$output \ "error opening ''infile'" } if( rc .gt. 0 ){ write sys$output "''rc' records written to ''p1'" close fout } else write sys$output "0 records written out" exit