Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
api.c
Go to the documentation of this file.
1 /* *************************************************************************************
2  Copyright (c) 2021, Lowell D. Thomas
3  All rights reserved.
4 
5  This file is part of APG Version 7.0.
6  APG Version 7.0 may be used under the terms of the BSD 2-Clause License.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  1. Redistributions of source code must retain the above copyright notice, this
12  list of conditions and the following disclaimer.
13 
14  2. Redistributions in binary form must reproduce the above copyright notice,
15  this list of conditions and the following disclaimer in the documentation
16  and/or other materials provided with the distribution.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 * *************************************************************************************/
39 #include "./api.h"
40 #include "./apip.h"
41 #include "./attributes.h"
42 
43 static const void* s_vpMagicNumber = (void*)"API";
44 
45 static void vRulesFooter(FILE *spOut);
46 static void vRulesHeader(FILE *spOut);
47 static int iCompRules(const void *vpL, const void *vpR);
48 static int iCompUdts(const void *vpL, const void *vpR);
49 
55 void* vpApiCtor(exception* spEx) {
56  if(!bExValidate(spEx)){
57  vExContext();
58  }
59  void* vpMem = vpMemCtor(spEx);
60  api* spCtx = (api*) vpMemAlloc(vpMem, (aint) sizeof(api));
61  memset((void*) spCtx, 0, sizeof(api));
62  spCtx->vpMem = vpMem;
63  spCtx->spException = spEx;
64  spCtx->vpLog = vpMsgsCtor(spEx);
65 
66  // create the input vector
67  spCtx->vpAltStack = vpVecCtor(spCtx->vpMem, sizeof(alt_data), 100);
68  spCtx->vpVecGrammar = vpVecCtor(spCtx->vpMem, (aint) sizeof(achar), 512);
69  spCtx->vpVecInput = vpVecCtor(spCtx->vpMem, (aint) sizeof(char), 5120);
70  spCtx->vpVecTempChars = vpVecCtor(spCtx->vpMem, (aint) sizeof(char), 1024);
71  char cZero = 0;
72  spCtx->cpInput = (char*)vpVecPush(spCtx->vpVecInput, &cZero);
73  spCtx->uiInputLength = 0;
74 
75  spCtx->vpValidate = s_vpMagicNumber;
76  return (void*) spCtx;
77 }
78 
84 void vApiDtor(void *vpCtx) {
85  if(vpCtx){
86  api *spCtx = (api*) vpCtx;
87  if (spCtx->vpValidate == s_vpMagicNumber) {
88  void *vpMem = spCtx->vpMem;
89  vLinesDtor(spCtx->vpLines);
90  vMsgsDtor(spCtx->vpLog);
91  vParserDtor(spCtx->vpParser);
92  memset(vpCtx, 0, sizeof(api));
93  vMemDtor(vpMem);
94  }else{
95  vExContext();
96  }
97  }
98 }
99 
104 abool bApiValidate(void *vpCtx){
105  if(vpCtx && ((api*)vpCtx)->vpValidate == s_vpMagicNumber){
106  return APG_TRUE;
107  }
108  return APG_FALSE;
109 }
110 
117 void* vpApiGetErrorLog(void *vpCtx) {
118  api *spApi = (api*) vpCtx;
119  if (vpCtx && (spApi->vpValidate == s_vpMagicNumber)) {
120  return spApi->vpLog;
121  }
122  vExContext();
123  return NULL;
124 }
125 
132 void vApiRulesToHtml(void *vpCtx, const char *cpFileName) {
133  api *spApi = (api*) vpCtx;
134  if (!vpCtx || (spApi->vpValidate != s_vpMagicNumber)) {
135  vExContext();
136  }
137  FILE *spOut = stdout;
138  attrs_ctx *spAttrsCtx = (attrs_ctx*) spApi->vpAttrsCtx;
139  if (!spApi->bAttributesComputed || !spAttrsCtx) {
140  XTHROW(spApi->spException,
141  "cannot display rule dependencies without attributes (bApiAttrs())");
142  }
143  if (cpFileName) {
144  spOut = fopen(cpFileName, "wb");
145  if (!spOut) {
146  char caBuf[126];
147  snprintf(caBuf, 126, "cannot output open file name %s for writing", cpFileName);
148  XTHROW(spApi->spException, caBuf);
149  }
150  }
151  aint uiRuleCount = spApi->uiRuleCount;
152  aint uiUdtCount = spApi->uiUdtCount;
153  api_rule *spRules = spApi->spRules;
154  api_udt *spUdt = spApi->spUdts;
155  api_attr_w *spAttr = spAttrsCtx->spAttrs;
156  aint ui, uj, uiCount;
157  abool bFirst;
158  api_rule saRules[uiRuleCount];
159 
160  vRulesHeader(spOut);
161  // For each rule, find and display the list of rules that it refers to
162  // and the list of rules that refer to it,
163  for (ui = 0; ui < uiRuleCount; ui++, spAttr++) {
164  fprintf(spOut, "rulesData[%"PRIuMAX"] = {\n", (luint) ui);
165  fprintf(spOut, "name: \"%s\",\n", spAttr->cpRuleName);
166  fprintf(spOut, "index: %"PRIuMAX",\n", (luint) spAttr->uiRuleIndex);
167  fprintf(spOut, "to: [");
168  uiCount = 0;
169  for (uj = 0; uj < uiRuleCount; uj++) {
170  if (spAttr->bpRefersTo[uj]) {
171  saRules[uiCount] = spRules[uj];
172  uiCount++;
173  }
174  }
175  if (uiCount) {
176  qsort(saRules, uiCount, sizeof(api_rule), iCompRules);
177  bFirst = APG_TRUE;
178  for (uj = 0; uj < uiCount; uj++) {
179  if (bFirst) {
180  fprintf(spOut, "\"%s\"", saRules[uj].cpName);
181  bFirst = APG_FALSE;
182  } else {
183  fprintf(spOut, ", \"%s\"", saRules[uj].cpName);
184  }
185  }
186  }
187  fprintf(spOut, "],\n");
188  fprintf(spOut, "by: [");
189  uiCount = 0;
190  for (uj = 0; uj < uiRuleCount; uj++) {
191  if (spAttr->bpIsReferencedBy[uj]) {
192  saRules[uiCount] = spRules[uj];
193  uiCount++;
194  }
195  }
196  if (uiCount) {
197  qsort(saRules, uiCount, sizeof(api_rule), iCompRules);
198  bFirst = APG_TRUE;
199  for (uj = 0; uj < uiCount; uj++) {
200  if (bFirst) {
201  fprintf(spOut, "\"%s\"", saRules[uj].cpName);
202  bFirst = APG_FALSE;
203  } else {
204  fprintf(spOut, ", \"%s\"", saRules[uj].cpName);
205  }
206  }
207  }
208  fprintf(spOut, "]};\n");
209  }
210  if (uiUdtCount) {
211  // For each UDT, find and display the list of rules that refer to it,
212  spAttr = spAttrsCtx->spAttrs;
213  for (ui = 0; ui < uiUdtCount; ui++, spUdt++) {
214  fprintf(spOut, "udtsData[%"PRIuMAX"] = {\n", (luint) ui);
215  fprintf(spOut, "name: \"%s\",\n", spUdt->cpName);
216  fprintf(spOut, "index: %"PRIuMAX",\n", (luint) spUdt->uiIndex);
217  fprintf(spOut, "by: [");
218  uiCount = 0;
219  spAttr = spAttrsCtx->spAttrs;
220  for (uj = 0; uj < uiRuleCount; uj++, spAttr++) {
221  if (spAttr->bpRefersToUdt[ui]) {
222  saRules[uiCount] = spRules[uj];
223  uiCount++;
224  }
225  }
226  if (uiCount) {
227  qsort(saRules, uiCount, sizeof(api_rule), iCompRules);
228  bFirst = APG_TRUE;
229  for (uj = 0; uj < uiCount; uj++) {
230  if (bFirst) {
231  fprintf(spOut, "\"%s\"", saRules[uj].cpName);
232  bFirst = APG_FALSE;
233  } else {
234  fprintf(spOut, ", \"%s\"", saRules[uj].cpName);
235  }
236  }
237  }
238 
239  fprintf(spOut, "]};\n");
240  }
241  }
242  vRulesFooter(spOut);
243  if(spOut != stdout){
244  fclose(spOut);
245  }
246 }
257 void vApiRulesToAscii(void *vpCtx, const char *cpMode, const char *cpFileName) {
258  api *spApi = (api*) vpCtx;
259  if (!vpCtx || (spApi->vpValidate != s_vpMagicNumber)) {
260  vExContext();
261  }
262  FILE *spOut = stdout;
263  if (!spApi->bSemanticsValid) {
264  XTHROW(spApi->spException,
265  "cannot display rules until semantic phase is complete (bApiOpcodes())");
266  }
267  aint uiRuleCount = spApi->uiRuleCount;
268  aint uiUdtCount = spApi->uiUdtCount;
269  api_rule saRules[uiRuleCount];
270  api_udt saUdts[uiUdtCount];
271  aint ui;
272  abool bAlpha = APG_FALSE;
273  if (cpFileName) {
274  spOut = fopen(cpFileName, "wb");
275  if (!spOut) {
276  char caBuf[126];
277  snprintf(caBuf, 126, "cannot open file name %s for writing", cpFileName);
278  XTHROW(spApi->spException, caBuf);
279  }
280  }
281  if (cpMode) {
282  if (*cpMode == 'a' || *cpMode == 'A') {
283  bAlpha = APG_TRUE;
284  }
285  }
286  for (ui = 0; ui < uiRuleCount; ui++) {
287  saRules[ui] = spApi->spRules[ui];
288  }
289  if (bAlpha) {
290  qsort((void*) saRules, (size_t) uiRuleCount, sizeof(api_rule), iCompRules);
291  fprintf(spOut, "RULES BY ALPHABET\n");
292  } else {
293  fprintf(spOut, "RULES BY INDEX\n");
294  }
295  fprintf(spOut, " index | rule name\n");
296  fprintf(spOut, "-------|----------\n");
297  for (ui = 0; ui < uiRuleCount; ui++) {
298  fprintf(spOut, "%6"PRIuMAX" | %s\n", (luint) saRules[ui].uiIndex, saRules[ui].cpName);
299  }
300  if (uiUdtCount) {
301  fprintf(spOut, "\n");
302  for (ui = 0; ui < uiUdtCount; ui++) {
303  saUdts[ui] = spApi->spUdts[ui];
304  }
305  if (bAlpha) {
306  qsort((void*) saUdts, (size_t) uiUdtCount, sizeof(api_udt), iCompUdts);
307  fprintf(spOut, "UDTS BY ALPHABET\n");
308  } else {
309  fprintf(spOut, "UDTS BY INDEX\n");
310  }
311  fprintf(spOut, "index | UDT name\n");
312  fprintf(spOut, "------|----------\n");
313  for (ui = 0; ui < uiUdtCount; ui++) {
314  fprintf(spOut, "%6"PRIuMAX"| %s\n", (luint) saUdts[ui].uiIndex, saUdts[ui].cpName);
315  }
316  }
317  fprintf(spOut, "\n");
318  if (spOut != stdout) {
319  fclose(spOut);
320  }
321 }
328 void vApiOpcodesToAscii(void *vpCtx, const char* cpFileName) {
329  api *spApi = (api*) vpCtx;
330  if (!vpCtx || (spApi->vpValidate != s_vpMagicNumber)) {
331  vExContext();
332  }
333  if (!spApi->bSemanticsValid && spApi->vpParser) {
334  XTHROW(spApi->spException,
335  "cannot display opcodes until semantic phase is complete (bApiOpcodes())");
336  }
337  FILE *spOut = stdout;
338  if(cpFileName){
339  spOut = fopen(cpFileName, "wb");
340  if (!spOut) {
341  char caBuf[126];
342  snprintf(caBuf, 126, "cannot open file name %s for writing", cpFileName);
343  XTHROW(spApi->spException, caBuf);
344  }
345  }
346  // opcodes
347  aint uiRuleCount = spApi->uiRuleCount;
348  aint ui, uj, uk, uc;
349  luint *luipBeg;
350  api_rule *spRule;
351  api_op *spOp = spApi->spOpcodes;
352  fprintf(spOut, "OPCODES\n");
353  uk = 0;
354  for (ui = 0; ui < uiRuleCount; ui++) {
355  spRule = &spApi->spRules[ui];
356  fprintf(spOut, "rule: %"PRIuMAX": %s\n", (luint) ui, spRule->cpName);
357  for (uj = 0; uj < spRule->uiOpCount; uj++, uk++) {
358  spOp = &spApi->spOpcodes[uk];
359  switch (spOp->uiId) {
360  case ID_ALT:
361  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
362  fprintf(spOut, "ALT: ");
363  fprintf(spOut, "children: %"PRIuMAX":", (luint) spOp->uiChildCount);
364  for (uc = 0; uc < spOp->uiChildCount; uc++) {
365  if (uc == 0) {
366  fprintf(spOut, " %"PRIuMAX"", (luint) spOp->uipChildIndex[uc]);
367  } else {
368  fprintf(spOut, ", %"PRIuMAX"", (luint) spOp->uipChildIndex[uc]);
369 
370  }
371  }
372  fprintf(spOut, "\n");
373  break;
374  case ID_CAT:
375  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
376  fprintf(spOut, "CAT: ");
377  fprintf(spOut, "children: %"PRIuMAX":", (luint) spOp->uiChildCount);
378  for (uc = 0; uc < spOp->uiChildCount; uc++) {
379  if (uc == 0) {
380  fprintf(spOut, " %"PRIuMAX"", (luint) spOp->uipChildIndex[uc]);
381  } else {
382  fprintf(spOut, ", %"PRIuMAX"", (luint) spOp->uipChildIndex[uc]);
383 
384  }
385  }
386  fprintf(spOut, "\n");
387  break;
388  case ID_REP:
389  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
390  fprintf(spOut, "REP: ");
391  fprintf(spOut, "min: %"PRIuMAX": ", spOp->luiMin);
392  if (spOp->luiMax == (luint) -1) {
393  fprintf(spOut, "max: infinity");
394  } else {
395  fprintf(spOut, "max: %"PRIuMAX"", spOp->luiMax);
396  }
397  fprintf(spOut, "\n");
398  break;
399  case ID_RNM:
400  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
401  fprintf(spOut, "RNM: ");
402  fprintf(spOut, "%s", spApi->spRules[spOp->uiIndex].cpName);
403  fprintf(spOut, "\n");
404  break;
405  case ID_TBS:
406  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
407  fprintf(spOut, "TBS: ");
408  luipBeg = spOp->luipAchar;
409  fprintf(spOut, "\'");
410  for (uc = 0; uc < spOp->uiAcharLength; uc++, luipBeg++) {
411  if (*luipBeg >= 32 && *luipBeg <= 126) {
412  fprintf(spOut, "%c", (char) *luipBeg);
413  } else {
414  fprintf(spOut, "0x%.2"PRIXMAX"", *luipBeg);
415  }
416  }
417  fprintf(spOut, "\'");
418  fprintf(spOut, "\n");
419  break;
420  case ID_TLS:
421  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
422  fprintf(spOut, "TLS: ");
423  fprintf(spOut, "\"");
424  luipBeg = spOp->luipAchar;
425  for (uc = 0; uc < spOp->uiAcharLength; uc++, luipBeg++) {
426  fprintf(spOut, "%c", (char) *luipBeg);
427  }
428  fprintf(spOut, "\"");
429  fprintf(spOut, "\n");
430  break;
431  case ID_TRG:
432  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
433  fprintf(spOut, "TRG: ");
434  fprintf(spOut, "min: %"PRIuMAX": ", spOp->luiMin);
435  fprintf(spOut, "max: %"PRIuMAX"", spOp->luiMax);
436  fprintf(spOut, "\n");
437  break;
438  case ID_UDT:
439  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
440  fprintf(spOut, "UDT: ");
441  fprintf(spOut, "%s", spApi->spUdts[spOp->uiIndex].cpName);
442  fprintf(spOut, "\n");
443  break;
444  case ID_AND:
445  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
446  fprintf(spOut, "AND: ");
447  fprintf(spOut, "\n");
448  break;
449  case ID_NOT:
450  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
451  fprintf(spOut, "NOT: ");
452  fprintf(spOut, "\n");
453  break;
454  case ID_BKA:
455  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
456  fprintf(spOut, "BKA: ");
457  fprintf(spOut, "\n");
458  break;
459  case ID_BKN:
460  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
461  fprintf(spOut, "BKN: ");
462  fprintf(spOut, "\n");
463  break;
464  case ID_BKR:
465  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
466  fprintf(spOut, "BKR: ");
467  if (spOp->uiCase == ID_BKR_CASE_I) {
468  fprintf(spOut, "\\%%i");
469  } else {
470  fprintf(spOut, "\\%%s");
471  }
472  if (spOp->uiMode == ID_BKR_MODE_U) {
473  fprintf(spOut, "%%u");
474  } else {
475  fprintf(spOut, "%%p");
476  }
477  aint uiIndex = spOp->uiBkrIndex;
478  if (uiIndex < spApi->uiRuleCount) {
479  fprintf(spOut, "%s", spApi->spRules[uiIndex].cpName);
480  } else {
481  uiIndex -= spApi->uiRuleCount;
482  fprintf(spOut, "%s", spApi->spUdts[uiIndex].cpName);
483  }
484  fprintf(spOut, "\n");
485  break;
486  case ID_ABG:
487  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
488  fprintf(spOut, "ABG: ");
489  fprintf(spOut, "\n");
490  break;
491  case ID_AEN:
492  fprintf(spOut, "%"PRIuMAX": ", (luint) uk);
493  fprintf(spOut, "AEN: ");
494  fprintf(spOut, "\n");
495  break;
496  }
497  }
498  fprintf(spOut, "\n");
499  }
500  if(spOut != stdout){
501  fclose(spOut);
502  }
503 }
504 
517 void vApiFile(void *vpCtx, const char *cpFileName, abool bStrict, abool bPppt){
518  api *spApi = (api*) vpCtx;
519  if (!vpCtx || (spApi->vpValidate != s_vpMagicNumber)) {
520  vExContext();
521  }
522  vApiInClear(vpCtx);
523  cpApiInFile(vpCtx, cpFileName);
524  vApiInValidate(vpCtx, bStrict);
525  vApiSyntax(vpCtx, bStrict);
526  vApiOpcodes(vpCtx);
527  bApiAttrs(vpCtx);
528  if(bPppt){
529  vApiPppt(vpCtx, NULL, 0);
530  }
531 }
544 void vApiString(void *vpCtx, const char *cpString, abool bStrict, abool bPppt){
545  api *spApi = (api*) vpCtx;
546  if (!vpCtx || (spApi->vpValidate != s_vpMagicNumber)) {
547  vExContext();
548  }
549  vApiInClear(spApi);
550  cpApiInString(spApi, cpString);
551  vApiInValidate(vpCtx, bStrict);
552  vApiSyntax(vpCtx, bStrict);
553  vApiOpcodes(vpCtx);
554  bApiAttrs(vpCtx);
555  if(bPppt){
556  vApiPppt(vpCtx, NULL, 0);
557  }
558 }
559 
565 void vHtmlHeader(FILE *spFile, const char *cpTitle) {
566  if (spFile) {
567  if (!cpTitle) {
568  cpTitle = "APG generated HTML";
569  }
570  fprintf(spFile, "<!DOCTYPE html>\n");
571  fprintf(spFile, "<html lang=\"en\">\n");
572  fprintf(spFile, "<meta charset=\"utf-8\">\n");
573  fprintf(spFile, "<title>\n");
574  fprintf(spFile, "%s", cpTitle);
575  fprintf(spFile, "</title>\n<style>\n");
576  fprintf(spFile, "body{font-family: monospace; font-size: 1em;}\n");
577  fprintf(spFile, "kbd{font-weight: bold; font-style: italic; color: red;}\n"); // errors
578  fprintf(spFile, "var{color: #8A2BE2;}\n"); // control characters
579  fprintf(spFile, "th{text-align: left;}\n");
580  fprintf(spFile, "</style>\n");
581  fprintf(spFile, "<body>\n");
582  }
583 }
584 
589 void vHtmlFooter(FILE *spFile) {
590  if (spFile) {
591  fprintf(spFile, "</body>\n");
592  fprintf(spFile, "</html>\n");
593  }
594 }
595 
596 static void vRulesHeader(FILE *spOut) {
597  fprintf(spOut, "<!DOCTYPE html>\n");
598  fprintf(spOut, "<!-- LICENSE:\n");
599  fprintf(spOut, "-->\n");
600  fprintf(spOut, "<html>\n");
601  fprintf(spOut, " <head>\n");
602  fprintf(spOut, " <title>Rule Dependencies</title>\n");
603  fprintf(spOut, " <meta charset=\"UTF-8\">\n");
604  fprintf(spOut, " <meta name=\"viewport\" sContent=\"width=device-width, initial-scale=1.0\">\n");
605  fprintf(spOut, " <style>\n");
606  fprintf(spOut, " td{\n");
607  fprintf(spOut, " vertical-align: top;\n");
608  fprintf(spOut, " }\n");
609  fprintf(spOut, " caption{\n");
610  fprintf(spOut, " text-align: left;\n");
611  fprintf(spOut, " }\n");
612  fprintf(spOut, " ul{\n");
613  fprintf(spOut, " margin: 0;\n");
614  fprintf(spOut, " list-style: none;\n");
615  fprintf(spOut, " padding-left: 5px;\n");
616  fprintf(spOut, " }\n");
617  fprintf(spOut, " li{\n");
618  fprintf(spOut, " font-size: .8em;\n");
619  fprintf(spOut, " }\n");
620  fprintf(spOut, " .bold{\n");
621  fprintf(spOut, " font-weight: bold;\n");
622  fprintf(spOut, " }\n");
623  fprintf(spOut, " .tableButton, .closeButton{\n");
624  fprintf(spOut, " background-color:#ffffff;\n");
625  fprintf(spOut, " -moz-border-radius:28px;\n");
626  fprintf(spOut, " -webkit-border-radius:28px;\n");
627  fprintf(spOut, " border-radius:28px;\n");
628  fprintf(spOut, " border:1px solid #000000;\n");
629  fprintf(spOut, " cursor:pointer;\n");
630  fprintf(spOut, " color:#000000;\n");
631  fprintf(spOut, " font-family:Arial;\n");
632  fprintf(spOut, " font-size:12px;\n");
633  fprintf(spOut, " font-weight:bold;\n");
634  fprintf(spOut, " padding:1px 18px;\n");
635  fprintf(spOut, " text-decoration:none;\n");
636  fprintf(spOut, " outline: none;\n");
637  fprintf(spOut, " }\n");
638  fprintf(spOut, " .tableButton:hover, .closeButton:hover {\n");
639  fprintf(spOut, " background-color:lightgray;\n");
640  fprintf(spOut, " }\n");
641  fprintf(spOut, " .closeButton{\n");
642  fprintf(spOut, " margin: 8px 0px;\n");
643  fprintf(spOut, " }\n");
644  fprintf(spOut, " </style>\n");
645  fprintf(spOut, " </head>\n");
646  fprintf(spOut, " <body>\n");
647  fprintf(spOut, " <div id=\"rulesTable\"></div>\n");
648  fprintf(spOut, " <div id=\"udtsTable\"></div>\n");
649  fprintf(spOut, " <script>\n");
650  fprintf(spOut, " var ASC = 0;\n");
651  fprintf(spOut, " var DESC = 1;\n");
652  fprintf(spOut, " var rulesNameToggle = ASC;\n");
653  fprintf(spOut, " var rulesIndexToggle = DESC;\n");
654  fprintf(spOut, " var udtsNameToggle = ASC;\n");
655  fprintf(spOut, " var udtsIndexToggle = DESC;\n");
656  fprintf(spOut, " var rulesData = [];\n");
657  fprintf(spOut, " var udtsData = [];\n");
658  fprintf(spOut, " function toggle(id) {\n");
659  fprintf(spOut, " var x = document.getElementById(id);\n");
660  fprintf(spOut, " if (x.style.display === \"none\") {\n");
661  fprintf(spOut, " x.style.display = \"block\";\n");
662  fprintf(spOut, " } else {\n");
663  fprintf(spOut, " x.style.display = \"none\";\n");
664  fprintf(spOut, " }\n");
665  fprintf(spOut, " }\n");
666  fprintf(spOut, " function closeAllRules() {\n");
667  fprintf(spOut, " for (var i = 0; i < rulesData.length; i++) {\n");
668  fprintf(spOut, " x = document.getElementById(\"to\" + i);\n");
669  fprintf(spOut, " if (x) {\n");
670  fprintf(spOut, " x.style.display = \"none\";\n");
671  fprintf(spOut, " }\n");
672  fprintf(spOut, " x = document.getElementById(\"by\" + i);\n");
673  fprintf(spOut, " if (x) {\n");
674  fprintf(spOut, " x.style.display = \"none\";\n");
675  fprintf(spOut, " }\n");
676  fprintf(spOut, " }\n");
677  fprintf(spOut, " }\n");
678  fprintf(spOut, " function closeAllUdts() {\n");
679  fprintf(spOut, " for (var i = 0; i < udtsData.length; i++) {\n");
680  fprintf(spOut, " x = document.getElementById(\"udt\" + i);\n");
681  fprintf(spOut, " if (x) {\n");
682  fprintf(spOut, " x.style.display = \"none\";\n");
683  fprintf(spOut, " }\n");
684  fprintf(spOut, " }\n");
685  fprintf(spOut, " }\n");
686  fprintf(spOut, " function nameSortAscending(l, r) {\n");
687  fprintf(spOut, " var li = l.name.toUpperCase();\n");
688  fprintf(spOut, " var ri = r.name.toUpperCase();\n");
689  fprintf(spOut, " var ret = 0;\n");
690  fprintf(spOut, " if (li > ri) {\n");
691  fprintf(spOut, " ret = 1;\n");
692  fprintf(spOut, " } else if (li < ri) {\n");
693  fprintf(spOut, " ret = -1;\n");
694  fprintf(spOut, " }\n");
695  fprintf(spOut, " return ret;\n");
696  fprintf(spOut, " }\n");
697  fprintf(spOut, " function nameSortDescending(l, r) {\n");
698  fprintf(spOut, " return -1 * nameSortAscending(l, r);\n");
699  fprintf(spOut, " }\n");
700  fprintf(spOut, " function tableSort(data, col) {\n");
701  fprintf(spOut, " if (data === \"rules\") {\n");
702  fprintf(spOut, " if (col === \"index\") {\n");
703  fprintf(spOut, " if (rulesIndexToggle === ASC) {\n");
704  fprintf(spOut, " rulesData.sort((l,r)=>(l.index - r.index));\n");
705  fprintf(spOut, " rulesIndexToggle = DESC;\n");
706  fprintf(spOut, " } else if (rulesIndexToggle === DESC) {\n");
707  fprintf(spOut, " rulesData.sort((l,r)=>(r.index - l.index));\n");
708  fprintf(spOut, " rulesIndexToggle = ASC;\n");
709  fprintf(spOut, " }\n");
710  fprintf(spOut, " } else if (col === \"name\") {\n");
711  fprintf(spOut, " if (rulesNameToggle === ASC) {\n");
712  fprintf(spOut, " rulesData.sort(nameSortAscending);\n");
713  fprintf(spOut, " rulesNameToggle = DESC;\n");
714  fprintf(spOut, " } else if (rulesNameToggle === DESC) {\n");
715  fprintf(spOut, " rulesData.sort(nameSortDescending);\n");
716  fprintf(spOut, " rulesNameToggle = ASC;\n");
717  fprintf(spOut, " }\n");
718  fprintf(spOut, " }\n");
719  fprintf(spOut, " rulesGen();\n");
720  fprintf(spOut, " } else if (data === \"udts\") {\n");
721  fprintf(spOut, " if (col === \"index\") {\n");
722  fprintf(spOut, " if (udtsIndexToggle === ASC) {\n");
723  fprintf(spOut, " udtsData.sort((l,r)=>(l.index - r.index));\n");
724  fprintf(spOut, " udtsIndexToggle = DESC;\n");
725  fprintf(spOut, " } else if (udtsIndexToggle === DESC) {\n");
726  fprintf(spOut, " udtsData.sort((l,r)=>(r.index - l.index));\n");
727  fprintf(spOut, " udtsIndexToggle = ASC;\n");
728  fprintf(spOut, " }\n");
729  fprintf(spOut, " } else if (col === \"name\") {\n");
730  fprintf(spOut, " if (udtsNameToggle === ASC) {\n");
731  fprintf(spOut, " udtsData.sort(nameSortAscending);\n");
732  fprintf(spOut, " udtsNameToggle = DESC;\n");
733  fprintf(spOut, " } else if (udtsNameToggle === DESC) {\n");
734  fprintf(spOut, " udtsData.sort(nameSortDescending);\n");
735  fprintf(spOut, " udtsNameToggle = ASC;\n");
736  fprintf(spOut, " }\n");
737  fprintf(spOut, " }\n");
738  fprintf(spOut, " udtsGen();\n");
739  fprintf(spOut, " }\n");
740  fprintf(spOut, " }\n");
741  fprintf(spOut, " function rulesGen() {\n");
742  fprintf(spOut, " var html = \"\";\n");
743  fprintf(spOut, " html += '<table id=\"rulesTable\">';\n");
744  fprintf(spOut, " html += '<caption><strong>Rule Dependencies</strong><br>';\n");
745  fprintf(spOut,
746  " html += '<button class=\"closeButton\" onclick=\"closeAllRules()\">close all rules</button>';\n");
747  fprintf(spOut, " html += '<caption/>';\n");
748  fprintf(spOut,
749  " html += '<tr><td class=\"tableButton\" onclick=\"tableSort(\\'rules\\', \\'index\\')\">index</td>';\n");
750  fprintf(spOut,
751  " html += '<td class=\"tableButton\" onclick=\"tableSort(\\'rules\\', \\'name\\')\">name</td>';\n");
752  fprintf(spOut, " html += '<td class=\"bold\">dependencies</td></tr>';\n");
753  fprintf(spOut, " for (var i = 0; i < rulesData.length; i++) {\n");
754  fprintf(spOut, " var data = rulesData[i];\n");
755  fprintf(spOut, " html += \"<tr><td>\" + data.index + \"</td><td>\" + data.name + \"</td>\";\n");
756  fprintf(spOut, " if (data.to.length > 0) {\n");
757  fprintf(spOut, " var to = \"to\" + i;\n");
758  fprintf(spOut,
759  " html += '<td><button class=\"tableButton\" onclick=\"toggle(\\'' + to + '\\')\">refers to</button><br>';\n");
760  fprintf(spOut, " html += '<ul id=\"' + to + '\">';\n");
761  fprintf(spOut, " for (var j = 0; j < data.to.length; j++) {\n");
762  fprintf(spOut, " html += \"<li>\" + data.to[j] + \"</li>\";\n");
763  fprintf(spOut, " }\n");
764  fprintf(spOut, " html += '</ul>';\n");
765  fprintf(spOut, " html += \"</td></tr>\";\n");
766  fprintf(spOut, " } else {\n");
767  fprintf(spOut, " html += \"<td><i>no referals</i></td></tr>\";\n");
768  fprintf(spOut, " }\n");
769  fprintf(spOut, " if (data.by.length > 0) {\n");
770  fprintf(spOut, " var by = \"by\" + i;\n");
771  fprintf(spOut,
772  " html += '<tr><td></td><td></td><td><button class=\"tableButton\" onclick=\"toggle(\\'' + by + '\\')\">referenced by</button><br>';\n");
773  fprintf(spOut, " html += '<ul id=\"' + by + '\">';\n");
774  fprintf(spOut, " for (var j = 0; j < data.by.length; j++) {\n");
775  fprintf(spOut, " html += \"<li>\" + data.by[j] + \"</li>\";\n");
776  fprintf(spOut, " }\n");
777  fprintf(spOut, " html += '</ul>';\n");
778  fprintf(spOut, " html += \"</td><tr>\";\n");
779  fprintf(spOut, " } else {\n");
780  fprintf(spOut, " html += \"<tr><td></td><td></td><td><i>not referenced</i></td></tr>\";\n");
781  fprintf(spOut, " }\n");
782  fprintf(spOut, " }\n");
783  fprintf(spOut, " html += '</table>';\n");
784  fprintf(spOut, " var d = document.getElementById(\"rulesTable\");\n");
785  fprintf(spOut, " d.innerHTML = html;\n");
786  fprintf(spOut, " closeAllRules();\n");
787  fprintf(spOut, " }\n");
788  fprintf(spOut, " function udtsGen() {\n");
789  fprintf(spOut, " if (udtsData.length > 0) {\n");
790  fprintf(spOut, " var html = \"\";\n");
791  fprintf(spOut, " html += \"<p></p>\";\n");
792  fprintf(spOut, " html += '<table id=\"rulesTable\">';\n");
793  fprintf(spOut, " html += '<caption><strong>UDT Dependencies</strong><br>';\n");
794  fprintf(spOut,
795  " html += '<button class=\"closeButton\" onclick=\"closeAllUdts()\">close all UDTS</button>';\n");
796  fprintf(spOut, " html += '<caption/>';\n");
797  fprintf(spOut,
798  " html += '<tr><td class=\"tableButton\" onclick=\"tableSort(\\'udts\\', \\'index\\')\">index</td>';\n");
799  fprintf(spOut,
800  " html += '<td class=\"tableButton\" onclick=\"tableSort(\\'udts\\', \\'name\\')\">name</td>';\n");
801  fprintf(spOut, " html += '<td class=\"bold\">dependencies</td><tr>';\n");
802  fprintf(spOut, " for (var i = 0; i < udtsData.length; i++) {\n");
803  fprintf(spOut, " var data = udtsData[i];\n");
804  fprintf(spOut, " html += \"<tr><td>\" + data.index + \"</td><td>\" + data.name + \"</td>\";\n");
805  fprintf(spOut, " if (data.by.length > 0) {\n");
806  fprintf(spOut, " var by = \"udt\" + i;\n");
807  fprintf(spOut,
808  " html += '<td><button class=\"tableButton\" onclick=\"toggle(\\'' + by + '\\')\">referenced by</button><br>';\n");
809  fprintf(spOut, " html += '<ul id=\"' + by + '\">';\n");
810  fprintf(spOut, " for (var j = 0; j < data.by.length; j++) {\n");
811  fprintf(spOut, " html += \"<li>\" + data.by[j] + \"</li>\";\n");
812  fprintf(spOut, " }\n");
813  fprintf(spOut, " html += '</ul>';\n");
814  fprintf(spOut, " html += \"</td><tr>\";\n");
815  fprintf(spOut, " } else {\n");
816  fprintf(spOut, " html += \"<td><i>not referenced</i></td></tr>\";\n");
817  fprintf(spOut, " }\n");
818  fprintf(spOut, " }\n");
819  fprintf(spOut, " html += '</table>';\n");
820  fprintf(spOut, " var d = document.getElementById(\"udtsTable\");\n");
821  fprintf(spOut, " d.innerHTML = html;\n");
822  fprintf(spOut, " closeAllUdts();\n");
823  fprintf(spOut, " }\n");
824  fprintf(spOut, " }\n");
825  fprintf(spOut, " function setup() {\n");
826  fprintf(spOut, " if (rulesData.length > 0) {\n");
827  fprintf(spOut, " rulesGen();\n");
828  fprintf(spOut, " }\n");
829  fprintf(spOut, " if (udtsData.length > 0) {\n");
830  fprintf(spOut, " udtsGen();\n");
831  fprintf(spOut, " }\n");
832  fprintf(spOut, " }\n");
833  fprintf(spOut, " window.onload = setup;\n");
834 }
835 static void vRulesFooter(FILE *spOut) {
836  fprintf(spOut, "</script>\n");
837  fprintf(spOut, "</body>\n");
838  fprintf(spOut, "</html>\n");
839 }
840 static int iCompRules(const void *vpL, const void *vpR) {
841  api_rule *spL = (api_rule*) vpL;
842  api_rule *spR = (api_rule*) vpR;
843  return strcmp(spL->cpName, spR->cpName);
844 }
845 static int iCompUdts(const void *vpL, const void *vpR) {
846  api_udt *spL = (api_udt*) vpL;
847  api_udt *spR = (api_udt*) vpR;
848  return strcmp(spL->cpName, spR->cpName);
849 }
api_attr_w::bpRefersToUdt
abool * bpRefersToUdt
a list of all the UDTs that this rule refers to
Definition: apip.h:111
api::uiUdtCount
aint uiUdtCount
The number of UDTs referenced in the SABNF grammar.
Definition: apip.h:148
bApiValidate
abool bApiValidate(void *vpCtx)
Validates an API context pointer.
Definition: api.c:104
ID_BKR_CASE_I
#define ID_BKR_CASE_I
the back reference is case insensitive
Definition: parser.h:121
vHtmlHeader
void vHtmlHeader(FILE *spFile, const char *cpTitle)
Prints an HTML header to an open file.
Definition: api.c:565
api::spRules
api_rule * spRules
Points to an array of rule structures.
Definition: apip.h:145
api_attr_w::bpIsReferencedBy
abool * bpIsReferencedBy
a list of all the rules that refer to this rule
Definition: apip.h:113
api_op::luiMax
luint luiMax
maximum value for REP and TRG opcodes
Definition: apip.h:85
vMemDtor
void vMemDtor(void *vpCtx)
Destroys a Memory component. Frees all memory allocated.
Definition: memory.c:141
ID_RNM
#define ID_RNM
rule name
Definition: parser.h:46
api::spOpcodes
api_op * spOpcodes
Pointer to the array of opcodes for the SANF grammar.
Definition: apip.h:162
vApiInClear
void vApiInClear(void *vpCtx)
Clears the input and related memory.
Definition: input.c:61
api_op::uiAcharLength
aint uiAcharLength
number of characters in TLS/TBS strings
Definition: apip.h:87
attrs_ctx
The API will construct an attributes object. This is the attribute object's context.
Definition: attributes.h:41
api::vpLog
void * vpLog
A msglog context for error reporting.
Definition: apip.h:179
api_attr_w
Working attribute information about a each rule.
Definition: apip.h:99
vpApiCtor
void * vpApiCtor(exception *spEx)
Construct an API component context (object).
Definition: api.c:55
ID_ALT
#define ID_ALT
alternation
Definition: parser.h:43
ID_BKR
#define ID_BKR
back reference to a previously matched rule or UDT name
Definition: parser.h:58
ID_UDT
#define ID_UDT
user-defined terminal
Definition: parser.h:55
vApiInValidate
void vApiInValidate(void *vpCtx, abool bStrict)
Scans the input SABNF grammar for invalid characters and line ends.
Definition: input.c:204
api_rule
API information about each rule.
Definition: apip.h:55
apip.h
Private header file for the APG API suite of functions.
vExContext
void vExContext()
Handles bad context pointers.
Definition: exception.c:126
api_op::uiChildCount
aint uiChildCount
number of children for this ALT or CAT operator
Definition: apip.h:83
vApiOpcodes
void vApiOpcodes(void *vpCtx)
Parse the SABNF grammar and translate its AST into opcodes for all the rules.
Definition: semantics.c:64
achar
uint_fast8_t achar
achar is the type for the parser's alphabet characters.
Definition: apg.h:91
api::vpAttrsCtx
void * vpAttrsCtx
context handle to the attributes object
Definition: apip.h:130
vApiDtor
void vApiDtor(void *vpCtx)
The API component destructor.
Definition: api.c:84
vpApiGetErrorLog
void * vpApiGetErrorLog(void *vpCtx)
Get the internal message log.
Definition: api.c:117
alt_data
Used by syntax.c but needed here for constructor/destructor.
Definition: apip.h:40
ID_NOT
#define ID_NOT
negative look ahead
Definition: parser.h:57
ID_AND
#define ID_AND
positive look ahead
Definition: parser.h:56
api_op::luipAchar
luint * luipAchar
pointer to the first character in the achar table for this TLS/TBS operator
Definition: apip.h:86
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
api_op::luiMin
luint luiMin
minimum value for REP and TRG opcodes
Definition: apip.h:84
api::spUdts
api_udt * spUdts
Points to an array of UDT structures, if one or more UDTs are referenced in the SABNF grammar.
Definition: apip.h:147
api::uiRuleCount
aint uiRuleCount
The number of rules in the SABNF grammar and in the array.
Definition: apip.h:146
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
vApiFile
void vApiFile(void *vpCtx, const char *cpFileName, abool bStrict, abool bPppt)
Quicky way to generate a parser from a grammar file.
Definition: api.c:517
vpMsgsCtor
void * vpMsgsCtor(exception *spEx)
The Message Log constructor.
Definition: msglog.c:68
ID_CAT
#define ID_CAT
concatenation
Definition: parser.h:44
api_op::uiMode
aint uiMode
ID_BKR_MODE_U of ID_BKR_MODE_P for BKR.
Definition: apip.h:89
vpMemAlloc
void * vpMemAlloc(void *vpCtx, aint uiBytes)
Allocates memory.
Definition: memory.c:196
vHtmlFooter
void vHtmlFooter(FILE *spFile)
Prints an HTML footer to an open file.
Definition: api.c:589
vApiSyntax
void vApiSyntax(void *vpCtx, abool bStrict)
Parse the SABNF grammar to validate that the grammar structure is valid.
Definition: syntax.c:51
vpVecCtor
void * vpVecCtor(void *vpMem, aint uiElementSize, aint uiInitialAlloc)
The vector object constructor.
Definition: vector.c:118
ID_TRG
#define ID_TRG
terminal range
Definition: parser.h:47
api_udt::cpName
char * cpName
pointer to null-terminated string in the string table
Definition: apip.h:70
ID_REP
#define ID_REP
repetition
Definition: parser.h:45
api::vpLines
void * vpLines
Context pointer to a lines object.
Definition: apip.h:141
exception
A structure to describe the type and location of a caught exception.
Definition: exception.h:47
api_op::uiCase
aint uiCase
ID_BKR_CASE_S or ID_BKR_CASE_I for BKR.
Definition: apip.h:88
api_op::uiIndex
aint uiIndex
index of this referenced rule or UDT
Definition: apip.h:80
api
The API context.
Definition: apip.h:123
vMsgsDtor
void vMsgsDtor(void *vpCtx)
The object destructor.
Definition: msglog.c:92
luint
uintmax_t luint
luint is used to cast integers suitable for the %"PRIuMAX" printf format.
Definition: apg.h:133
vApiRulesToAscii
void vApiRulesToAscii(void *vpCtx, const char *cpMode, const char *cpFileName)
Display rules and UDTs in human-readable format in ASCII format.
Definition: api.c:257
bExValidate
abool bExValidate(exception *spException)
Test an exception structure for validity.
Definition: exception.c:70
api_attr_w::cpRuleName
char * cpRuleName
the rule name for these attributes
Definition: apip.h:107
api_op
API information about each opcode.
Definition: apip.h:78
bApiAttrs
abool bApiAttrs(void *vpCtx)
Computes the grammar's attributes.
Definition: attributes.c:79
api_udt
API information about each UDT.
Definition: apip.h:69
ID_BKA
#define ID_BKA
positive look behind
Definition: parser.h:59
vpMemCtor
void * vpMemCtor(exception *spException)
Construct a memory component.
Definition: memory.c:121
attributes.h
Header file for the attributes functions.
api::bAttributesComputed
abool bAttributesComputed
APG_TRUE if attributes have been computed (even is there are attribute errors), APG_FALSE otherwise.
Definition: apip.h:188
api::vpValidate
const void * vpValidate
the "magic number" to indicate that this is a valid context
Definition: apip.h:124
cpApiInFile
const char * cpApiInFile(void *vpCtx, const char *cpFileName)
Reads an SABNF grammar byte stream from a file.
Definition: input.c:117
api_attr_w::bpRefersTo
abool * bpRefersTo
a list of all the rules that this rule refers to
Definition: apip.h:112
api_op::uiId
aint uiId
type of opcode, ID_ALT, etc.
Definition: apip.h:79
ID_TLS
#define ID_TLS
terminal literal string
Definition: parser.h:49
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
cpApiInString
const char * cpApiInString(void *vpCtx, const char *cpString)
Reads an SABNF grammar byte stream from a string.
Definition: input.c:165
vLinesDtor
void vLinesDtor(void *vpCtx)
The lines object destructor.
Definition: lines.c:123
vParserDtor
void vParserDtor(void *vpCtx)
Clears the parser component's context and frees all heap memory associated with this parser.
Definition: parser.c:245
vApiOpcodesToAscii
void vApiOpcodesToAscii(void *vpCtx, const char *cpFileName)
Display all opcodes in human-readable format.
Definition: api.c:328
ID_BKN
#define ID_BKN
negative look behind
Definition: parser.h:60
abool
uint8_t abool
abool is the APG bool type.
Definition: apg.h:140
api_rule::cpName
char * cpName
pointer to null-terminated string in the string table
Definition: apip.h:56
api_attr_w::uiRuleIndex
aint uiRuleIndex
the index of the rule for these attributes
Definition: apip.h:108
api_udt::uiIndex
aint uiIndex
index of this UDT in the UDT list
Definition: apip.h:71
api_op::uiBkrIndex
aint uiBkrIndex
if BKR, this is the index to the rule or UDT that is being back referenced
Definition: apip.h:90
api::vpParser
void * vpParser
context handle to the SABNF grammar parser object
Definition: apip.h:127
api::vpMem
void * vpMem
Pointer to the memory context used for all memory allocations and exceptions thrown.
Definition: apip.h:126
vApiRulesToHtml
void vApiRulesToHtml(void *vpCtx, const char *cpFileName)
Display the grammar rules in human-readable, HTML format.
Definition: api.c:132
api_op::uipChildIndex
aint * uipChildIndex
pointer to the first child index of this ALT or CAT operator
Definition: apip.h:82
attrs_ctx::spAttrs
api_attr_w * spAttrs
An array of private attribute structures used in their construction.
Definition: attributes.h:48
ID_ABG
#define ID_ABG
anchor - beginning of string
Definition: parser.h:61
api::spException
exception * spException
Definition: apip.h:125
api::bSemanticsValid
abool bSemanticsValid
APG_TRUE if the the input semantics are valid. That is, the opcodes for the parser have been generate...
Definition: apip.h:184
ID_BKR_MODE_U
#define ID_BKR_MODE_U
the back reference is universal mode
Definition: parser.h:118
vApiString
void vApiString(void *vpCtx, const char *cpString, abool bStrict, abool bPppt)
Quicky way to generate a parser from a grammar string.
Definition: api.c:544
ID_TBS
#define ID_TBS
terminal binary string
Definition: parser.h:48
vpVecPush
void * vpVecPush(void *vpCtx, void *vpElement)
Adds one element to the end of the array.
Definition: vector.c:193
api_rule::uiOpCount
aint uiOpCount
the number of opcodes in this rule
Definition: apip.h:59
ID_AEN
#define ID_AEN
anchor - end of string
Definition: parser.h:62
vApiPppt
void vApiPppt(void *vpCtx, char **cppProtectedRules, aint uiProtectedRules)
Compute the Partially-Predictive Parsing Tables.
Definition: pppt.c:101
api.h
Public header file for the APG API suite of functions.
APG_FALSE
#define APG_FALSE
Definition: apg.h:292
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.