home *** CD-ROM | disk | FTP | other *** search
/ The Education Master 1994 (4th Edition) / EDUCATIONS_MASTER_4TH_EDITION.bin / files / progmisc / qparser2 / cskels / main.c < prev    next >
Encoding:
Text File  |  1993-11-07  |  6.4 KB  |  183 lines

  1. /* main.c
  2.  
  3.    QCAD Systems, Inc. 1990
  4.  
  5.    'main' program for parser construction
  6.  
  7.   This is the 'main' section for an LALR(1) table-driven parser for
  8.   use with QPARSER.
  9.  
  10.   FILE REDIRECTION
  11.  
  12.     DOS and the Unix shells permit redirecting stdin and stdout to/from
  13.   a file.  Determining whether I/O comes from a file or the keyboard/screen
  14.   from within the program is not easy.  We recommend NOT using redirection
  15.   when debugging interactively.  You can specify a file name
  16.   containing source material as a command-line option without interfering
  17.   with keyboard/screen I/O; for example:
  18.  
  19.      main -d2 t1.cal
  20.  
  21.   provides full interactivity with text drawn from file 't1.cal'.
  22.  
  23.   DEBUGGING TOOLS:
  24.  
  25.     1. Compile all files with /DDEBUG (or -DDEBUG in Unix) compiler options:
  26.        This generates debugging tables and code.
  27.     2. You can insert the character '!' in the source file at a position
  28.        at which debugging is desired.  The parser will stop and bring up
  29.        an interactive menu when that token is scanned.
  30.     3. You can call the compiled program with any of the following options:
  31.  
  32.           -dN:  starts debugging, setting debug level to N
  33.           -s:   copy source lines to stdout when read by lex.  This is
  34.                    useful when a source file name is specified in the
  35.                    command line
  36.  
  37.   INTERACTIVE MENU:
  38.  
  39.     From the interactive debugging menu, you can:
  40.  
  41.     1. Set any number of 'production traps'.
  42.        When a production trap is set, the parser will stop just before
  43.        that production is reduced.
  44.     2. Choose to see only the production before reduction (level 1),
  45.        the stack and the production (level 2), all parser actions (level 3),
  46.        or all parser actions and error recovery actions (level 4).
  47.     3. Display the current lexical token and line position.
  48.     4. Inspect a tree built by the qtrees option by walking down through
  49.        and examining nodes in detail.
  50.     5. Send a screen dump to file 'screen.txt'.  (This only works for
  51.        DOS and 24 x 80 text screens, color or mono).
  52.  
  53.   All these capabilities are written into the skeleton files -- see
  54.     skeldbug for details.  You will want to augment these functions
  55.     as your semantic actions grow in complexity.
  56.  
  57.   IMPLEMENTATION NOTES
  58.  
  59.      You will need the \QPARSER\LIB directory compiled for certain
  60.      modules.  Make sure its memory model and compiler agree with
  61.      those in your work directory.
  62.  
  63.      Where it seems to matter, use one of the compiler directives
  64.      indicated below.
  65.  
  66.                        MicroSoft       (-DMSDOS supplied by default)
  67.                        Turbo C++       -DTCC
  68.                        Unix system V   -DUNIX
  69.  
  70.      You can generate source code on an AT and copy it to a Unix or
  71.      other system.  Use the -DUNIX option to deal with a few differences
  72.      between System V Unix and MSDOS compilers.
  73.  
  74.      Depending on which C compiler you are using, you may have to
  75.      manually make adjustments for these conditions:
  76.  
  77.      - Some compilers buffer output to the screen when the screen is
  78.          accessed through a file and fprintf calls (as opposed to printf).
  79.      - The "fgets" function does not return an EOF condition in some
  80.          C implementations, so an end state may be necessary in your
  81.          grammar (as in the token "quit" in the CALC grammar).
  82.      - The "resp" function behaves differently in a Unix environment
  83.          than a PC environment.  The root of the problem is that in Unix,
  84.          the standard function "getchar" doesn't return anything until a
  85.          line feed is entered.  Under Microsoft, function 'getc' returns
  86.          the next character entered immediately.
  87.  
  88.        There are two ways around this for the Unix user, but neither
  89.          comes without some pain --
  90.          1. Use curses, which provides a 'getch' single-character call.
  91.             The pain is that ALL file references to stdin, stdout and
  92.             stderr must be replaced -- and there is no reliable curses
  93.             equivalent to these.  You must go curses windows all the way
  94.             or not at all.
  95.          2. Consult the 'terminfo' information, and write a function
  96.             equivalent to Microsoft's 'getc' by configuring the tty
  97.             input port suitably.  This depends on whether you are using
  98.             bsd, system V or some other version of Unix.
  99.  
  100.      */
  101.  
  102. #include <stdio.h>
  103. #include <ctype.h>
  104. #include "decl.h"
  105.  
  106. #define VERSION "4.8"
  107.  
  108. int prompt_len= 0,
  109.     debug_level= 0,
  110.     trace_mode= 0;
  111.  
  112. /* .............. */
  113. static void registry()
  114. {
  115.   fprintf(stderr, "+++++++++++++++++++++++++++++++++++++++++++++++++\n");
  116.   fprintf(stderr, "UNREGISTERED -- please register with QCAD Systems\n");
  117.   fprintf(stderr, "  CALL or FAX 408 727-6884 for more information\n");
  118.   fprintf(stderr, "+++++++++++++++++++++++++++++++++++++++++++++++++\n");
  119.   }
  120.  
  121. /* ............ */
  122. static void give_help(progname)
  123.   char *progname;
  124. {
  125.   fprintf(stderr, "Version %s\n", VERSION);
  126.   registry();
  127.   fprintf(stderr, "Usage: %s [-s] [-dN] [infilename]\n", progname);
  128.   fprintf(stderr, "  -s: show source lines during parse\n");
  129.   fprintf(stderr, "  -dN: set interactive debug level N\n");
  130.   fprintf(stderr, "  -DN: trace with debug level N\n");
  131.   exit(1);
  132.   }
  133.  
  134. /* ............ */
  135. main(argc, argv)
  136.   int argc;
  137.   char *argv[];
  138. { char *infilename= NULL;
  139.   int argnum= 1, show_src= 0;
  140.  
  141.   while (argnum < argc) {
  142.     if (argv[argnum][0]=='-') {
  143.       int argpos= 1;
  144.       while (argv[argnum][argpos]) {
  145.         switch (argv[argnum][argpos]) {
  146.           case 's':
  147.             show_src= 1;
  148.             argpos++;
  149.             break;
  150.           case 'D':
  151.             trace_mode= 1;  /* then fall through */
  152.           case 'd':
  153.             argpos++;
  154.             if (sscanf(argv[argnum] + argpos, "%d", &debug_level)!=1)
  155.               debug_level= 2;
  156.             if (debug_level < 0) debug_level= 0;
  157.             while (isdigit(argv[argnum][argpos])) argpos++;
  158.             break;
  159.           default: give_help(argv[0]);
  160.           }
  161.         }
  162.       }
  163.     else if (infilename==NULL) infilename= argv[argnum];
  164.     else give_help(argv[0]);
  165.     argnum++;
  166.     }
  167.  
  168.   if (infilename==NULL) {
  169.     prompt_len= 2;
  170.     infilename= "stdin";
  171.     }
  172.  
  173.   errors = 0;
  174.   registry();
  175.   if (open_lex(infilename, show_src)) {
  176.     inittables();
  177.     parser();  /* does it all */
  178.     close_lex();
  179.     }
  180.   exit(0);
  181.   }
  182.  
  183.