home *** CD-ROM | disk | FTP | other *** search
- /* main.c
-
- QCAD Systems, Inc. 1990
-
- 'main' program for parser construction
-
- This is the 'main' section for an LALR(1) table-driven parser for
- use with QPARSER.
-
- FILE REDIRECTION
-
- DOS and the Unix shells permit redirecting stdin and stdout to/from
- a file. Determining whether I/O comes from a file or the keyboard/screen
- from within the program is not easy. We recommend NOT using redirection
- when debugging interactively. You can specify a file name
- containing source material as a command-line option without interfering
- with keyboard/screen I/O; for example:
-
- main -d2 t1.cal
-
- provides full interactivity with text drawn from file 't1.cal'.
-
- DEBUGGING TOOLS:
-
- 1. Compile all files with /DDEBUG (or -DDEBUG in Unix) compiler options:
- This generates debugging tables and code.
- 2. You can insert the character '!' in the source file at a position
- at which debugging is desired. The parser will stop and bring up
- an interactive menu when that token is scanned.
- 3. You can call the compiled program with any of the following options:
-
- -dN: starts debugging, setting debug level to N
- -s: copy source lines to stdout when read by lex. This is
- useful when a source file name is specified in the
- command line
-
- INTERACTIVE MENU:
-
- From the interactive debugging menu, you can:
-
- 1. Set any number of 'production traps'.
- When a production trap is set, the parser will stop just before
- that production is reduced.
- 2. Choose to see only the production before reduction (level 1),
- the stack and the production (level 2), all parser actions (level 3),
- or all parser actions and error recovery actions (level 4).
- 3. Display the current lexical token and line position.
- 4. Inspect a tree built by the qtrees option by walking down through
- and examining nodes in detail.
- 5. Send a screen dump to file 'screen.txt'. (This only works for
- DOS and 24 x 80 text screens, color or mono).
-
- All these capabilities are written into the skeleton files -- see
- skeldbug for details. You will want to augment these functions
- as your semantic actions grow in complexity.
-
- IMPLEMENTATION NOTES
-
- You will need the \QPARSER\LIB directory compiled for certain
- modules. Make sure its memory model and compiler agree with
- those in your work directory.
-
- Where it seems to matter, use one of the compiler directives
- indicated below.
-
- MicroSoft (-DMSDOS supplied by default)
- Turbo C++ -DTCC
- Unix system V -DUNIX
-
- You can generate source code on an AT and copy it to a Unix or
- other system. Use the -DUNIX option to deal with a few differences
- between System V Unix and MSDOS compilers.
-
- Depending on which C compiler you are using, you may have to
- manually make adjustments for these conditions:
-
- - Some compilers buffer output to the screen when the screen is
- accessed through a file and fprintf calls (as opposed to printf).
- - The "fgets" function does not return an EOF condition in some
- C implementations, so an end state may be necessary in your
- grammar (as in the token "quit" in the CALC grammar).
- - The "resp" function behaves differently in a Unix environment
- than a PC environment. The root of the problem is that in Unix,
- the standard function "getchar" doesn't return anything until a
- line feed is entered. Under Microsoft, function 'getc' returns
- the next character entered immediately.
-
- There are two ways around this for the Unix user, but neither
- comes without some pain --
- 1. Use curses, which provides a 'getch' single-character call.
- The pain is that ALL file references to stdin, stdout and
- stderr must be replaced -- and there is no reliable curses
- equivalent to these. You must go curses windows all the way
- or not at all.
- 2. Consult the 'terminfo' information, and write a function
- equivalent to Microsoft's 'getc' by configuring the tty
- input port suitably. This depends on whether you are using
- bsd, system V or some other version of Unix.
-
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include "decl.h"
-
- #define VERSION "4.8"
-
- int prompt_len= 0,
- debug_level= 0,
- trace_mode= 0;
-
- /* .............. */
- static void registry()
- {
- fprintf(stderr, "+++++++++++++++++++++++++++++++++++++++++++++++++\n");
- fprintf(stderr, "UNREGISTERED -- please register with QCAD Systems\n");
- fprintf(stderr, " CALL or FAX 408 727-6884 for more information\n");
- fprintf(stderr, "+++++++++++++++++++++++++++++++++++++++++++++++++\n");
- }
-
- /* ............ */
- static void give_help(progname)
- char *progname;
- {
- fprintf(stderr, "Version %s\n", VERSION);
- registry();
- fprintf(stderr, "Usage: %s [-s] [-dN] [infilename]\n", progname);
- fprintf(stderr, " -s: show source lines during parse\n");
- fprintf(stderr, " -dN: set interactive debug level N\n");
- fprintf(stderr, " -DN: trace with debug level N\n");
- exit(1);
- }
-
- /* ............ */
- main(argc, argv)
- int argc;
- char *argv[];
- { char *infilename= NULL;
- int argnum= 1, show_src= 0;
-
- while (argnum < argc) {
- if (argv[argnum][0]=='-') {
- int argpos= 1;
- while (argv[argnum][argpos]) {
- switch (argv[argnum][argpos]) {
- case 's':
- show_src= 1;
- argpos++;
- break;
- case 'D':
- trace_mode= 1; /* then fall through */
- case 'd':
- argpos++;
- if (sscanf(argv[argnum] + argpos, "%d", &debug_level)!=1)
- debug_level= 2;
- if (debug_level < 0) debug_level= 0;
- while (isdigit(argv[argnum][argpos])) argpos++;
- break;
- default: give_help(argv[0]);
- }
- }
- }
- else if (infilename==NULL) infilename= argv[argnum];
- else give_help(argv[0]);
- argnum++;
- }
-
- if (infilename==NULL) {
- prompt_len= 2;
- infilename= "stdin";
- }
-
- errors = 0;
- registry();
- if (open_lex(infilename, show_src)) {
- inittables();
- parser(); /* does it all */
- close_lex();
- }
- exit(0);
- }
-