home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / extrnl / adaform.msg next >
Encoding:
Internet Message Format  |  1988-05-03  |  12.9 KB

  1. From: decvax!bellcore!allegra!princeton!siemens!emery@Ucb-Vax.ARPA
  2. To: net.sources
  3. Subject: Ada formatter for Scribe
  4. Date: 2 May 85 15:08:00 GMT
  5.  
  6. We use Scribe as our standard word processing system.  We needed a way
  7. to present Ada code within some text.  The Ada Language Reference
  8. Manual has defined a presentation style for Ada code, with reserved
  9. words in lower-case/boldface.  We wanted to use this style, and add
  10. other changes to make the code more readable.  In particular, we
  11. wanted to set comments off from Ada code.  Finally, we wanted to do
  12. this without having to modify our Ada code by hand.
  13.  
  14. To meet these requirements, we developed a tool called "adaform".
  15. "adaform" is a UNIX filter that accepts (well formed) Ada programs
  16. from stdin, and adds Scribe commands.  The output is then suitable for
  17. 'Scribing'.  See the implementation section for a definition of the
  18. Scribe environmnents used by adaform.  Invocation is "adaform < <your
  19. input> > <your output>".  You must direct input from standard input;
  20. adaform does not recognize the convention that a filename may be
  21. passed as a parameter for standard input.
  22.  
  23. The following is straight text, of 3 parts: The first is a description
  24. of the tool, followed by the LEX file, followed by our C driver
  25. program.
  26.  
  27. Capabilities:
  28.  
  29. adaform does the following things:
  30.  
  31. 1. Ada reserved words are printed in boldface.
  32.  
  33. 2. Ada comments are printed in italics.
  34.  
  35. 3. Comment reserved words (such as pre-conditions, history, etc.) are 
  36. printed in bold italics.
  37.  
  38. 4.  Pragma page is recognized; a new page is started after this pragma.
  39. Additionally, every library unit is started on a new page (triggered by an
  40. Ada 'with' clause.)
  41.  
  42. 5.  Package, procedure, function, type, subtype and task names are 
  43. indexed.  The index entry is the identifier, followed by the Ada thing
  44. identified.  Additionally, if you use the LibraryFile MultiLevelIndex, 
  45. then there is a secondary index by the class of item.  for instance:
  46.     Foo, package            2
  47.     Fred, type            1
  48.     Frog, type            3
  49.     Fubar, task            3
  50.     package
  51.       Foo                       2
  52.     task
  53.       Fubar                3
  54.       Fred                1
  55.       Frog                3
  56.  
  57. 6.  A 'hinge' is placed on each blank line.  This means that a group of
  58. non-blank lines will be kept on one page.  An example of this is a
  59. function declaration and its comments.
  60.  
  61. Limitations:  
  62.  
  63. adaform expects legal Ada code.  It has no error handling, and its actions
  64. on an ill-formed program are undefined, and will probably either give you
  65. a lex error, or garbage.
  66.  
  67. The logic used to detect a new compilation unit is very primitive.  If
  68. adaform finds a with clause (that is not in a generic declaration), it
  69. first inserts a page feed (@newpage).  Lines preceeding the with clause
  70. will be placed on the preceeding page.  If there is more than one 
  71. compilation unit in a package, and they do not have with clauses, then
  72. they will not start on a new page.  The rule of thumb here is first,
  73. use only 1 compilation unit per text file, and second, don't use 
  74. preceeding comments.
  75.  
  76. If a set of non-blank lines exceeds a single page, Scribe will probably
  77. issue an error message.  Use "pragma page" to establish page breaks.
  78.  
  79. The only 'prettyprinting' performed by adaform is that reserved words are
  80. translated to lower case, except for EXIT, RETURN, RAISE and GOTO. Adaform
  81. performs no formatting.  However, tabs are converted to the scribe tab
  82. character "@\".  
  83.  
  84. Because the output from Scribe is in proportionally spaced fonts, column
  85. alignment is not preserved.  This is most noticable when you have a comment
  86. like:
  87.  
  88. ----------------------------------
  89. --  Here is my comment          --
  90. ----------------------------------
  91. This usually comes out looking something like:
  92.  
  93. -----------------------
  94. --  Here is my comment         --
  95. -----------------------
  96.  
  97. due to the different character widths of the text and the '-' character.
  98. To insure indentation alignment, use tabs instead of spaces.
  99.  
  100. Implementation:
  101.  
  102. adaform was created using Lex and Herm Fischer's Lex input for his Ada 
  103. grammar.  Because it is 'lexed', and I'm not a Lexpert, it runs a little
  104. slowly.  A driver is also requred for the Lex output, this driver writes 
  105. out the environment standards, and then calls yylex().
  106.  
  107. There are 4 Scribe definitions needed to support adaform.  These are
  108. definitions of the various Scribe environments used by adaform:
  109.  
  110. @define(AdaResWord=B)        makes reserved words all boldface
  111. @define(AdaComment=I)           comments are in italics
  112. @define(AdaCommentWord=P)       special comment reserved words in bold italics
  113.  
  114. @define(AdaCode=example, FaceCode R, LeftMargin 0, RightMargin 0, 
  115.         font SmallBodyFont, BlankLines=HingeKeep)
  116.  
  117.                     AdaCode is an example environment, with 
  118.                 no indentation, using roman (standard) type,
  119.                 in the SmallBodyFont (10 point), and simulates
  120.                 a hinge command at each blank line.
  121.  
  122. These definitions are usually written out by the driver.
  123.  
  124. Future Features:
  125.  
  126. I hope to add scope information to the index entries, so the following 
  127. will be the result:
  128.  
  129.     Foo, type, defined in Ralph.Bar        3
  130.     Fred, function, defined in Ralph    2
  131.  
  132. It would be nice to make adaform more intelligent about when to start a new
  133. page.
  134.  
  135. Finally, in conjunction with a conventional prettyprinter, I hope to solve
  136. the alignment problem when using porportional spaced fonts.
  137.  
  138. Send bugs (hopefully with fixes) to:
  139.  
  140.                             Dave Emery
  141.         uucp:    ...princeton!siemens!emery 
  142.         arpa:    "siemens!emery"@topaz
  143.         us mail: Siemens Research
  144.              105 College Rd East
  145.              Princeton, NJ 08540
  146.         ma bell: (609) 734-6568
  147.  
  148.  
  149. trademarks:  Ada is a trademark of U.S. Government, AJPO.  Scribe is a
  150. trademark of Unilogic, Inc.  UNIX is a trademark of ATT Bell Labs.
  151. LEX DEFINITION
  152. %{
  153. /**************************************************************************/
  154. /*                 Ada for SCRIBE PRINTER                                 */
  155. /**************************************************************************/
  156. /*------------------------------------------------------------------------*/
  157. /* Lexical input for LEX for LALR(1) Grammar for ANSI Ada                 */
  158. /*                                                                        */
  159. /*              Herman Fischer                                            */
  160. /*            Litton Data Systems                                         */
  161. /*              March 26, 1984                                            */
  162. /*                                                                        */
  163. /*------------------------------------------------------------------------*/
  164.     int    my_start   = 0; /* indicates that it's startup time       */
  165.     int    ignore_next_subprog = 0;  /* when in a generic parameter  */
  166.                       /* declaration, indicates that  */
  167.                       /* the next subprogram is a     */
  168.                       /* formal parameter, and not    */
  169.                       /* the actual generic thing.    */
  170.     int    funct_defn = 0;  /* indicates that this return is part    */
  171.                  /* of a function declaration, and should */
  172.                  /* not be capitalized              */ 
  173.     char    class[20];
  174. #include "stdio.h"
  175. #include "ctype.h"
  176. %}
  177.  
  178. %e      3500  /* tree nodes array size    */
  179. %p      9500  /* positions                */
  180. %a      10000  /* transitions array size   */
  181. %k      500   /* packed character classes */
  182. %o      10000  /* output array size        */
  183. %n    2000   /* states ?!          */
  184.  
  185. %START IDENT Z COMMENT OTHERCMT PRAGMA KEEPNAME GENERICSPEC
  186.  
  187. %%
  188.      {BEGIN Z;}
  189. <Z,IDENT>(ABORT|abort)|(ABS|abs)|(ACCEPT|accept)|(ACCESS|access)    |
  190. <Z,IDENT>(ALL|all)|(AND|and)|(ARRAY|array)|(AT|at)            |
  191. <Z,IDENT>(BEGIN|begin)|(BODY|body)|(CASE|case)|(CONSTANT|constant)    |
  192. <Z,IDENT>(DECLARE|declare)|(DELAY|delay)|(DELTA|delta)|(DIGITS|digits)    |
  193. <Z,IDENT>(DO|do)|(ELSE|else)|(ELSIF|elsif)|(END|end)|(ENTRY|entry)    |
  194. <Z,IDENT>(EXCEPTION|exception)|(FOR|for)                |
  195. <Z,IDENT>(IF|if)|(IN|in)|(IS|is)|(LIMITED|limited)|(LOOP|loop)        |
  196. <Z,IDENT>(MOD|mod)|(NEW|new)|(NOT|not)|(NULL|null)|(OF|of)|(OR|or)    |
  197. <Z,IDENT>(OTHERS|others)|(OUT|out)|(PRIVATE|private)            |
  198. <Z,IDENT>(RANGE|range)|(RECORD|record)|(REM|rem)            |
  199. <Z,IDENT>(RENAMES|renames)|(REVERSE|reverse)                |
  200. <Z,IDENT>(SELECT|select)|(SEPARATE|separate)                |
  201. <Z,IDENT>(TERMINATE|terminate)|(THEN|then)|(USE|use)            |
  202. <Z,IDENT>(WHEN|when)|(WHILE|while)|(XOR|xor)                {
  203.             MAKELOWER(yytext); hilite(yytext); BEGIN Z;    }
  204.  
  205. <Z,IDENT>(WITH|with)                            {
  206.             printf("\n@newpage\n");
  207.             MAKELOWER(yytext); hilite(yytext);
  208.             BEGIN Z;                    }
  209.  
  210.  
  211. <Z,IDENT>(GOTO|goto)|(EXIT|exit)|(RAISE|raise)                {
  212.             MAKEUPPER(yytext); hilite(yytext); BEGIN Z;    }
  213.  
  214. <Z,IDENT>(RETURN|return)                        {
  215.             if (funct_defn) 
  216.                 funct_defn = 0;
  217.              else   {MAKEUPPER(yytext);
  218.                  funct_defn = 0;};
  219.             hilite(yytext); BEGIN Z;            }
  220.  
  221. <Z,IDENT>("=>")|("..")|("**")|(":=")|("/=")|(">=")|("<=")|("<<")    |
  222. <Z,IDENT>(">>")|("<>")|("&")|("(")|("*")|("+")|(",")|("-")|(".")    |
  223. <Z,IDENT>("/")|(":")|(";")|("<")|("=")|(">")|("|")            {
  224.                         ECHO; BEGIN Z;        }
  225.  
  226. <Z,IDENT>")"             {ECHO; BEGIN IDENT;}
  227.  
  228. "\t"                {unput('\\'); unput('@');}
  229.  
  230. <Z,IDENT>(PRAGMA|pragma)    {
  231.                 MAKELOWER(yytext);
  232.                 hilite(yytext);
  233.                 BEGIN PRAGMA;
  234.                 }
  235.  
  236. <PRAGMA>[" "(@\\)]+(PAGE|page)[ (@\\)]*;    {
  237.                     ECHO;
  238.                     printf("\n@newpage\n");
  239.                     BEGIN Z;
  240.                     }
  241.  
  242. <PRAGMA>.            {
  243.                 unput(yytext[0]);
  244.                 BEGIN Z;
  245.                 }
  246.  
  247. <Z,IDENT>TYPE|type        |
  248. <Z,IDENT>SUBTYPE|subtype    |
  249. <Z,IDENT>TASK|task        |
  250. <Z,IDENT>(PROCEDURE|procedure)    |
  251. <Z,IDENT>(PACKAGE|package)     {
  252.                 MAKELOWER(yytext);
  253.                 hilite(yytext); strcpy(class, yytext);
  254.                 BEGIN KEEPNAME;}
  255.  
  256.  
  257. <Z,IDENT>(FUNCTION|function)    {
  258.                 MAKELOWER(yytext);
  259.                 hilite(yytext); strcpy(class, yytext);
  260.                 funct_defn = 1;
  261.                 BEGIN KEEPNAME;}
  262.  
  263.  
  264. <KEEPNAME>[a-zA-Z][a-z_A-Z0-9]*       {
  265.                 ECHO; printf("@index(%s, %s)", yytext, class);
  266.            printf("@indexsecondary(primary=%s, secondary=%s)", class, yytext);
  267.                 BEGIN Z;}
  268.  
  269. <Z,IDENT>(GENERIC|generic)    {
  270.                 MAKELOWER(yytext); hilite(yytext); 
  271.                 BEGIN GENERICSPEC;}
  272.  
  273. <GENERICSPEC>(WITH|with)                        {
  274.                 MAKELOWER(yytext); hilite(yytext);
  275.                 ignore_next_subprog = 1;}
  276.  
  277. <GENERICSPEC>(PROCEDURE|procedure)|(FUNCTION|function)            {
  278.                 MAKELOWER(yytext); hilite(yytext);
  279.                 {if (ignore_next_subprog)
  280.                     ignore_next_subprog = 0;
  281.                  else {
  282.                         {if (strcmp(yytext,"procedure"))
  283.                         strcpy(class,"generic procedure");
  284.                      else    
  285.                         strcpy(class,"generic function");
  286.                         funct_defn = 1;
  287.                     };
  288.                     ignore_next_subprog = 0;
  289.                     BEGIN KEEPNAME;
  290.                        };
  291.                 };
  292.                                     }
  293.  
  294. <GENERICSPEC>(PACKAGE|package)                        {
  295.                 MAKELOWER(yytext); hilite(yytext);
  296.                 strcpy(class,"generic package");
  297.                 BEGIN KEEPNAME;}
  298.  
  299.  
  300. <GENERICSPEC>(ACCESS|access)|(ARRAY|array)|(CONSTANT|constant)        |
  301. <GENERICSPEC>(DELTA|delta)|(DIGITS|digits)|(IN|in)|(IS|is)        |
  302. <GENERICSPEC>(LIMITED|limited)|(OF|of)|(OTHERS|others)|(OUT|out)    |
  303. <GENERICSPEC>(PRIVATE|private)|(RANGE|range)|(RETURN|return)        |
  304. <GENERICSPEC>(SUBTYPE|subtype)|(TYPE|type)                {
  305.                 MAKELOWER(yytext); hilite(yytext);    }
  306.  
  307. <GENERICSPEC>[a-zA-Z][a-z_A-Z0-9]*    {ECHO;}
  308.  
  309. <GENERICSPEC>.                {ECHO;}
  310.  
  311.  
  312. <IDENT>\'  {ECHO; BEGIN Z;}   /* type mark only */
  313.  
  314. <Z,IDENT>[a-zA-Z][a-z_A-Z0-9]*       {ECHO; BEGIN IDENT; }
  315.  
  316. <Z,IDENT>[0-9][0-9_]*([.][0-9_]+)?([Ee][-+]?[0-9_]+)?  {
  317.                                  ECHO; BEGIN Z; }
  318.  
  319. <Z,IDENT>[0-9][0-9_]*#[0-9a-fA-F_]+([.][0-9a-fA-F_]+)?#([Ee][-+]?[0-9_]+)? {
  320.                   ECHO; BEGIN Z; }
  321.  
  322. <Z,IDENT>\"([^\"]*(\"\")*)*\" {ECHO; BEGIN Z; }
  323.  
  324. <Z>\'([^\']|\'\')\'    {ECHO; BEGIN Z; }
  325.  
  326. <Z,IDENT>[" "(@\\)]   {ECHO;}          /* ignore spaces and tabs */
  327.  
  328. <Z,IDENT>.       {ECHO; printf("?? lexical error [%s] ??\n(@\\)", yytext);}
  329.  
  330. <Z,IDENT>"--"([" "(@\\)]*)    {ECHO; BEGIN COMMENT;}
  331.  
  332. <COMMENT,OTHERCMT>"-"+    {ECHO;}
  333. <COMMENT,OTHERCMT>[\n]    {ECHO; BEGIN Z;}
  334.  
  335. <COMMENT>(("Function"[" "(@\\)]*":")|("Reference"[" "(@\\)]*":"))        |
  336. <COMMENT>(("History"[" "(@\\)]*":")|("Exceptions"[" "(@\\)]*":"))        |
  337. <COMMENT>(("Authorization"[" "(@\\)]*":")|("Pre-conditions"[" "(@\\)]*":"))    |
  338. <COMMENT>(("Post-conditions"[" "(@\\)]*":")|("EXCEPTIONS"[" "(@\\)]*":"))    {
  339.                 printf("@AdaCommentWord(%s)", yytext);
  340.                 BEGIN OTHERCMT;
  341.                                     }
  342.  
  343. <COMMENT>.    {
  344.          unput(yytext[0]); 
  345.          BEGIN OTHERCMT;
  346.         }
  347.  
  348. <OTHERCMT>.*    {
  349.          printf("@begin(AdaComment)%s@end(AdaComment)", yytext);
  350.          BEGIN Z;
  351.         }
  352.  
  353. %%
  354. hilite(it)    
  355.     char     *it;
  356. {printf("@AdaResWord(%s)", it);}
  357.  
  358. MAKEUPPER(s)
  359.     char    *s;
  360. {
  361.     for (; *s != NULL; ++s)
  362.         *s = (islower(*s) ? toupper(*s) : *s);
  363. }
  364. MAKELOWER(s)
  365.     char    *s;
  366. {
  367.     for (; *s != NULL; ++s)
  368.         *s = (isupper(*s) ? tolower(*s) : *s);
  369. }
  370.  
  371. end of LEX DEFINITION
  372. OUR DRIVER:
  373.  
  374. main()
  375.  
  376. {
  377.     printf("@comment(formatted with adaform v 1.3)\n");
  378.     printf("@define(AdaResWord=B)\n");
  379.     printf("@define(AdaComment=I)\n");
  380.     printf("@define(AdaCommentWord=P)\n");
  381. printf("@define(AdaCode=example, FaceCode R, LeftMargin 0, RightMargin 0,\n");
  382.     printf("\t font SmallBodyFont, blanklines=hingekeep)\n");
  383.     printf("@begin(AdaCode)\n");
  384.     printf("@TabClear\n@TabDivide(10)\n");
  385.     yylex();
  386.     printf("@end(AdaCode)\n");
  387. }
  388.  
  389. end of OUR DRIVER
  390.