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