lpprint.c 7.0 KB

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