|
Packit |
909456 |
/*
|
|
Packit |
909456 |
** $Id: lpprint.c,v 1.10 2016/09/13 16:06:03 roberto Exp $
|
|
Packit |
909456 |
** Copyright 2007, Lua.org & PUC-Rio (see 'lpeg.html' for license)
|
|
Packit |
909456 |
*/
|
|
Packit |
909456 |
|
|
Packit |
909456 |
#include <ctype.h>
|
|
Packit |
909456 |
#include <limits.h>
|
|
Packit |
909456 |
#include <stdio.h>
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
#include "lptypes.h"
|
|
Packit |
909456 |
#include "lpprint.h"
|
|
Packit |
909456 |
#include "lpcode.h"
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
#if defined(LPEG_DEBUG)
|
|
Packit |
909456 |
|
|
Packit |
909456 |
/*
|
|
Packit |
909456 |
** {======================================================
|
|
Packit |
909456 |
** Printing patterns (for debugging)
|
|
Packit |
909456 |
** =======================================================
|
|
Packit |
909456 |
*/
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
void printcharset (const byte *st) {
|
|
Packit |
909456 |
int i;
|
|
Packit |
909456 |
printf("[");
|
|
Packit |
909456 |
for (i = 0; i <= UCHAR_MAX; i++) {
|
|
Packit |
909456 |
int first = i;
|
|
Packit |
909456 |
while (testchar(st, i) && i <= UCHAR_MAX) i++;
|
|
Packit |
909456 |
if (i - 1 == first) /* unary range? */
|
|
Packit |
909456 |
printf("(%02x)", first);
|
|
Packit |
909456 |
else if (i - 1 > first) /* non-empty range? */
|
|
Packit |
909456 |
printf("(%02x-%02x)", first, i - 1);
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
printf("]");
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
static const char *capkind (int kind) {
|
|
Packit |
909456 |
const char *const modes[] = {
|
|
Packit |
909456 |
"close", "position", "constant", "backref",
|
|
Packit |
909456 |
"argument", "simple", "table", "function",
|
|
Packit |
909456 |
"query", "string", "num", "substitution", "fold",
|
|
Packit |
909456 |
"runtime", "group"};
|
|
Packit |
909456 |
return modes[kind];
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
static void printjmp (const Instruction *op, const Instruction *p) {
|
|
Packit |
909456 |
printf("-> %d", (int)(p + (p + 1)->offset - op));
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
void printinst (const Instruction *op, const Instruction *p) {
|
|
Packit |
909456 |
const char *const names[] = {
|
|
Packit |
909456 |
"any", "char", "set",
|
|
Packit |
909456 |
"testany", "testchar", "testset",
|
|
Packit |
909456 |
"span", "behind",
|
|
Packit |
909456 |
"ret", "end",
|
|
Packit |
909456 |
"choice", "jmp", "call", "open_call",
|
|
Packit |
909456 |
"commit", "partial_commit", "back_commit", "failtwice", "fail", "giveup",
|
|
Packit |
909456 |
"fullcapture", "opencapture", "closecapture", "closeruntime"
|
|
Packit |
909456 |
};
|
|
Packit |
909456 |
printf("%02ld: %s ", (long)(p - op), names[p->i.code]);
|
|
Packit |
909456 |
switch ((Opcode)p->i.code) {
|
|
Packit |
909456 |
case IChar: {
|
|
Packit |
909456 |
printf("'%c'", p->i.aux);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case ITestChar: {
|
|
Packit |
909456 |
printf("'%c'", p->i.aux); printjmp(op, p);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case IFullCapture: {
|
|
Packit |
909456 |
printf("%s (size = %d) (idx = %d)",
|
|
Packit |
909456 |
capkind(getkind(p)), getoff(p), p->i.key);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case IOpenCapture: {
|
|
Packit |
909456 |
printf("%s (idx = %d)", capkind(getkind(p)), p->i.key);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case ISet: {
|
|
Packit |
909456 |
printcharset((p+1)->buff);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case ITestSet: {
|
|
Packit |
909456 |
printcharset((p+2)->buff); printjmp(op, p);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case ISpan: {
|
|
Packit |
909456 |
printcharset((p+1)->buff);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case IOpenCall: {
|
|
Packit |
909456 |
printf("-> %d", (p + 1)->offset);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case IBehind: {
|
|
Packit |
909456 |
printf("%d", p->i.aux);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case IJmp: case ICall: case ICommit: case IChoice:
|
|
Packit |
909456 |
case IPartialCommit: case IBackCommit: case ITestAny: {
|
|
Packit |
909456 |
printjmp(op, p);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
default: break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
printf("\n");
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
void printpatt (Instruction *p, int n) {
|
|
Packit |
909456 |
Instruction *op = p;
|
|
Packit |
909456 |
while (p < op + n) {
|
|
Packit |
909456 |
printinst(op, p);
|
|
Packit |
909456 |
p += sizei(p);
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
#if defined(LPEG_DEBUG)
|
|
Packit |
909456 |
static void printcap (Capture *cap) {
|
|
Packit |
909456 |
printf("%s (idx: %d - size: %d) -> %p\n",
|
|
Packit |
909456 |
capkind(cap->kind), cap->idx, cap->siz, cap->s);
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
void printcaplist (Capture *cap, Capture *limit) {
|
|
Packit |
909456 |
printf(">======\n");
|
|
Packit |
909456 |
for (; cap->s && (limit == NULL || cap < limit); cap++)
|
|
Packit |
909456 |
printcap(cap);
|
|
Packit |
909456 |
printf("=======\n");
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
#endif
|
|
Packit |
909456 |
|
|
Packit |
909456 |
/* }====================================================== */
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
/*
|
|
Packit |
909456 |
** {======================================================
|
|
Packit |
909456 |
** Printing trees (for debugging)
|
|
Packit |
909456 |
** =======================================================
|
|
Packit |
909456 |
*/
|
|
Packit |
909456 |
|
|
Packit |
909456 |
static const char *tagnames[] = {
|
|
Packit |
909456 |
"char", "set", "any",
|
|
Packit |
909456 |
"true", "false",
|
|
Packit |
909456 |
"rep",
|
|
Packit |
909456 |
"seq", "choice",
|
|
Packit |
909456 |
"not", "and",
|
|
Packit |
909456 |
"call", "opencall", "rule", "grammar",
|
|
Packit |
909456 |
"behind",
|
|
Packit |
909456 |
"capture", "run-time"
|
|
Packit |
909456 |
};
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
void printtree (TTree *tree, int ident) {
|
|
Packit |
909456 |
int i;
|
|
Packit |
909456 |
for (i = 0; i < ident; i++) printf(" ");
|
|
Packit |
909456 |
printf("%s", tagnames[tree->tag]);
|
|
Packit |
909456 |
switch (tree->tag) {
|
|
Packit |
909456 |
case TChar: {
|
|
Packit |
909456 |
int c = tree->u.n;
|
|
Packit |
909456 |
if (isprint(c))
|
|
Packit |
909456 |
printf(" '%c'\n", c);
|
|
Packit |
909456 |
else
|
|
Packit |
909456 |
printf(" (%02X)\n", c);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case TSet: {
|
|
Packit |
909456 |
printcharset(treebuffer(tree));
|
|
Packit |
909456 |
printf("\n");
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case TOpenCall: case TCall: {
|
|
Packit |
909456 |
assert(sib2(tree)->tag == TRule);
|
|
Packit |
909456 |
printf(" key: %d (rule: %d)\n", tree->key, sib2(tree)->cap);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case TBehind: {
|
|
Packit |
909456 |
printf(" %d\n", tree->u.n);
|
|
Packit |
909456 |
printtree(sib1(tree), ident + 2);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case TCapture: {
|
|
Packit |
909456 |
printf(" kind: '%s' key: %d\n", capkind(tree->cap), tree->key);
|
|
Packit |
909456 |
printtree(sib1(tree), ident + 2);
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case TRule: {
|
|
Packit |
909456 |
printf(" n: %d key: %d\n", tree->cap, tree->key);
|
|
Packit |
909456 |
printtree(sib1(tree), ident + 2);
|
|
Packit |
909456 |
break; /* do not print next rule as a sibling */
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
case TGrammar: {
|
|
Packit |
909456 |
TTree *rule = sib1(tree);
|
|
Packit |
909456 |
printf(" %d\n", tree->u.n); /* number of rules */
|
|
Packit |
909456 |
for (i = 0; i < tree->u.n; i++) {
|
|
Packit |
909456 |
printtree(rule, ident + 2);
|
|
Packit |
909456 |
rule = sib2(rule);
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
assert(rule->tag == TTrue); /* sentinel */
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
default: {
|
|
Packit |
909456 |
int sibs = numsiblings[tree->tag];
|
|
Packit |
909456 |
printf("\n");
|
|
Packit |
909456 |
if (sibs >= 1) {
|
|
Packit |
909456 |
printtree(sib1(tree), ident + 2);
|
|
Packit |
909456 |
if (sibs >= 2)
|
|
Packit |
909456 |
printtree(sib2(tree), ident + 2);
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
break;
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
|
|
Packit |
909456 |
|
|
Packit |
909456 |
void printktable (lua_State *L, int idx) {
|
|
Packit |
909456 |
int n, i;
|
|
Packit |
909456 |
lua_getuservalue(L, idx);
|
|
Packit |
909456 |
if (lua_isnil(L, -1)) /* no ktable? */
|
|
Packit |
909456 |
return;
|
|
Packit |
909456 |
n = lua_rawlen(L, -1);
|
|
Packit |
909456 |
printf("[");
|
|
Packit |
909456 |
for (i = 1; i <= n; i++) {
|
|
Packit |
909456 |
printf("%d = ", i);
|
|
Packit |
909456 |
lua_rawgeti(L, -1, i);
|
|
Packit |
909456 |
if (lua_isstring(L, -1))
|
|
Packit |
909456 |
printf("%s ", lua_tostring(L, -1));
|
|
Packit |
909456 |
else
|
|
Packit |
909456 |
printf("%s ", lua_typename(L, lua_type(L, -1)));
|
|
Packit |
909456 |
lua_pop(L, 1);
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
printf("]\n");
|
|
Packit |
909456 |
/* leave ktable at the stack */
|
|
Packit |
909456 |
}
|
|
Packit |
909456 |
|
|
Packit |
909456 |
/* }====================================================== */
|
|
Packit |
909456 |
|
|
Packit |
909456 |
#endif
|