Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
operators-abnf.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 * *************************************************************************************/
56 #include "./lib.h"
57 #include "./parserp.h"
58 #include "./astp.h"
59 #include "./tracep.h"
60 #include "./statsp.h"
61 #include "./operators.h"
62 #include "./backref.h"
63 #include "./backrefu.h"
64 #include "./backrefp.h"
65 
66 void vAlt(parser* spCtx, const opcode* spOp) {
67  const aint* uipChildBeg;
68  const aint* uipChildEnd;
69  const opcode* spChildOp;
70  spCtx->sState.uiHitCount++;
71  spCtx->uiTreeDepth++;
72  if(spCtx->uiTreeDepth > spCtx->sState.uiMaxTreeDepth){
73  spCtx->sState.uiMaxTreeDepth = spCtx->uiTreeDepth;
74  }
75  // note: don't need AST_OP_OPEN & AST_OP_CLOSE because all of the
76  // ALT children do this on the syntax tree node immediately below
77  TRACE_DOWN(spCtx->vpTrace, spOp, spCtx->uiOffset);
78  PPPT_OPEN(spCtx, spOp, spCtx->uiOffset);
79  uipChildBeg = spOp->sAlt.uipChildList;
80  uipChildEnd = uipChildBeg + spOp->sAlt.uiChildCount;
81  for (; uipChildBeg < uipChildEnd; uipChildBeg++) {
82 
83  // execute the child opcode
84  spCtx->uiOpState = ID_ACTIVE;
85  spChildOp = spCtx->spOpcodes + *uipChildBeg;
86  spCtx->pfnOpFunc[spChildOp->sGen.uiId](spCtx, spChildOp);
87  if (spCtx->uiOpState == ID_MATCH) {
88  // found a match, stop here, spCtx will have correct phrase length from matched child
89  break;
90  }
91  }
92  PPPT_CLOSE;
93  // NOTE: if no match is found, spCtx will have NOMATCH and zero phrase length from last child
94  TRACE_UP(spCtx->vpTrace, spOp, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
95  STATS_HIT(spCtx->vpStats, spOp, spCtx->uiOpState);
96  spCtx->uiTreeDepth--;
97 }
98 
99 void vCat(parser* spCtx, const opcode* spOp) {
100  aint uiOffset = spCtx->uiOffset;
101  aint uiPhraseLength = 0;
102  aint uiMatched = APG_TRUE;
103  const aint* uipChildBeg;
104  const aint* uipChildEnd;
105  const opcode* spChildOp;
106  spCtx->sState.uiHitCount++;
107  spCtx->uiTreeDepth++;
108  if(spCtx->uiTreeDepth > spCtx->sState.uiMaxTreeDepth){
109  spCtx->sState.uiMaxTreeDepth = spCtx->uiTreeDepth;
110  }
111  TRACE_DOWN(spCtx->vpTrace, spOp, spCtx->uiOffset);
112  AST_OP_OPEN(spCtx->vpAst, spCtx->uiInLookaround);
113  BKRU_OP_OPEN(spCtx->vpBkru);
114  BKRP_OP_OPEN(spCtx->vpBkrp);
115  PPPT_OPEN(spCtx, spOp, spCtx->uiOffset);
116  uipChildBeg = spOp->sCat.uipChildList;
117  uipChildEnd = uipChildBeg + spOp->sCat.uiChildCount;
118  while (uipChildBeg < uipChildEnd) {
119  // execute the child opcode
120  spCtx->uiOpState = ID_ACTIVE;
121  spChildOp = spCtx->spOpcodes + *uipChildBeg;
122  spCtx->pfnOpFunc[spChildOp->sGen.uiId](spCtx, spChildOp);
123 
124  if (spCtx->uiOpState == ID_NOMATCH) {
125  // if any child doesn't match, CAT doesn't match
126  spCtx->uiOffset = uiOffset; // reset the offset on no match
127  uiMatched = APG_FALSE;
128  break;
129  }
130  uiPhraseLength += spCtx->uiPhraseLength;
131  uipChildBeg++;
132  }
133  if (uiMatched) {
134  spCtx->uiPhraseLength = uiPhraseLength;
135  } else {
136  spCtx->uiOpState = ID_NOMATCH;
137  spCtx->uiOffset = uiOffset;
138  }
139  PPPT_CLOSE;
140  BKRU_OP_CLOSE(spCtx->vpBkru, spCtx->uiOpState);
141  BKRP_OP_CLOSE(spCtx->vpBkrp, spCtx->uiOpState);
142  AST_OP_CLOSE(spCtx->vpAst, spCtx->uiInLookaround, spCtx->uiOpState);
143  TRACE_UP(spCtx->vpTrace, spOp, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
144  STATS_HIT(spCtx->vpStats, spOp, spCtx->uiOpState);
145  spCtx->uiTreeDepth--;
146 }
147 
148 void vRep(parser* spCtx, const opcode* spOp) {
149  aint uiMatchCount = 0;
150  aint uiPhraseLength = 0;
151  aint uiOffset = spCtx->uiOffset;
152  spCtx->sState.uiHitCount++;
153  spCtx->uiTreeDepth++;
154  if(spCtx->uiTreeDepth > spCtx->sState.uiMaxTreeDepth){
155  spCtx->sState.uiMaxTreeDepth = spCtx->uiTreeDepth;
156  }
157  TRACE_DOWN(spCtx->vpTrace, spOp, spCtx->uiOffset);
158  AST_OP_OPEN(spCtx->vpAst, spCtx->uiInLookaround);
159  BKRU_OP_OPEN(spCtx->vpBkru);
160  BKRP_OP_OPEN(spCtx->vpBkrp);
161  PPPT_OPEN(spCtx, spOp, spCtx->uiOffset);
162  spCtx->uiOpState = ID_ACTIVE;
163  while (APG_TRUE) {
164  // setup
165  AST_OP_OPEN(spCtx->vpAst, spCtx->uiInLookaround);
166  BKRU_OP_OPEN(spCtx->vpBkru);
167  BKRP_OP_OPEN(spCtx->vpBkrp);
168 
169  // execute the child opcode
170  spCtx->pfnOpFunc[(spOp + 1)->sGen.uiId](spCtx, (spOp + 1));
171 
172  BKRU_OP_CLOSE(spCtx->vpBkru, spCtx->uiOpState);
173  BKRP_OP_CLOSE(spCtx->vpBkrp, spCtx->uiOpState);
174  AST_OP_CLOSE(spCtx->vpAst, spCtx->uiInLookaround, spCtx->uiOpState);
175  if ((spCtx->uiOpState == ID_MATCH) && (spCtx->uiPhraseLength == 0)) {
176  // REP succeeds on empty, regardless of min/max
177  spCtx->uiOpState = ID_MATCH;
178  spCtx->uiOffset = uiOffset + uiPhraseLength;
179  spCtx->uiPhraseLength = uiPhraseLength;
180  break;
181  }
182  if (spCtx->uiOpState == ID_NOMATCH) {
183  // no match, see if match count is in range
184  if (uiMatchCount >= spOp->sRep.uiMin && uiMatchCount <= spOp->sRep.uiMax) {
185  // in range
186  spCtx->uiOpState = ID_MATCH;
187  spCtx->uiOffset = uiOffset + uiPhraseLength;
188  spCtx->uiPhraseLength = uiPhraseLength;
189  } else {
190  // out of range - REP fails
191  spCtx->uiOpState = ID_NOMATCH;
192  spCtx->uiOffset = uiOffset;
193  spCtx->uiPhraseLength = 0;
194  }
195  // all done with repetitions
196  break;
197  } else {
198  // matched phrase, increment the match count and check if done
199  uiMatchCount += 1;
200  uiPhraseLength += spCtx->uiPhraseLength;
201  if (uiMatchCount >= spOp->sRep.uiMax) {
202  // reached max allowed matches, all done
203  spCtx->uiOpState = ID_MATCH;
204  spCtx->uiOffset = uiOffset + uiPhraseLength;
205  spCtx->uiPhraseLength = uiPhraseLength;
206  break;
207  } // else repeat
208  }
209  }
210  PPPT_CLOSE;
211  BKRU_OP_CLOSE(spCtx->vpBkru, spCtx->uiOpState);
212  BKRP_OP_CLOSE(spCtx->vpBkrp, spCtx->uiOpState);
213  AST_OP_CLOSE(spCtx->vpAst, spCtx->uiInLookaround, spCtx->uiOpState);
214  TRACE_UP(spCtx->vpTrace, spOp, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
215  STATS_HIT(spCtx->vpStats, spOp, spCtx->uiOpState);
216  spCtx->uiTreeDepth--;
217 }
218 
219 static void vRnmValidateCallback(parser* spCtx, rule* spRule, aint uiOffset, const char* cpFile, const char* cpFunc,
220  uint32_t uiLine) {
221  aint uiState = spCtx->sCBData.uiCallbackState;
222  if (!(uiState == ID_ACTIVE || uiState == ID_MATCH || uiState == ID_NOMATCH)) {
223  XTHROW(spCtx->spException,
224  "user rule name callback function: returned invalid state");
225  }
226  if (uiState != ID_ACTIVE) {
227  // validate the phrase length & state
228  if ((uiOffset + spCtx->sCBData.uiCallbackPhraseLength) > spCtx->uiSubStringEnd) {
229  XTHROW(spCtx->spException,
230  "user rule name callback function: returned phrase length too long - beyond end of input string");
231  }
232  if ((spRule->uiEmpty == APG_FALSE) && (spCtx->sCBData.uiCallbackState == ID_MATCH)
233  && (spCtx->sCBData.uiCallbackPhraseLength == 0)) {
234  XTHROW(spCtx->spException,
235  "user rule name callback function: returned empty phrase for non-empty rule");
236  }
237  // enforce 0 phrase length on NOMATCH
238  if(uiState == ID_NOMATCH){
239  spCtx->sCBData.uiCallbackPhraseLength = 0;
240  }
241  }
242 }
243 //#define PPPT_FAILED bPpptFailed
244 //#define PPPT_FAILED_DECL abool bPpptFailed = APG_TRUE
245 void vRnm(parser* spCtx, const opcode* spOp) {
246  rule* spRule = spOp->sRnm.spRule;
247  parser_callback pfnCallback = spRule->pfnCallback;
248  aint uiOffset = spCtx->uiOffset;
249  spCtx->sState.uiHitCount++;
250  spCtx->uiTreeDepth++;
251  if(spCtx->uiTreeDepth > spCtx->sState.uiMaxTreeDepth){
252  spCtx->sState.uiMaxTreeDepth = spCtx->uiTreeDepth;
253  }
254  TRACE_DOWN(spCtx->vpTrace, spOp, spCtx->uiOffset);
255  AST_RULE_OPEN(spCtx->vpAst, spCtx->uiInLookaround, spRule->uiRuleIndex, spCtx->uiOffset);
256  BKRU_RULE_OPEN(spCtx->vpBkru, spRule->uiRuleIndex);
257  BKRP_RULE_OPEN(spCtx->vpBkrp, spRule->uiRuleIndex);
258  while (APG_TRUE) {
259  if (pfnCallback) {
260  // have callback for this rule, call it going down the tree
261  spCtx->sCBData.uiCallbackState = ID_ACTIVE;
262  spCtx->sCBData.uiCallbackPhraseLength = 0;
263  spCtx->sCBData.uiParserOffset = uiOffset - spCtx->uiSubStringBeg;
264  spCtx->sCBData.uiParserState = ID_ACTIVE;
265  spCtx->sCBData.uiParserPhraseLength = 0;
266  spCtx->sCBData.uiRuleIndex = spRule->uiRuleIndex;
267  spCtx->sCBData.uiUDTIndex = APG_UNDEFINED;
268  pfnCallback(&spCtx->sCBData);
269  vRnmValidateCallback(spCtx, spRule, uiOffset, __FILE__, __func__, __LINE__);
270  if (spCtx->sCBData.uiCallbackState != ID_ACTIVE) {
271  // accept the callback phrase and quit parsing this node
272  if (spCtx->sCBData.uiCallbackState == ID_EMPTY) {
273  // caller should not return ID_EMPTY but give her a break
274  spCtx->sCBData.uiCallbackState = ID_MATCH;
275  spCtx->sCBData.uiCallbackPhraseLength = 0;
276  }
277  spCtx->uiOpState = spCtx->sCBData.uiCallbackState;
278  spCtx->uiOffset = uiOffset + spCtx->sCBData.uiCallbackPhraseLength;
279  spCtx->uiPhraseLength = spCtx->sCBData.uiCallbackPhraseLength;
280  break;
281  }
282  }
283  // call the child
284  PPPT_OPEN(spCtx, spOp, spCtx->uiOffset);
285  spCtx->uiOpState = ID_ACTIVE;
286  spCtx->pfnOpFunc[spOp->sRnm.spRule->spOp->sGen.uiId](spCtx, spOp->sRnm.spRule->spOp);
287  PPPT_CLOSE;
288 
289  if (pfnCallback) {
290  // have callback for this rule, call it going up the tree
291  spCtx->sCBData.uiCallbackState = ID_ACTIVE;
292  spCtx->sCBData.uiCallbackPhraseLength = 0;
293  spCtx->sCBData.uiParserOffset = uiOffset - spCtx->uiSubStringBeg;
294  spCtx->sCBData.uiParserState = spCtx->uiOpState;
295  spCtx->sCBData.uiParserPhraseLength = spCtx->uiPhraseLength;
296  spCtx->sCBData.uiRuleIndex = spRule->uiRuleIndex;
297  spCtx->sCBData.uiUDTIndex = APG_UNDEFINED;
298  pfnCallback(&spCtx->sCBData);
299  vRnmValidateCallback(spCtx, spRule, uiOffset, __FILE__, __func__, __LINE__);
300  if (spCtx->sCBData.uiCallbackState != ID_ACTIVE) {
301  // accept the callback phrase and quit parsing this node
302  if (spCtx->sCBData.uiCallbackState == ID_EMPTY) {
303  // caller should not return ID_EMPTY but give her a break
304  spCtx->sCBData.uiCallbackState = ID_MATCH;
305  spCtx->sCBData.uiCallbackPhraseLength = 0;
306  }
307  spCtx->uiOpState = spCtx->sCBData.uiCallbackState;
308  spCtx->uiOffset = uiOffset + spCtx->sCBData.uiCallbackPhraseLength;
309  spCtx->uiPhraseLength = spCtx->sCBData.uiCallbackPhraseLength;
310  break;
311  }
312  }
313  break;
314  }
315  BKRU_RULE_CLOSE(spCtx->vpBkru, spRule->uiRuleIndex, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
316  BKRP_RULE_CLOSE(spCtx->vpBkrp, spRule->uiRuleIndex, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
317  AST_RULE_CLOSE(spCtx->vpAst, spCtx->uiInLookaround, spRule->uiRuleIndex, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
318  TRACE_UP(spCtx->vpTrace, spOp, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
319  STATS_HIT(spCtx->vpStats, spOp, spCtx->uiOpState);
320  spCtx->uiTreeDepth--;
321 }
322 
323 void vTrg(parser* spCtx, const opcode* spOp) {
324  spCtx->sState.uiHitCount++;
325  spCtx->uiTreeDepth++;
326  if(spCtx->uiTreeDepth > spCtx->sState.uiMaxTreeDepth){
327  spCtx->sState.uiMaxTreeDepth = spCtx->uiTreeDepth;
328  }
329  TRACE_DOWN(spCtx->vpTrace, spOp, spCtx->uiOffset);
330  PPPT_OPEN(spCtx, spOp, spCtx->uiOffset);
331  spCtx->uiOpState = ID_NOMATCH;
332  spCtx->uiPhraseLength = 0;
333  if (spCtx->uiOffset < spCtx->uiSubStringEnd) {
334  achar aChar = spCtx->acpInputString[spCtx->uiOffset];
335  if (aChar >= spOp->sTrg.acMin && aChar <= spOp->sTrg.acMax) {
336  spCtx->uiOpState = ID_MATCH;
337  spCtx->uiOffset += 1;
338  spCtx->uiPhraseLength = 1;
339  }
340  }
341  PPPT_CLOSE;
342  TRACE_UP(spCtx->vpTrace, spOp, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
343  STATS_HIT(spCtx->vpStats, spOp, spCtx->uiOpState);
344  spCtx->uiTreeDepth--;
345 }
346 
347 void vTls(parser* spCtx, const opcode* spOp) {
348  spCtx->sState.uiHitCount++;
349  spCtx->uiTreeDepth++;
350  if(spCtx->uiTreeDepth > spCtx->sState.uiMaxTreeDepth){
351  spCtx->sState.uiMaxTreeDepth = spCtx->uiTreeDepth;
352  }
353  TRACE_DOWN(spCtx->vpTrace, spOp, spCtx->uiOffset);
354  PPPT_OPEN(spCtx, spOp, spCtx->uiOffset);
355  if (spCtx->uiOffset + spOp->sTls.uiStrLen > spCtx->uiSubStringEnd) {
356  spCtx->uiOpState = ID_NOMATCH;
357  spCtx->uiPhraseLength = 0;
358  } else {
359  const achar* acpInputBeg = &spCtx->acpInputString[spCtx->uiOffset];
360  const achar* acpStrBeg = spOp->sTls.acpStrTbl;
361  const achar* acpStrEnd = spOp->sTls.acpStrTbl + spOp->sTls.uiStrLen;
362  spCtx->uiOpState = ID_MATCH;
363  for (; acpStrBeg < acpStrEnd; acpStrBeg++, acpInputBeg++) {
364  // compare lower case, character by character, TLS string already converted to lower case
365  achar acChar = *acpInputBeg;
366  if (acChar >= (achar) 65 && acChar <= (achar) 90) {
367  acChar += (achar) 32;
368  }
369  if (acChar != *acpStrBeg) {
370  spCtx->uiOpState = ID_NOMATCH;
371  spCtx->uiPhraseLength = 0;
372  break;
373  }
374  }
375  if (spCtx->uiOpState == ID_MATCH) {
376  spCtx->uiOffset += spOp->sTls.uiStrLen;
377  spCtx->uiPhraseLength = spOp->sTls.uiStrLen;
378  }
379  }
380  PPPT_CLOSE;
381  TRACE_UP(spCtx->vpTrace, spOp, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
382  STATS_HIT(spCtx->vpStats, spOp, spCtx->uiOpState);
383  spCtx->uiTreeDepth--;
384 }
385 
386 void vTbs(parser* spCtx, const opcode* spOp) {
387  spCtx->sState.uiHitCount++;
388  spCtx->uiTreeDepth++;
389  if(spCtx->uiTreeDepth > spCtx->sState.uiMaxTreeDepth){
390  spCtx->sState.uiMaxTreeDepth = spCtx->uiTreeDepth;
391  }
392  TRACE_DOWN(spCtx->vpTrace, spOp, spCtx->uiOffset);
393  PPPT_OPEN(spCtx, spOp, spCtx->uiOffset);
394  if (spCtx->uiOffset + spOp->sTbs.uiStrLen > spCtx->uiSubStringEnd) {
395  spCtx->uiOpState = ID_NOMATCH;
396  spCtx->uiPhraseLength = 0;
397  } else {
398  const achar* acpInputBeg = &spCtx->acpInputString[spCtx->uiOffset];
399  const achar* acpStrBeg = spOp->sTbs.acpStrTbl;
400  const achar* acpStrEnd = spOp->sTbs.acpStrTbl + spOp->sTbs.uiStrLen;
401  spCtx->uiOpState = ID_MATCH;
402  for (; acpStrBeg < acpStrEnd; acpStrBeg++, acpInputBeg++) {
403  // compare character by character
404  if (*acpInputBeg != *acpStrBeg) {
405  spCtx->uiOpState = ID_NOMATCH;
406  spCtx->uiPhraseLength = 0;
407  break;
408  }
409  }
410  if (spCtx->uiOpState == ID_MATCH) {
411  spCtx->uiOffset += spOp->sTbs.uiStrLen;
412  spCtx->uiPhraseLength = spOp->sTbs.uiStrLen;
413  }
414  }
415  PPPT_CLOSE;
416  TRACE_UP(spCtx->vpTrace, spOp, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
417  STATS_HIT(spCtx->vpStats, spOp, spCtx->uiOpState);
418  spCtx->uiTreeDepth--;
419 }
420 
lib.h
This header "#include"s all publid lib headers and other standard headers needed by most objects.
backrefp.h
The parent-mode back reference object.
vCat
void vCat(parser *spCtx, const opcode *spOp)
Definition: operators-abnf.c:99
vRnm
void vRnm(parser *spCtx, const opcode *spOp)
Definition: operators-abnf.c:245
parserp.h
Private header for the SABNF parser.
AST_OP_OPEN
#define AST_OP_OPEN(x, l)
Definition: apg.h:255
rule::pfnCallback
parser_callback pfnCallback
Pointer to the call back function for this rule. NULL if the user has not defined a call back functio...
Definition: parserp.h:124
BKRU_OP_CLOSE
#define BKRU_OP_CLOSE(x, s)
Definition: apg.h:219
BKRP_OP_CLOSE
#define BKRP_OP_CLOSE(x, s)
Definition: apg.h:225
STATS_HIT
#define STATS_HIT(x, o, s)
Definition: apg.h:190
achar
uint_fast8_t achar
achar is the type for the parser's alphabet characters.
Definition: apg.h:91
BKRU_RULE_CLOSE
#define BKRU_RULE_CLOSE(x, i, s, o, p)
Definition: apg.h:216
BKRU_RULE_OPEN
#define BKRU_RULE_OPEN(x, i)
Definition: apg.h:215
BKRP_RULE_OPEN
#define BKRP_RULE_OPEN(x, i)
Definition: apg.h:221
ID_EMPTY
#define ID_EMPTY
indicates a matched empty phrase parser state on return from parse tree below this node
Definition: parser.h:75
BKRP_OP_OPEN
#define BKRP_OP_OPEN(x)
Definition: apg.h:224
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
parser_callback
void(* parser_callback)(callback_data *spData)
User-written callback function prototype.
Definition: parser.h:178
BKRP_RULE_CLOSE
#define BKRP_RULE_CLOSE(x, i, s, o, p)
Definition: apg.h:222
rule::uiRuleIndex
aint uiRuleIndex
The rule index - zero-based order in which the rule appears in the SABNF grammar.
Definition: parserp.h:127
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
vTbs
void vTbs(parser *spCtx, const opcode *spOp)
Definition: operators-abnf.c:386
backref.h
Private declarations common to both universal and parent modes.
vTrg
void vTrg(parser *spCtx, const opcode *spOp)
Definition: operators-abnf.c:323
AST_RULE_OPEN
#define AST_RULE_OPEN(x, l, i, o)
Definition: apg.h:253
ID_ACTIVE
#define ID_ACTIVE
indicates active parser state, parser has just entered the node and is moving down the parse tree
Definition: parser.h:72
BKRU_OP_OPEN
#define BKRU_OP_OPEN(x)
Definition: apg.h:218
ID_MATCH
#define ID_MATCH
indicates a matched phrase parser state on return from parse tree below this node
Definition: parser.h:73
vTls
void vTls(parser *spCtx, const opcode *spOp)
Definition: operators-abnf.c:347
APG_UNDEFINED
#define APG_UNDEFINED
Definition: apg.h:318
AST_RULE_CLOSE
#define AST_RULE_CLOSE(x, l, i, s, o, p)
Definition: apg.h:254
AST_OP_CLOSE
#define AST_OP_CLOSE(x, l, s)
Definition: apg.h:256
vRep
void vRep(parser *spCtx, const opcode *spOp)
Definition: operators-abnf.c:148
tracep.h
Private header file for the trace functions.
rule
Data structure for a single rule.
Definition: parserp.h:119
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
vAlt
void vAlt(parser *spCtx, const opcode *spOp)
Definition: operators-abnf.c:66
rule::uiEmpty
aint uiEmpty
APG_TRUE if this rule can be empty, APG_FALSE otherwise.
Definition: parserp.h:126
PPPT_OPEN
#define PPPT_OPEN(x, o, f)
Definition: apg.h:275
ID_NOMATCH
#define ID_NOMATCH
indicates that no phrase was matched on return from parse tree below this node
Definition: parser.h:74
TRACE_DOWN
#define TRACE_DOWN(x, o, f)
Definition: apg.h:167
PPPT_CLOSE
#define PPPT_CLOSE
Definition: apg.h:276
astp.h
Private header file for the AST functions.
backrefu.h
The universal-mode back reference object.
operators.h
Header file for the suite of the parser's operator functions.
statsp.h
Private header file for the statistics gathering functions.
TRACE_UP
#define TRACE_UP(x, o, s, f, p)
Definition: apg.h:168
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.