123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- #include <ctype.h>
- #include <limits.h>
- #include <stdio.h>
- #include "lptypes.h"
- #include "lpprint.h"
- #include "lpcode.h"
- #if defined(LPEG_DEBUG)
- /*
- ** {======================================================
- ** Printing patterns (for debugging)
- ** =======================================================
- */
- void printcharset (const byte *st) {
- int i;
- printf("[");
- for (i = 0; i <= UCHAR_MAX; i++) {
- int first = i;
- while (i <= UCHAR_MAX && testchar(st, i)) i++;
- if (i - 1 == first) /* unary range? */
- printf("(%02x)", first);
- else if (i - 1 > first) /* non-empty range? */
- printf("(%02x-%02x)", first, i - 1);
- }
- printf("]");
- }
- static void printIcharset (const Instruction *inst, const byte *buff) {
- byte cs[CHARSETSIZE];
- int i;
- printf("(%02x-%d) ", inst->i.aux2.set.offset, inst->i.aux2.set.size);
- clearset(cs);
- for (i = 0; i < CHARSETSIZE * 8; i++) {
- if (charinset(inst, buff, i))
- setchar(cs, i);
- }
- printcharset(cs);
- }
- static void printTcharset (TTree *tree) {
- byte cs[CHARSETSIZE];
- int i;
- printf("(%02x-%d) ", tree->u.set.offset, tree->u.set.size);
- fillset(cs, tree->u.set.deflt);
- for (i = 0; i < tree->u.set.size; i++)
- cs[tree->u.set.offset + i] = treebuffer(tree)[i];
- printcharset(cs);
- }
- static const char *capkind (int kind) {
- const char *const modes[] = {
- "close", "position", "constant", "backref",
- "argument", "simple", "table", "function", "accumulator",
- "query", "string", "num", "substitution", "fold",
- "runtime", "group"};
- return modes[kind];
- }
- static void printjmp (const Instruction *op, const Instruction *p) {
- printf("-> %d", (int)(p + (p + 1)->offset - op));
- }
- void printinst (const Instruction *op, const Instruction *p) {
- const char *const names[] = {
- "any", "char", "set",
- "testany", "testchar", "testset",
- "span", "utf-range", "behind",
- "ret", "end",
- "choice", "jmp", "call", "open_call",
- "commit", "partial_commit", "back_commit", "failtwice", "fail", "giveup",
- "fullcapture", "opencapture", "closecapture", "closeruntime",
- "--"
- };
- printf("%02ld: %s ", (long)(p - op), names[p->i.code]);
- switch ((Opcode)p->i.code) {
- case IChar: {
- printf("'%c' (%02x)", p->i.aux1, p->i.aux1);
- break;
- }
- case ITestChar: {
- printf("'%c' (%02x)", p->i.aux1, p->i.aux1); printjmp(op, p);
- break;
- }
- case IUTFR: {
- printf("%d - %d", p[1].offset, utf_to(p));
- break;
- }
- case IFullCapture: {
- printf("%s (size = %d) (idx = %d)",
- capkind(getkind(p)), getoff(p), p->i.aux2.key);
- break;
- }
- case IOpenCapture: {
- printf("%s (idx = %d)", capkind(getkind(p)), p->i.aux2.key);
- break;
- }
- case ISet: {
- printIcharset(p, (p+1)->buff);
- break;
- }
- case ITestSet: {
- printIcharset(p, (p+2)->buff); printjmp(op, p);
- break;
- }
- case ISpan: {
- printIcharset(p, (p+1)->buff);
- break;
- }
- case IOpenCall: {
- printf("-> %d", (p + 1)->offset);
- break;
- }
- case IBehind: {
- printf("%d", p->i.aux1);
- break;
- }
- case IJmp: case ICall: case ICommit: case IChoice:
- case IPartialCommit: case IBackCommit: case ITestAny: {
- printjmp(op, p);
- break;
- }
- default: break;
- }
- printf("\n");
- }
- void printpatt (Instruction *p) {
- Instruction *op = p;
- uint n = op[-1].codesize - 1;
- while (p < op + n) {
- printinst(op, p);
- p += sizei(p);
- }
- }
- static void printcap (Capture *cap, int ident) {
- while (ident--) printf(" ");
- printf("%s (idx: %d - size: %d) -> %lu (%p)\n",
- capkind(cap->kind), cap->idx, cap->siz, (long)cap->index, (void*)cap);
- }
- /*
- ** Print a capture and its nested captures
- */
- static Capture *printcap2close (Capture *cap, int ident) {
- Capture *head = cap++;
- printcap(head, ident); /* print head capture */
- while (capinside(head, cap))
- cap = printcap2close(cap, ident + 2); /* print nested captures */
- if (isopencap(head)) {
- assert(isclosecap(cap));
- printcap(cap++, ident); /* print and skip close capture */
- }
- return cap;
- }
- void printcaplist (Capture *cap) {
- { /* for debugging, print first a raw list of captures */
- Capture *c = cap;
- while (c->index != MAXINDT) { printcap(c, 0); c++; }
- }
- printf(">======\n");
- while (!isclosecap(cap))
- cap = printcap2close(cap, 0);
- printf("=======\n");
- }
- /* }====================================================== */
- /*
- ** {======================================================
- ** Printing trees (for debugging)
- ** =======================================================
- */
- static const char *tagnames[] = {
- "char", "set", "any",
- "true", "false", "utf8.range",
- "rep",
- "seq", "choice",
- "not", "and",
- "call", "opencall", "rule", "xinfo", "grammar",
- "behind",
- "capture", "run-time"
- };
- void printtree (TTree *tree, int ident) {
- int i;
- int sibs = numsiblings[tree->tag];
- for (i = 0; i < ident; i++) printf(" ");
- printf("%s", tagnames[tree->tag]);
- switch (tree->tag) {
- case TChar: {
- int c = tree->u.n;
- if (isprint(c))
- printf(" '%c'\n", c);
- else
- printf(" (%02X)\n", c);
- break;
- }
- case TSet: {
- printTcharset(tree);
- printf("\n");
- break;
- }
- case TUTFR: {
- assert(sib1(tree)->tag == TXInfo);
- printf(" %d (%02x %d) - %d (%02x %d) \n",
- tree->u.n, tree->key, tree->cap,
- sib1(tree)->u.n, sib1(tree)->key, sib1(tree)->cap);
- break;
- }
- case TOpenCall: case TCall: {
- assert(sib1(sib2(tree))->tag == TXInfo);
- printf(" key: %d (rule: %d)\n", tree->key, sib1(sib2(tree))->u.n);
- break;
- }
- case TBehind: {
- printf(" %d\n", tree->u.n);
- break;
- }
- case TCapture: {
- printf(" kind: '%s' key: %d\n", capkind(tree->cap), tree->key);
- break;
- }
- case TRule: {
- printf(" key: %d\n", tree->key);
- sibs = 1; /* do not print 'sib2' (next rule) as a sibling */
- break;
- }
- case TXInfo: {
- printf(" n: %d\n", tree->u.n);
- break;
- }
- case TGrammar: {
- TTree *rule = sib1(tree);
- printf(" %d\n", tree->u.n); /* number of rules */
- for (i = 0; i < tree->u.n; i++) {
- printtree(rule, ident + 2);
- rule = sib2(rule);
- }
- assert(rule->tag == TTrue); /* sentinel */
- sibs = 0; /* siblings already handled */
- break;
- }
- default:
- printf("\n");
- break;
- }
- if (sibs >= 1) {
- printtree(sib1(tree), ident + 2);
- if (sibs >= 2)
- printtree(sib2(tree), ident + 2);
- }
- }
- void printktable (lua_State *L, int idx) {
- int n, i;
- lua_getuservalue(L, idx);
- if (lua_isnil(L, -1)) /* no ktable? */
- return;
- n = lua_rawlen(L, -1);
- printf("[");
- for (i = 1; i <= n; i++) {
- printf("%d = ", i);
- lua_rawgeti(L, -1, i);
- if (lua_isstring(L, -1))
- printf("%s ", lua_tostring(L, -1));
- else
- printf("%s ", lua_typename(L, lua_type(L, -1)));
- lua_pop(L, 1);
- }
- printf("]\n");
- /* leave ktable at the stack */
- }
- /* }====================================================== */
- #endif
|