home *** CD-ROM | disk | FTP | other *** search
/ The Education Master 1994 (4th Edition) / EDUCATIONS_MASTER_4TH_EDITION.bin / files / progmisc / qparser2 / cskels / debug.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-07  |  13.6 KB  |  576 lines

  1. /* debug.c
  2.  
  3.    QCAD Systems, Inc. 1990
  4.  
  5.    This contains debugging tools used to check semantic functions in
  6. a newly generated parser/translator.
  7.    The whole file is covered by the DEBUG ifdef -- you need to compile
  8. with -DDEBUG option.
  9.  
  10.      */
  11.  
  12. #if DEBUG == 1
  13.  
  14. #include <stdio.h>
  15. #include <ctype.h>
  16. #include "sets.h"
  17. #include "decl.h"
  18. #include "help.h"
  19.  
  20. char *prodtrap= NULL;  /* production trap set */
  21. #define PRODSETSIZE  SETSIZE(REDUCELEN+1)
  22. static struct prod_struct {
  23.   int  state;
  24.   char *prod;
  25.   } *productions;  /* sorted productions */
  26.  
  27. /* .............. */
  28. static int swrprod(rstate, str)
  29.   int rstate;
  30.   char *str;
  31.   /* write out the production for reduce state "rstate" to str. */
  32. { char *tstr= str;
  33.   int px= prodx[rstate];
  34.  
  35.   sprintf(str, "%s ->", tokstring[prods[px++]]);
  36.   str += strlen(str);
  37.   while (prods[px]) {
  38.     sprintf(str, " %s", tokstring[prods[px++]]);
  39.     str += strlen(str);
  40.     }
  41.   if (map[rstate]) {
  42.     sprintf(str, " #%s", flags[map[rstate]]);
  43.     str += strlen(str);
  44.     }
  45.   return str - tstr;
  46.   }
  47.  
  48. /* .............. */
  49. void wrprod(rstate)
  50.   int rstate;
  51.   /* write the production for reduce state "rstate" to stdout */
  52. { char pstring[256];
  53.  
  54.   swrprod(rstate, pstring);
  55.   printf("%s", pstring);
  56.   }
  57.  
  58. /* ................. */
  59. char *flag2string(flag)
  60.   int flag;
  61. {  /*produce the flag symbol as a string*/
  62.   if (flag<0 || flag>= FLAG_ARRAY_DIM) return "???";
  63.   else return flags[flag];
  64.   }
  65.  
  66. /* ............... */
  67. void print_flagged_rule(flag)
  68.   int flag;
  69. { int rstate;
  70.  
  71.   for (rstate= 1; rstate<= REDUCELEN; rstate++)
  72.     if (map[rstate]==flag) break;
  73.   if (rstate <= REDUCELEN)  /* is a known flag */
  74.     wrprod(rstate);
  75.   }
  76.  
  77. /* ............... */
  78. void dump_sem(indent, tsemp)
  79.   int indent;
  80.   semrectype *tsemp;
  81.   /* output a semantic stack record. */
  82. {
  83.   if (tsemp) {
  84.     printf("%*s%s: ", indent, "", flag2string(tsemp->semt));
  85.     switch (tsemp->semt) {
  86.       case IDENT:
  87.         if (tsemp->usem.symp)
  88.           printf("%s", tsemp->usem.symp->sym);
  89.         else printf("NULL");
  90.         break;
  91.       case FIXED:
  92.         printf("%ld", tsemp->usem.numval);
  93.         break;
  94.       case FLOAT:
  95.         printf("%lf", tsemp->usem.rval);
  96.         break;
  97.       case STRNG:
  98.         printf("'%s'", tsemp->usem.strx);
  99.         break;
  100.       case CHART:
  101.         printf("'%c'", (char) tsemp->usem.numval);
  102.         break;
  103.       /* display other cases here */
  104.       default: ;
  105.       }
  106.     }
  107.   else printf("%*sNULL", indent, "");
  108.   }
  109.  
  110. /* .................... */
  111. static void wr_stack(stack, sx, markx)
  112.   int *stack;
  113.   int sx, markx;
  114. {  /*write a preamble for index SX in the stack*/
  115.   int tl= 0, the_state;
  116.  
  117.   printf("%c%3d: ", (sx==markx ? '*' : ' '), sx);
  118.   tl += 5;
  119.   printf("%3d ", stack[sx]);
  120.   tl += 4;
  121.   the_state= stack[sx+1];
  122.   if (the_state)  {
  123.     printf("%s", tokstring[insym[the_state]]);
  124.     tl += strlen(tokstring[insym[the_state]]);
  125.     }
  126.   else {
  127.     printf("---");
  128.     tl += 3;
  129.     }
  130.   if (tl < 20)
  131.     printf("%*s", 20-tl, "");
  132.   else
  133.     printf(" ");
  134.   }
  135.  
  136. /* ................... */
  137. void stk_dump(kind, stack, stackx, debug_level)
  138.   char *kind;
  139.   int *stack;
  140.   int stackx, debug_level;
  141. { int sx, cstate= stack[stackx+1];
  142.  
  143.   if (abs(debug_level) > 1) {
  144.     printf("%s, state %d", kind, cstate);
  145.     if (token>0 && cstate>= READSTATE)  {
  146.       if (token==IDENT_TOKX)
  147.         printf("   on id %s", lsemp->usem.symp->sym);
  148.       else printf(", on token %s", tokstring[token]);
  149.       }
  150.     printf("\n");
  151.  
  152.     if (stackx>10)  {
  153.       printf("  ###\n");
  154.       sx = stackx-9;
  155.       }
  156.     else sx = 1;
  157.     while (sx<=stackx)  {
  158.       wr_stack(stack, sx, -1);
  159.       if (*kind != '*') dump_sem(0, semstack[sx]);
  160.       printf("\n");
  161.       sx++;
  162.       }
  163.     }
  164.   if (cstate < READSTATE) {
  165.     wrprod(cstate);
  166.     printf("\n");
  167.     }
  168.   if (!trace_mode) idebug();
  169.   }
  170.  
  171. /* ................ */
  172. static void wrindent(vx)
  173.   int vx;
  174. {
  175.   printf("%2d> ", vx);
  176.   }
  177.  
  178. /* ................ */
  179. static void inspect_sym(indent, tsymp)
  180.   int indent;
  181.   symtabtype *tsymp;
  182. { int more= 1;
  183.  
  184.   if (tsymp==NULL)  {
  185.     wrindent(indent);
  186.     printf("\nNIL");
  187.     }
  188.   else while (more) {
  189.     wrindent(indent);
  190.     printf("SYM: ");
  191.     dump_sym(tsymp);  /*some basic information*/
  192.     while (more) {
  193.       wrindent(indent);
  194.       switch (resp(" U(p")) {
  195.         case '?': help("inspect_sym"); break;
  196.         case 'u': case 'U': case '\n':
  197.           more= 0; break;
  198.         default:  ;
  199.         }
  200.       }
  201.     }
  202.   }
  203.  
  204. /* ................ */
  205. static void show_sym(indent)
  206.   /* prompts for a symbol, then calls the symbol inspector on it */
  207.   int indent;
  208. { char str[80];
  209.   int  len;
  210.  
  211.   printf("What symbol (case-sensitive!) ? ");
  212.   fflush(stdout);
  213.   readline(str, 79);
  214.   if (*str=='\0') return;
  215.   inspect_sym(indent, findsym(str));
  216.   printf("\n");
  217.   }
  218.  
  219. /* .............. */
  220. void inspect_sem(indent, place)
  221.   int indent;
  222.   semrectype *place;
  223. {  /*an interactive SEMREC inspector */
  224.  
  225.   if (place==NULL)  {
  226.     wrindent(indent);
  227.     printf("\nNIL");
  228.     }
  229.   else {
  230.     /* this builds a compound 'prompt' based on what the semantics
  231.         environment is */
  232.     char pmark[160], *pp, ch;
  233.     int more= 1;
  234.  
  235. #define IPROMPT "[inspect_sem] ?(help, N(ame, A(ll names, T(ree, U(p"
  236.  
  237.     while (more) {
  238.       int inx;
  239.  
  240.       strcpy(pmark, IPROMPT);
  241.       pp= pmark + strlen(IPROMPT);
  242.       dump_sem(0, place);   /*shows some basic features*/
  243.       printf("\n");
  244.       if (place->semt == IDENT) {
  245.         strcpy(pp, ", S(ymp");
  246.         pp += strlen(pp);
  247.         }
  248.       else if (place->semt >= GENL_KIND) {
  249.         for (inx= 0; inx< MAXNRPLEN; inx++)
  250.         if (place->usem.position0[inx]) {
  251.           sprintf(pp, ", %d(", inx+1);
  252.           pp += strlen(pp);
  253.           }
  254.         }
  255.       wrindent(indent);
  256.       ch= resp(pmark);
  257.       if (islower(ch)) ch= toupper(ch);
  258.       if (ch >= '1' &&
  259.           ch < '1' + MAXNRPLEN &&
  260.           place->usem.position0[ch-'1'])
  261.         inspect_sem(indent+1, place->usem.position0[ch - '1']);
  262.       else switch (ch) {
  263.         case 'N':
  264.           show_sym(indent+1);
  265.           break;
  266.         case 'A':
  267.           dump_all();
  268.           break;
  269.         case 'T':
  270.           print_tree(place);
  271.           printf("\n");
  272.           break;
  273.         case '?':
  274.           help("inspect_sem");
  275.           break;
  276.         case 'U':
  277.         case '\n':
  278.           more= 0;
  279.           break;
  280.         case 'S':
  281.           if (place->semt==IDENT) inspect_sym(indent+1, place->usem.symp);
  282.           break;
  283.         default:  break;
  284.         }
  285.       }
  286.     }
  287.   }
  288.  
  289. /* .............. */
  290. void inspect_stack(stack, stackx, kind)
  291.   int *stack, stackx;
  292.   char kind;   /* if (kind=='*') ignore semantics */
  293. {  /*an interactive stack inspector */
  294.  
  295.   if (stackx < 0)
  296.     printf("\nNIL");
  297.   else {
  298.     char prompt[160],
  299.          pmark[80], *pp, ch;
  300.     int more= 1;
  301.     int stkx= stackx, inx;
  302.  
  303.     sprintf(prompt,
  304.               "[inspect_stack] ?(help, N(ame, A(ll names, \n\
  305.    %s+(tos, -(tos, ENTER? ",
  306.                     (kind=='*' ? "" : "I(nspect, T(ree, "));
  307.     while (more) {
  308.       int sx= (stackx >= 10 ? stackx-9 : 1);
  309.  
  310.       while (sx <= stackx) {
  311.         wr_stack(stack, sx, stkx);   /* preamble */
  312.         if (kind != '*') dump_sem(0, semstack[sx]);
  313.         printf("\n");
  314.         sx++;
  315.         }
  316.       ch= resp(prompt);
  317.       if (islower(ch)) ch= toupper(ch);
  318.       switch (ch) {
  319.         case '+':
  320.           stkx++;  /*toward top of stack*/
  321.           if (stkx > stackx)  stkx= stackx;
  322.           break;
  323.         case '-':
  324.           stkx--;  /*away from top of stack*/
  325.           if (stkx < 1)  stkx= 1;
  326.           break;
  327.         case 'N':
  328.           show_sym(0);
  329.           break;
  330.         case 'A':
  331.           dump_all();
  332.           break;
  333.         case 'I':
  334.           if (kind!='*')
  335.             inspect_sem(0, semstack[stkx]);
  336.           break;
  337.         case 'T':
  338.           if (kind!='*') {
  339.             print_tree(semstack[stkx]);
  340.             printf("\n");
  341.             }
  342.           break;
  343.         case '?':
  344.           help("inspect_stack");
  345.           break;
  346.         case '\n':
  347.           more= 0;
  348.           break;
  349.         default:  continue;
  350.         }
  351.       }
  352.     }
  353.   }
  354.  
  355. /* .............. */
  356. static int stringsort(p1, p2)
  357.   struct prod_struct *p1, *p2;
  358. {
  359.   return strcmp(p1->prod, p2->prod);
  360.   }
  361.  
  362. /* .............. */
  363. static void show_productions(pinx)
  364.   int *pinx;
  365. { int count= SHOWLINES;
  366.  
  367.   if (*pinx < 1) *pinx= 1;
  368.   while (count--) {
  369.     int pstate;
  370.  
  371.     if (*pinx > REDUCELEN) *pinx= 1;
  372.     pstate= productions[*pinx].state;
  373.     printf("%3d: %c ", *pinx,
  374.            (set_member(pstate, prodtrap) ? '*' : ' '));
  375.     printf("%s\n", productions[*pinx].prod);
  376.     (*pinx)++;
  377.     }
  378.   }
  379.  
  380. /* ............ */
  381. static void select_some(mp)
  382.   char *mp;
  383. { int value;
  384.  
  385.   while (*mp) {
  386.     value= 0;
  387.     while (*mp==' ') mp++;
  388.     if (isdigit(*mp)) {
  389.       while (isdigit(*mp)) value = 10*value + *(mp++) - '0';
  390.       if (value > 0 && value <= REDUCELEN) {
  391.         int state= productions[value].state;
  392.  
  393.         if (set_member(state, prodtrap))
  394.           set_exclude(state, prodtrap);
  395.         else set_include(state, prodtrap);
  396.         }
  397.       }
  398.     else mp++;  /* ignore anything else */
  399.     }
  400.   }
  401.  
  402. /* .............. */
  403. static void set_prodtraps()
  404. { char rch, msg[80], *mp;
  405.   int value, prodno= 1;
  406.  
  407.   if (prodtrap==NULL) {
  408.     int px;
  409.  
  410.     prodtrap= (char *) malloc(PRODSETSIZE);
  411.     productions= (struct prod_struct *) malloc((REDUCELEN+1) *
  412.                                             sizeof(*productions));
  413.     clearset(prodtrap, PRODSETSIZE);
  414.     productions[0].prod= "";
  415.     productions[0].state= 0;
  416.     for (px= 1; px<= REDUCELEN; px++) {
  417.       char tstring[256];
  418.       int tlen;
  419.  
  420.       tlen= swrprod(px, tstring);
  421.       productions[px].state= px;
  422.       productions[px].prod= (char *) malloc(tlen+1);
  423.       strcpy(productions[px].prod, tstring);
  424.       }
  425.     qsort((char *) (productions+1), REDUCELEN, sizeof(*productions),
  426.           stringsort);
  427.     }
  428.  
  429.   while (1) {
  430.     show_productions(&prodno);
  431.     printf("[set_prodtraps] ?(help, C(lear all, S(elect all,\n");
  432.     rch= resp("  #( <number>, SPACE, ENTER ");
  433.     if (islower(rch)) rch= toupper(rch);
  434.     switch (rch) {
  435.       case '?':
  436.         help("set_prodtraps");
  437.         prodno -= SHOWLINES;
  438.         break;
  439.       case 'C':
  440.         clearset(prodtrap, PRODSETSIZE);
  441.         prodno -= SHOWLINES;
  442.         break;
  443.       case 'S':
  444.         fillset(prodtrap, PRODSETSIZE);
  445.         prodno -= SHOWLINES;
  446.         break;
  447.       case '#':
  448.         printf("> ");
  449.         fflush(stdout);
  450.         fgets(msg, 79, stdin);
  451.         select_some(msg);
  452.         break;
  453.       case '\n': return;
  454.       }
  455.     }
  456.   }
  457.  
  458. /*................*/
  459. static void set_debug()
  460.   /* prompts for a debug level number */
  461. { char rch= resp("Set debug level to (0, 1, ...)? ");
  462.  
  463.   if (isdigit(rch)) debug_level= rch - '0';
  464.   }
  465.  
  466. #if QTREES == 1
  467.  
  468. /* ............... */
  469. static void upshift(string)
  470.   char *string;
  471. {
  472.   while (*string) {
  473.     if (islower(*string)) *string= toupper(*string);
  474.     string++;
  475.     }
  476.   }
  477.  
  478. /* ............... */
  479. static void set_ntraps(line)
  480.   char *line;
  481. { char choice[80], *cp, *lp;
  482.   int node;
  483.  
  484.   lp= line;
  485.   while (1) {
  486.     if (*lp < ' ') break;  /* \n, \0, etc. */
  487.     while (*lp==' ') lp++;
  488.     cp= choice;
  489.     while (*lp > ' ') *(cp++)= *(lp++);
  490.     *cp= '\0';
  491.     upshift(choice);
  492.     for (node= FIRST_SEMTYPE; node <= LAST_SEMTYPE; node++)
  493.     if (strcmp(choice, flags[node])==0) {
  494.       if (set_member(node, trace_nodes))
  495.         set_exclude(node, trace_nodes);
  496.       else set_include(node, trace_nodes);
  497.       break;  /* out of for loop */
  498.       }
  499.     }
  500.   }
  501.  
  502. /* ............... */
  503. static void display_nodes(node)
  504.   int *node;
  505. { int lines= SHOWLINES;
  506.  
  507.   while (lines--) {
  508.     if (*node > LAST_SEMTYPE) *node= FIRST_SEMTYPE;
  509.     if (set_member(*node, trace_nodes)) printf("* ");
  510.     else printf("  ");
  511.     printf("%s\n", flags[*node]);
  512.     (*node)++;
  513.     }
  514.   }
  515.  
  516. /* ................... */
  517. static void set_nodetraps()
  518. { int nextnode= FIRST_SEMTYPE, node, more= 1;
  519.   char rch;
  520.   char line[80];
  521.  
  522.   while (more) {
  523.     display_nodes(&nextnode);
  524.     printf("[set_nodetraps] ?(help, S(elect all, C(lear all,\n");
  525.     rch= resp("  #( <tag>, SPACE, ENTER? ");
  526.     if (islower(rch)) rch= toupper(rch);
  527.     switch (rch) {
  528.       case 'S': fillset(trace_nodes, TSETSIZE); break;
  529.       case 'C': clearset(trace_nodes, TSETSIZE); break;
  530.       case '#':
  531.         printf("> ");
  532.         fflush(stdout);
  533.         fgets(line, 79, stdin);  /* get the rest of the input */
  534.         set_ntraps(line);
  535.         break;
  536.       case '\n': return;
  537.       case '?': help("set_nodetraps"); break;
  538.       default: ;
  539.       }
  540.     }
  541.   }
  542. #else
  543.  
  544. static void set_nodetraps()
  545. {
  546.   printf("Trace mode not enabled -- you aren't using QTREES\n");
  547.   }
  548. #endif
  549.  
  550. /* .............. */
  551. void idebug()
  552.   /* interactive debugging support on existing stack, symbol table */
  553. { int more= 1;
  554.   char rch;
  555.  
  556.   while (more)  {
  557.     printf("\n[idebug] ?(help, N(ame, A(ll, D(bug level,\n");
  558.     rch= resp("   P(rodTrap, T(race, L(ex, S(tack, ENTER? ");
  559.     if (islower(rch)) rch= toupper(rch);
  560.     switch (rch) {
  561.       case 'D':  set_debug(); break;
  562.       case 'P':  set_prodtraps(); break;
  563.       case 'T':  set_nodetraps(); break;
  564.       case 'L':  show_lex(); break;
  565.       case 'S':  inspect_stack(stack, stackx, ' '); break;
  566.       case 'N':  show_sym(0); break;
  567.       case 'A':  dump_all(); break;
  568.       case '\n': more= 0; break;
  569.       case '?':  help("idebug"); break;
  570.       default:  ;
  571.       }
  572.     }
  573.   }
  574.  
  575. #endif
  576.