mudgangster

Tiny, scriptable MUD client
Log | Files | Refs | README

lpprint.cc (5668B)


      1 /*
      2 ** $Id: lpprint.c,v 1.10 2016/09/13 16:06:03 roberto Exp $
      3 ** Copyright 2007, Lua.org & PUC-Rio  (see 'lpeg.html' for license)
      4 */
      5 
      6 #include <ctype.h>
      7 #include <limits.h>
      8 #include <stdio.h>
      9 
     10 
     11 #include "lptypes.h"
     12 #include "lpprint.h"
     13 #include "lpcode.h"
     14 
     15 
     16 #if defined(LPEG_DEBUG)
     17 
     18 /*
     19 ** {======================================================
     20 ** Printing patterns (for debugging)
     21 ** =======================================================
     22 */
     23 
     24 
     25 void printcharset (const byte *st) {
     26   int i;
     27   printf("[");
     28   for (i = 0; i <= UCHAR_MAX; i++) {
     29     int first = i;
     30     while (testchar(st, i) && i <= UCHAR_MAX) i++;
     31     if (i - 1 == first)  /* unary range? */
     32       printf("(%02x)", first);
     33     else if (i - 1 > first)  /* non-empty range? */
     34       printf("(%02x-%02x)", first, i - 1);
     35   }
     36   printf("]");
     37 }
     38 
     39 
     40 static const char *capkind (int kind) {
     41   const char *const modes[] = {
     42     "close", "position", "constant", "backref",
     43     "argument", "simple", "table", "function",
     44     "query", "string", "num", "substitution", "fold",
     45     "runtime", "group"};
     46   return modes[kind];
     47 }
     48 
     49 
     50 static void printjmp (const Instruction *op, const Instruction *p) {
     51   printf("-> %d", (int)(p + (p + 1)->offset - op));
     52 }
     53 
     54 
     55 void printinst (const Instruction *op, const Instruction *p) {
     56   const char *const names[] = {
     57     "any", "char", "set",
     58     "testany", "testchar", "testset",
     59     "span", "behind",
     60     "ret", "end",
     61     "choice", "jmp", "call", "open_call",
     62     "commit", "partial_commit", "back_commit", "failtwice", "fail", "giveup",
     63      "fullcapture", "opencapture", "closecapture", "closeruntime"
     64   };
     65   printf("%02ld: %s ", (long)(p - op), names[p->i.code]);
     66   switch ((Opcode)p->i.code) {
     67     case IChar: {
     68       printf("'%c'", p->i.aux);
     69       break;
     70     }
     71     case ITestChar: {
     72       printf("'%c'", p->i.aux); printjmp(op, p);
     73       break;
     74     }
     75     case IFullCapture: {
     76       printf("%s (size = %d)  (idx = %d)",
     77              capkind(getkind(p)), getoff(p), p->i.key);
     78       break;
     79     }
     80     case IOpenCapture: {
     81       printf("%s (idx = %d)", capkind(getkind(p)), p->i.key);
     82       break;
     83     }
     84     case ISet: {
     85       printcharset((p+1)->buff);
     86       break;
     87     }
     88     case ITestSet: {
     89       printcharset((p+2)->buff); printjmp(op, p);
     90       break;
     91     }
     92     case ISpan: {
     93       printcharset((p+1)->buff);
     94       break;
     95     }
     96     case IOpenCall: {
     97       printf("-> %d", (p + 1)->offset);
     98       break;
     99     }
    100     case IBehind: {
    101       printf("%d", p->i.aux);
    102       break;
    103     }
    104     case IJmp: case ICall: case ICommit: case IChoice:
    105     case IPartialCommit: case IBackCommit: case ITestAny: {
    106       printjmp(op, p);
    107       break;
    108     }
    109     default: break;
    110   }
    111   printf("\n");
    112 }
    113 
    114 
    115 void printpatt (Instruction *p, int n) {
    116   Instruction *op = p;
    117   while (p < op + n) {
    118     printinst(op, p);
    119     p += sizei(p);
    120   }
    121 }
    122 
    123 
    124 #if defined(LPEG_DEBUG)
    125 static void printcap (Capture *cap) {
    126   printf("%s (idx: %d - size: %d) -> %p\n",
    127          capkind(cap->kind), cap->idx, cap->siz, cap->s);
    128 }
    129 
    130 
    131 void printcaplist (Capture *cap, Capture *limit) {
    132   printf(">======\n");
    133   for (; cap->s && (limit == NULL || cap < limit); cap++)
    134     printcap(cap);
    135   printf("=======\n");
    136 }
    137 #endif
    138 
    139 /* }====================================================== */
    140 
    141 
    142 /*
    143 ** {======================================================
    144 ** Printing trees (for debugging)
    145 ** =======================================================
    146 */
    147 
    148 static const char *tagnames[] = {
    149   "char", "set", "any",
    150   "true", "false",
    151   "rep",
    152   "seq", "choice",
    153   "not", "and",
    154   "call", "opencall", "rule", "grammar",
    155   "behind",
    156   "capture", "run-time"
    157 };
    158 
    159 
    160 void printtree (TTree *tree, int ident) {
    161   int i;
    162   for (i = 0; i < ident; i++) printf(" ");
    163   printf("%s", tagnames[tree->tag]);
    164   switch (tree->tag) {
    165     case TChar: {
    166       int c = tree->u.n;
    167       if (isprint(c))
    168         printf(" '%c'\n", c);
    169       else
    170         printf(" (%02X)\n", c);
    171       break;
    172     }
    173     case TSet: {
    174       printcharset(treebuffer(tree));
    175       printf("\n");
    176       break;
    177     }
    178     case TOpenCall: case TCall: {
    179       assert(sib2(tree)->tag == TRule);
    180       printf(" key: %d  (rule: %d)\n", tree->key, sib2(tree)->cap);
    181       break;
    182     }
    183     case TBehind: {
    184       printf(" %d\n", tree->u.n);
    185         printtree(sib1(tree), ident + 2);
    186       break;
    187     }
    188     case TCapture: {
    189       printf(" kind: '%s'  key: %d\n", capkind(tree->cap), tree->key);
    190       printtree(sib1(tree), ident + 2);
    191       break;
    192     }
    193     case TRule: {
    194       printf(" n: %d  key: %d\n", tree->cap, tree->key);
    195       printtree(sib1(tree), ident + 2);
    196       break;  /* do not print next rule as a sibling */
    197     }
    198     case TGrammar: {
    199       TTree *rule = sib1(tree);
    200       printf(" %d\n", tree->u.n);  /* number of rules */
    201       for (i = 0; i < tree->u.n; i++) {
    202         printtree(rule, ident + 2);
    203         rule = sib2(rule);
    204       }
    205       assert(rule->tag == TTrue);  /* sentinel */
    206       break;
    207     }
    208     default: {
    209       int sibs = numsiblings[tree->tag];
    210       printf("\n");
    211       if (sibs >= 1) {
    212         printtree(sib1(tree), ident + 2);
    213         if (sibs >= 2)
    214           printtree(sib2(tree), ident + 2);
    215       }
    216       break;
    217     }
    218   }
    219 }
    220 
    221 
    222 void printktable (lua_State *L, int idx) {
    223   int n, i;
    224   lua_getuservalue(L, idx);
    225   if (lua_isnil(L, -1))  /* no ktable? */
    226     return;
    227   n = lua_rawlen(L, -1);
    228   printf("[");
    229   for (i = 1; i <= n; i++) {
    230     printf("%d = ", i);
    231     lua_rawgeti(L, -1, i);
    232     if (lua_isstring(L, -1))
    233       printf("%s  ", lua_tostring(L, -1));
    234     else
    235       printf("%s  ", lua_typename(L, lua_type(L, -1)));
    236     lua_pop(L, 1);
    237   }
    238   printf("]\n");
    239   /* leave ktable at the stack */
    240 }
    241 
    242 /* }====================================================== */
    243 
    244 #endif