Tim%UPenn@UDel-Relay@sri-unix.UUCP (08/04/83)
From: Tim Finin <Tim%UPenn@UDel-Relay> We have built a rule-driven lisp-to-lisp translation system (FRANZLATOR) in Franz lisp and have used it to translate KL-ONE from Interlisp to Franz. (We includes people here at Penn and at BBN and CCA). The system is modular so that modifying it to work with a different source and target dialect should involve only changing several data bases. The translator is organized as a two-pass system which is applied to a set of source-dialect files and produces a corresponding set of target-dialect files and a set of files containing notes about the translation (e.g. possible errors). During the first pass all of the source files are scanned to build up a database of information about the functions defined in the file (e.g. type of function, arity, how it evals its args). In the second pass the expressions in the source files are translated and the results written to the target files. The translation of an s-expression is driven by transformation rules applied according to an "eval-order" schedule (i.e. the arguments to a function call are translated before the call to the function itself). An additional initial pass may be required to perform certain character-level transformations, although this can often be done through the use of multiple readtables. The actual translation is done by a set of rewrite rules, each rule taking an s-expression into one or more resultant s-expressions. In addition to the usual "pattern" and "result" parts, rules can be easily augmented with arbitrary conditions and actions and can have several other attributes which control their application (e.g. a priority). Variables are represented using the "backquote" convention. Example of rules for Interlisp->Franz are: (NIL nil) ((NLISTP ,x) (not (dtpr ,x))) ((PROG1 ,@args) (prog2 nil ,@args)) ((DECLARE: ,@args) ,(translateDeclare: ,args)) ((and ,@x (and ,@y) ,@z) (and ,@x ,@y ,@z) -cyclic) The translation rules are presented to the system in the form described above and are immediately "compiled" (by macro-expansion) into Lisp code which is quite efficient and can be, of course, further compiled by LISZT. The pattern matching operation, for example, is "open coded" into a conjuction of primitive tests and action (e.g. EQ, EQUAL, LENGTH, SETQ). If you are interested in more information, contact me. - Tim at UPENN (csnet)