home *** CD-ROM | disk | FTP | other *** search
- /* debug.c
-
- QCAD Systems, Inc. 1990
-
- This contains debugging tools used to check semantic functions in
- a newly generated parser/translator.
- The whole file is covered by the DEBUG ifdef -- you need to compile
- with -DDEBUG option.
-
- */
-
- #if DEBUG == 1
-
- #include <stdio.h>
- #include <ctype.h>
- #include "sets.h"
- #include "decl.h"
- #include "help.h"
-
- char *prodtrap= NULL; /* production trap set */
- #define PRODSETSIZE SETSIZE(REDUCELEN+1)
- static struct prod_struct {
- int state;
- char *prod;
- } *productions; /* sorted productions */
-
- /* .............. */
- static int swrprod(rstate, str)
- int rstate;
- char *str;
- /* write out the production for reduce state "rstate" to str. */
- { char *tstr= str;
- int px= prodx[rstate];
-
- sprintf(str, "%s ->", tokstring[prods[px++]]);
- str += strlen(str);
- while (prods[px]) {
- sprintf(str, " %s", tokstring[prods[px++]]);
- str += strlen(str);
- }
- if (map[rstate]) {
- sprintf(str, " #%s", flags[map[rstate]]);
- str += strlen(str);
- }
- return str - tstr;
- }
-
- /* .............. */
- void wrprod(rstate)
- int rstate;
- /* write the production for reduce state "rstate" to stdout */
- { char pstring[256];
-
- swrprod(rstate, pstring);
- printf("%s", pstring);
- }
-
- /* ................. */
- char *flag2string(flag)
- int flag;
- { /*produce the flag symbol as a string*/
- if (flag<0 || flag>= FLAG_ARRAY_DIM) return "???";
- else return flags[flag];
- }
-
- /* ............... */
- void print_flagged_rule(flag)
- int flag;
- { int rstate;
-
- for (rstate= 1; rstate<= REDUCELEN; rstate++)
- if (map[rstate]==flag) break;
- if (rstate <= REDUCELEN) /* is a known flag */
- wrprod(rstate);
- }
-
- /* ............... */
- void dump_sem(indent, tsemp)
- int indent;
- semrectype *tsemp;
- /* output a semantic stack record. */
- {
- if (tsemp) {
- printf("%*s%s: ", indent, "", flag2string(tsemp->semt));
- switch (tsemp->semt) {
- case IDENT:
- if (tsemp->usem.symp)
- printf("%s", tsemp->usem.symp->sym);
- else printf("NULL");
- break;
- case FIXED:
- printf("%ld", tsemp->usem.numval);
- break;
- case FLOAT:
- printf("%lf", tsemp->usem.rval);
- break;
- case STRNG:
- printf("'%s'", tsemp->usem.strx);
- break;
- case CHART:
- printf("'%c'", (char) tsemp->usem.numval);
- break;
- /* display other cases here */
- default: ;
- }
- }
- else printf("%*sNULL", indent, "");
- }
-
- /* .................... */
- static void wr_stack(stack, sx, markx)
- int *stack;
- int sx, markx;
- { /*write a preamble for index SX in the stack*/
- int tl= 0, the_state;
-
- printf("%c%3d: ", (sx==markx ? '*' : ' '), sx);
- tl += 5;
- printf("%3d ", stack[sx]);
- tl += 4;
- the_state= stack[sx+1];
- if (the_state) {
- printf("%s", tokstring[insym[the_state]]);
- tl += strlen(tokstring[insym[the_state]]);
- }
- else {
- printf("---");
- tl += 3;
- }
- if (tl < 20)
- printf("%*s", 20-tl, "");
- else
- printf(" ");
- }
-
- /* ................... */
- void stk_dump(kind, stack, stackx, debug_level)
- char *kind;
- int *stack;
- int stackx, debug_level;
- { int sx, cstate= stack[stackx+1];
-
- if (abs(debug_level) > 1) {
- printf("%s, state %d", kind, cstate);
- if (token>0 && cstate>= READSTATE) {
- if (token==IDENT_TOKX)
- printf(" on id %s", lsemp->usem.symp->sym);
- else printf(", on token %s", tokstring[token]);
- }
- printf("\n");
-
- if (stackx>10) {
- printf(" ###\n");
- sx = stackx-9;
- }
- else sx = 1;
- while (sx<=stackx) {
- wr_stack(stack, sx, -1);
- if (*kind != '*') dump_sem(0, semstack[sx]);
- printf("\n");
- sx++;
- }
- }
- if (cstate < READSTATE) {
- wrprod(cstate);
- printf("\n");
- }
- if (!trace_mode) idebug();
- }
-
- /* ................ */
- static void wrindent(vx)
- int vx;
- {
- printf("%2d> ", vx);
- }
-
- /* ................ */
- static void inspect_sym(indent, tsymp)
- int indent;
- symtabtype *tsymp;
- { int more= 1;
-
- if (tsymp==NULL) {
- wrindent(indent);
- printf("\nNIL");
- }
- else while (more) {
- wrindent(indent);
- printf("SYM: ");
- dump_sym(tsymp); /*some basic information*/
- while (more) {
- wrindent(indent);
- switch (resp(" U(p")) {
- case '?': help("inspect_sym"); break;
- case 'u': case 'U': case '\n':
- more= 0; break;
- default: ;
- }
- }
- }
- }
-
- /* ................ */
- static void show_sym(indent)
- /* prompts for a symbol, then calls the symbol inspector on it */
- int indent;
- { char str[80];
- int len;
-
- printf("What symbol (case-sensitive!) ? ");
- fflush(stdout);
- readline(str, 79);
- if (*str=='\0') return;
- inspect_sym(indent, findsym(str));
- printf("\n");
- }
-
- /* .............. */
- void inspect_sem(indent, place)
- int indent;
- semrectype *place;
- { /*an interactive SEMREC inspector */
-
- if (place==NULL) {
- wrindent(indent);
- printf("\nNIL");
- }
- else {
- /* this builds a compound 'prompt' based on what the semantics
- environment is */
- char pmark[160], *pp, ch;
- int more= 1;
-
- #define IPROMPT "[inspect_sem] ?(help, N(ame, A(ll names, T(ree, U(p"
-
- while (more) {
- int inx;
-
- strcpy(pmark, IPROMPT);
- pp= pmark + strlen(IPROMPT);
- dump_sem(0, place); /*shows some basic features*/
- printf("\n");
- if (place->semt == IDENT) {
- strcpy(pp, ", S(ymp");
- pp += strlen(pp);
- }
- else if (place->semt >= GENL_KIND) {
- for (inx= 0; inx< MAXNRPLEN; inx++)
- if (place->usem.position0[inx]) {
- sprintf(pp, ", %d(", inx+1);
- pp += strlen(pp);
- }
- }
- wrindent(indent);
- ch= resp(pmark);
- if (islower(ch)) ch= toupper(ch);
- if (ch >= '1' &&
- ch < '1' + MAXNRPLEN &&
- place->usem.position0[ch-'1'])
- inspect_sem(indent+1, place->usem.position0[ch - '1']);
- else switch (ch) {
- case 'N':
- show_sym(indent+1);
- break;
- case 'A':
- dump_all();
- break;
- case 'T':
- print_tree(place);
- printf("\n");
- break;
- case '?':
- help("inspect_sem");
- break;
- case 'U':
- case '\n':
- more= 0;
- break;
- case 'S':
- if (place->semt==IDENT) inspect_sym(indent+1, place->usem.symp);
- break;
- default: break;
- }
- }
- }
- }
-
- /* .............. */
- void inspect_stack(stack, stackx, kind)
- int *stack, stackx;
- char kind; /* if (kind=='*') ignore semantics */
- { /*an interactive stack inspector */
-
- if (stackx < 0)
- printf("\nNIL");
- else {
- char prompt[160],
- pmark[80], *pp, ch;
- int more= 1;
- int stkx= stackx, inx;
-
- sprintf(prompt,
- "[inspect_stack] ?(help, N(ame, A(ll names, \n\
- %s+(tos, -(tos, ENTER? ",
- (kind=='*' ? "" : "I(nspect, T(ree, "));
- while (more) {
- int sx= (stackx >= 10 ? stackx-9 : 1);
-
- while (sx <= stackx) {
- wr_stack(stack, sx, stkx); /* preamble */
- if (kind != '*') dump_sem(0, semstack[sx]);
- printf("\n");
- sx++;
- }
- ch= resp(prompt);
- if (islower(ch)) ch= toupper(ch);
- switch (ch) {
- case '+':
- stkx++; /*toward top of stack*/
- if (stkx > stackx) stkx= stackx;
- break;
- case '-':
- stkx--; /*away from top of stack*/
- if (stkx < 1) stkx= 1;
- break;
- case 'N':
- show_sym(0);
- break;
- case 'A':
- dump_all();
- break;
- case 'I':
- if (kind!='*')
- inspect_sem(0, semstack[stkx]);
- break;
- case 'T':
- if (kind!='*') {
- print_tree(semstack[stkx]);
- printf("\n");
- }
- break;
- case '?':
- help("inspect_stack");
- break;
- case '\n':
- more= 0;
- break;
- default: continue;
- }
- }
- }
- }
-
- /* .............. */
- static int stringsort(p1, p2)
- struct prod_struct *p1, *p2;
- {
- return strcmp(p1->prod, p2->prod);
- }
-
- /* .............. */
- static void show_productions(pinx)
- int *pinx;
- { int count= SHOWLINES;
-
- if (*pinx < 1) *pinx= 1;
- while (count--) {
- int pstate;
-
- if (*pinx > REDUCELEN) *pinx= 1;
- pstate= productions[*pinx].state;
- printf("%3d: %c ", *pinx,
- (set_member(pstate, prodtrap) ? '*' : ' '));
- printf("%s\n", productions[*pinx].prod);
- (*pinx)++;
- }
- }
-
- /* ............ */
- static void select_some(mp)
- char *mp;
- { int value;
-
- while (*mp) {
- value= 0;
- while (*mp==' ') mp++;
- if (isdigit(*mp)) {
- while (isdigit(*mp)) value = 10*value + *(mp++) - '0';
- if (value > 0 && value <= REDUCELEN) {
- int state= productions[value].state;
-
- if (set_member(state, prodtrap))
- set_exclude(state, prodtrap);
- else set_include(state, prodtrap);
- }
- }
- else mp++; /* ignore anything else */
- }
- }
-
- /* .............. */
- static void set_prodtraps()
- { char rch, msg[80], *mp;
- int value, prodno= 1;
-
- if (prodtrap==NULL) {
- int px;
-
- prodtrap= (char *) malloc(PRODSETSIZE);
- productions= (struct prod_struct *) malloc((REDUCELEN+1) *
- sizeof(*productions));
- clearset(prodtrap, PRODSETSIZE);
- productions[0].prod= "";
- productions[0].state= 0;
- for (px= 1; px<= REDUCELEN; px++) {
- char tstring[256];
- int tlen;
-
- tlen= swrprod(px, tstring);
- productions[px].state= px;
- productions[px].prod= (char *) malloc(tlen+1);
- strcpy(productions[px].prod, tstring);
- }
- qsort((char *) (productions+1), REDUCELEN, sizeof(*productions),
- stringsort);
- }
-
- while (1) {
- show_productions(&prodno);
- printf("[set_prodtraps] ?(help, C(lear all, S(elect all,\n");
- rch= resp(" #( <number>, SPACE, ENTER ");
- if (islower(rch)) rch= toupper(rch);
- switch (rch) {
- case '?':
- help("set_prodtraps");
- prodno -= SHOWLINES;
- break;
- case 'C':
- clearset(prodtrap, PRODSETSIZE);
- prodno -= SHOWLINES;
- break;
- case 'S':
- fillset(prodtrap, PRODSETSIZE);
- prodno -= SHOWLINES;
- break;
- case '#':
- printf("> ");
- fflush(stdout);
- fgets(msg, 79, stdin);
- select_some(msg);
- break;
- case '\n': return;
- }
- }
- }
-
- /*................*/
- static void set_debug()
- /* prompts for a debug level number */
- { char rch= resp("Set debug level to (0, 1, ...)? ");
-
- if (isdigit(rch)) debug_level= rch - '0';
- }
-
- #if QTREES == 1
-
- /* ............... */
- static void upshift(string)
- char *string;
- {
- while (*string) {
- if (islower(*string)) *string= toupper(*string);
- string++;
- }
- }
-
- /* ............... */
- static void set_ntraps(line)
- char *line;
- { char choice[80], *cp, *lp;
- int node;
-
- lp= line;
- while (1) {
- if (*lp < ' ') break; /* \n, \0, etc. */
- while (*lp==' ') lp++;
- cp= choice;
- while (*lp > ' ') *(cp++)= *(lp++);
- *cp= '\0';
- upshift(choice);
- for (node= FIRST_SEMTYPE; node <= LAST_SEMTYPE; node++)
- if (strcmp(choice, flags[node])==0) {
- if (set_member(node, trace_nodes))
- set_exclude(node, trace_nodes);
- else set_include(node, trace_nodes);
- break; /* out of for loop */
- }
- }
- }
-
- /* ............... */
- static void display_nodes(node)
- int *node;
- { int lines= SHOWLINES;
-
- while (lines--) {
- if (*node > LAST_SEMTYPE) *node= FIRST_SEMTYPE;
- if (set_member(*node, trace_nodes)) printf("* ");
- else printf(" ");
- printf("%s\n", flags[*node]);
- (*node)++;
- }
- }
-
- /* ................... */
- static void set_nodetraps()
- { int nextnode= FIRST_SEMTYPE, node, more= 1;
- char rch;
- char line[80];
-
- while (more) {
- display_nodes(&nextnode);
- printf("[set_nodetraps] ?(help, S(elect all, C(lear all,\n");
- rch= resp(" #( <tag>, SPACE, ENTER? ");
- if (islower(rch)) rch= toupper(rch);
- switch (rch) {
- case 'S': fillset(trace_nodes, TSETSIZE); break;
- case 'C': clearset(trace_nodes, TSETSIZE); break;
- case '#':
- printf("> ");
- fflush(stdout);
- fgets(line, 79, stdin); /* get the rest of the input */
- set_ntraps(line);
- break;
- case '\n': return;
- case '?': help("set_nodetraps"); break;
- default: ;
- }
- }
- }
- #else
-
- static void set_nodetraps()
- {
- printf("Trace mode not enabled -- you aren't using QTREES\n");
- }
- #endif
-
- /* .............. */
- void idebug()
- /* interactive debugging support on existing stack, symbol table */
- { int more= 1;
- char rch;
-
- while (more) {
- printf("\n[idebug] ?(help, N(ame, A(ll, D(bug level,\n");
- rch= resp(" P(rodTrap, T(race, L(ex, S(tack, ENTER? ");
- if (islower(rch)) rch= toupper(rch);
- switch (rch) {
- case 'D': set_debug(); break;
- case 'P': set_prodtraps(); break;
- case 'T': set_nodetraps(); break;
- case 'L': show_lex(); break;
- case 'S': inspect_stack(stack, stackx, ' '); break;
- case 'N': show_sym(0); break;
- case 'A': dump_all(); break;
- case '\n': more= 0; break;
- case '?': help("idebug"); break;
- default: ;
- }
- }
- }
-
- #endif