diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-02-20 10:13:46 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-02-20 10:13:46 -0300 |
commit | e08e5df853560de6482d84066a7accc6a18de545 (patch) | |
tree | ee19686bb35da90709a32ed24bf7855de1a3946a /lpprint.c | |
download | lpeg-e08e5df853560de6482d84066a7accc6a18de545.tar.gz lpeg-e08e5df853560de6482d84066a7accc6a18de545.tar.bz2 lpeg-e08e5df853560de6482d84066a7accc6a18de545.zip |
Fist version of LPeg on GIT
LPeg repository is being moved to git. Past versions won't be moved;
they are still available in RCS.
Diffstat (limited to 'lpprint.c')
-rw-r--r-- | lpprint.c | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/lpprint.c b/lpprint.c new file mode 100644 index 0000000..f7be408 --- /dev/null +++ b/lpprint.c | |||
@@ -0,0 +1,244 @@ | |||
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 | ||