NAME ratfor - Ratfor preprocessor SYNOPSIS ratfor [files...] >outfile DESCRIPTION Ratfor translates the ratfor programs in the named files into Fortran. If no input files are given, or the filename '-' appears, the standard input will be read. A file containing general purpose software tools definitions (e.g. EOF, NEWLINE, EOS, etc.) will be automatically opened and processed before any of the files specified are read. Syntax: Ratfor has the following syntax: prog: stmt prog stmt stmt: if (expr) stmt if (expr) stmt else stmt while (expr) stmt repeat (expr) stmt repeat stmt until (expr) for (init expr; test expr; incr expr) stmt do expr stmt do n expr stmt break break n next next n return (expr) switch (expr) { case expr: stmt .... default: stmt } digits stmt { prog } or [ prog ] anything unrecognizable (i.e. fortran) where 'stmt' is any Fortran or Ratfor statement. A statement is terminated by an end-of-line or a semicolon. Character Translation: The following character translations are performed: < .lt. <= .le. == .eq. != .ne. ^= .ne. ~= .ne. >= .ge. > .gt. | .or. & .and. ! .not. ^ .not. ~ .not. Included files: The statement include file or include "file" will insert the contents of the specified file into the ratfor input in place of the 'include' statement. Quotes must surround the file name if it contains characters other than alphanumerics or underscores. Macro Definitions: The statement define(name,replacement text) defines 'name' as a macro which will be replaced with the indicated text when encountered in the source files. Any occurrences of the strings '$n' in the replacement text, where 1 <= n <= 9, will be replaced with the nth argument when the macro is actually invoked. For example: define(bump, $1 = $1 + 1) will cause the source line bump(i) to be expanded into i = i + 1 The names of macros may contain letters, digits and underline characters, but must start with a letter. Upper case is not equivalent to lower case in macro names. The replacement text is copied directly into the lookup table with no intepretation of the arguments, which differs from the procedure used in the macro utility. This "deferred evaluation" has the effect of eliminating the need for bracketing strings to get them through the macro processor unchanged. A side effect of the deferred evaluation is that defined names cannot be forced through the processor - i.e. the string "define" will never be output from the preprocessor. The inequivalence of upper and lower case in macro names may be used in this case to force the name of a user defined macro onto the output - i.e. if the user has defined a macro named mymac, the replacement text may contain the string MYMAC, which is not defined, and will pass through the processor. (For compatibility, an "mdefine" macro call has been included which interprets definitions before stacking them, as does the macro tool. When using this version, use "$(" and "$)" to indicate deferred evaluation, rather than the "[" and "]" used by the macro tool.) In addition to define, four other built-in macros are provided: arith(x,op,y) performs the "integer" arithmetic specified by op (+,-,*,/) on the two numeric operands and returns the result as its replacement. incr(x) converts the string x to a number, adds one to it, and returns the value as its replacement (as a character string). ifelse(a,b,c,d) compares a and b as character strings; if they are the same, c is pushed back onto the input, else d is pushed back. substr(s,m,n) produces the substring of s which starts at position m (with origin one), of length n. If n is omitted or too big, the rest of the string is used, while if m is out of range the result is a null string. Note: the statement define name text may also be used, but will not always perform correctly for macros with parameters or multi-line replacement text. The functional form is preferred. Conditional Preprocessing: The statements ifdef(macro,text) ifnotdef(macro,text) conditionalize the preprocessing upon whether the macro has been previously defined or not. String Data Types: The statements string name "character string" or string name(size) "character string" declare 'name' to be a character array long enough to accomodate the ascii codes for the given character string, one per array element. The array is then filled by data statements. The last word of 'name' is initialized to the symbolic parameter EOS, and indicates the end of a string. EOS must be defined either in the standard definitions file or by the user. If a size is given, name is declared to be a character array of 'size' elements. If several string declarations appear consecutively, the generated declarations for the arrays will precede the data statements that initialize them. String Literals: Conversion of in-line quoted strings to hollerith constants is performed in the following manner: "str" nHstr 'str' nHstr (where 'n' is the number of characters in str) String literals can be continued across line boundaries by ending the line to be continued with an underline. The underline is not included as part of the literal. Leading blanks and tabs on the next line are ignored. Integer Constants: Integer constants in bases other than decimal may be specified as n%dddd... where 'n' is a decimal number indicating the base and 'dddd...' are digits in that base. For bases > 10, letters are used for digits above 9. Examples include: 8%77 (=63), 16%2ff (=767), 2%0010011 (=19). The number is converted to the equivalent decimal value using multiplication; this may cause sign problems if the number has too many digits. Lines and Continuation: Input is free-format; that is, statements may appear anywhere on a line, and the end of the line is generally considered the end of the statement. However, lines ending in special characters such as comma, +, -, and * are assumed to be continued on the next line. An exception to this rule is within a condition; the line is assumed to be continued if the condition does not fit on one line. Explicit continuation is indicated by ending a line with an underline character (_). The underline character is not copied to the output file. Comments: Comments are preceded by '#' signs and may appear anywhere in the code. Literal (unprocessed) Lines: Lines can be passed through ratfor without being processed by putting a percent "%" as the first character on the line. The percent will be removed and the line shifted one position to the left, but otherwise will be output without change. Macro invocations, long names, etc., appearing in the line will not be processed. Long Variable Names Unlike Fortran, Ratfor variable names may be essentially any length, and may contain underscores as well as letters and digits. Every character in a variable name is significant; "very_long_variable_name_1" is different from "very_long_variable_name_2". Ratfor converts such exceptional names into legal Fortran names of six alphanumeric characters, and guarantees that no conflicts will arise from converting two special names or from user variables that happen to be the same as a Ratfor-generated name. In the unfortunate event that it ever becomes necessary to debug the Fortran output of Ratfor, Ratfor outputs a "long name dictionary" as a series of comments at the end of its output code. This dictionary shows each internal variable name along with its Fortran equivalent. CHANGES This ratfor preprocessor differs from the original (as released by Kernighan and Plauger) in the following ways: The code has been rewritten and reorganized. Hash tables have been added for increased efficiency in searching for macro definitions and Ratfor keywords. The 'string' declaration has been included. The define processor has been augmented to support macros with arguments. Conditional preprocessing upon the definition (or lack therof) of a symbol has been included. Many extraneous gotos have been avoided. Blanks have been included in the output for increased readability. Multi-level 'break' and 'next' statements have been included. The Fortran 'DO' is allowed, as well as the ratfor one. The capability of specifying integer constants in bases other than decimal has been added. Underscores have been allowed in names. The 'define' syntax has been expanded to include the form: define name value The 'return(value)' feature has been added. Quoted file names following 'include' statements have been added to allow for special characters in file names. A method for allowing lines to pass through un-processed has been added. The 'switch' control statement has been included. Continuation lines have been implemented. Brackets have been allowed to replace braces (but NOT $( and $) ) Variable names that are longer than 6 characters or that contain underscores are automatically converted to legal Fortran variable names. FILES A generalized definition file (e.g. 'ratdef') is automatically opened and read. SEE ALSO Kernighan and Plauger's "Software Tools" Kernighan's "RATFOR - A Preprocessor for a Rational Fortran" The Unix command rc in the Unix Manual The tools 'incl' and 'macro' DIAGNOSTICS (The errors marked with asterisk '*' are fatal; all others are simply warning messages.) * arg stack overflow The argument stack for the macro processor has been exceeded. The size of the stack is determined by the symbol ARGSIZE in the source definitions file. * buffer overflow One of the preprocessor's internal buffers overflowed, possibly, but not necessarily, because the string buffers were exceeded. The definition SBUFSIZE in the preprocessor symbols file determines the size of the string buffers. * call stack overflow The call stack (used to store call frames) in the macro processor has been exceeded. The definition CALLSIZE in the source definition file determines the size of this stack. can't open standard definitions file The special file containing general purpose ratfor definitions could not be opened, possibly because it did not exist or the user did not have access to the directory on which it resides. can't open include File to be included could not be located, the user did not have privilege to access it, or the file could not be opened due to some problem in the local primitives. * definition too long The number of characters in the name to be defined exceeded Ratfor's internal array size. The size is defined by the MAXTOK definition in the preprocessor symbols file. * EOF in string The macro processor detected an EOF in the current input file while evaluating a macro. * evaluation stack overflow The evaluation stack for the macro processor has been exceeded. This stack's size is determined by the symbol EVALSIZE in the source definition file. * for clause too long The internal buffer used to hold the clauses for the 'for' statement was exceeded. Size of this buffer is determined by the MAXFORSTK definition in the preprocessor symbols file. * getdef is confused There were horrendous problems when attempting to access the definition table illegal break Break did not occur inside a valid "while", "for", or "repeat" loop illegal else Else clause probably did not follow an "if" clause illegal next "Next" did not occur inside a valid "for", "while", or "repeat" loop illegal right brace A right brace was found without a matching left brace * in dsget: out of dynamic storage space There is insufficient memory for macro definitions, long variable names, etc. Increase the MEMSIZE definition in the preprocessor. includes nested too deeply There is a limit to the level of nesting of included files. It is dependent upon the maximum number of opened files allowed at a time, and is set by the NFILES definition in the preprocessor symbols file. invalid for clause The "for" clause did not contain a valid init, condition, and/or increment section invalid string size The string format 'string name(size) "..."' was used, but the size was given improperly. * missing comma in define Definitions of the form 'define(name,defn)' must include the comma as a separator. missing function name There was an error in declaring a function missing left paren A parenthesis was expected, probably in an "if" statement, but not found missing parenthesis in condition A right parenthesis was expected, probably in an "if" statement, but not found missing quote A quoted string was not terminated by a quote missing right paren A right parenthesis was expected in a Fortran (as opposed to Ratfor) statement but not found missing string token No array name was given when declaring a string variable * non-alphanumeric name Definitions may contain only alphanumeric characters and underscores. * stack overflow in parser Statements were nested at too deep a level. The stack depth is set by the MAXSTACK definition in the preprocessor symbols file. token too long A token (word) in the source code was too long to fit into one of Ratfor's internal arrays. The maximum size is set by the MAXTOK definition in the preprocessor symbols file. * too many characters pushed back The source code has illegally specified a Ratfor command, or has used a Ratfor keyword in an illegal manner, and the parser has attempted but failed to make sense out of it. The size of the push-back buffer is set by BUFSIZE in the preprocessor symbols file. unbalanced parentheses Unbalanced parentheses detected in a Fortran (as opposed to Ratfor) statement unexpected brace or EOF A brace occurred after a Fortran (but not Ratfor) statement or an end-of-file was reached before the end of a statement unexpected EOF An end-of-file was reached before all braces had been accounted for. This is usually caused by unmatched braces somewhere deep in the source code. warning: possible label conflict This message is printed when the user has labeled a statement with a label in the 23000-23999 range. Ratfor statements are assigned in this range and a user-defined one may conflict with a Ratfor-generated one. "file": cannot open Ratfor could not open an input file specified by the user on the command line. AUTHORS Original by B. Kernighan and P. J. Plauger, with rewrites and enhancements by David Hanson and friends (U. of Arizona), Joe Sventek and Debbie Scherrer (Lawrence Berkeley Laboratory), and Allen Akin (Georgia Institute of Technology). BUGS/DEFICIENCIES Missing parentheses or braces may cause erratic behavior. Eventually Ratfor should be taught to terminate parenthesis/brace checking at the end of each subroutine. Although one bug was fixed which caused line numbers in error messages to be incorrect, they still aren't quite right. (newlines in macro text are difficult to handle properly). Use them only as a general area in which to look for errors. Extraneous 'continue' statements are generated within Fortran 'do' statements. The 'next' statement does not work properly when used within Fortran 'do' statements. There is no way to explicitly cause a statement to begin in column 6 (i.e. a Fortran continued statement), although implicit continuation is performed. The 'switch' statement generates a variable to be used in a computed goto. This variable is undeclared and its type may be incorrect due to a preceding 'implicit' declaration. Because of this and other (minor) faults, the 'switch' statement should be considered experimental and subject to change or deletion in the future. Use it with care! Ratfor is very slow, principally in the lexical analysis, character input, and macro processing routines (in that order). Attempts to speed it up should concentrate on the routines 'gtok', 'ngetch', and 'deftok'. An even better approach would be to re-work the lexical analyzer and parser completely. Problems arise with the long variable name conversion process if subprograms or common blocks with long names are compiled separately. The easiest way to avoid this is to use 6-character or shorter names (with no underscores and not ending in the character zero) for external subprograms and common blocks. In the future, a "linkage" statement will be added to get around this difficulty.