Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
operators-bkr.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 * *************************************************************************************/
36 #include "./apg.h"
37 #ifdef APG_BKR
38 #include "./lib.h"
39 #include "./parserp.h"
40 #include "./astp.h"
41 #include "./tracep.h"
42 #include "./statsp.h"
43 #include "./operators.h"
44 #include "./backref.h"
45 #include "./backrefu.h"
46 #include "./backrefp.h"
47 
48 static aint uiIMatch(parser* spCtx, aint uiOffset, aint uiPhraseOffset, aint uiPhraseLength);
49 static aint uiSMatch(parser* spCtx, aint uiOffset, aint uiPhraseOffset, aint uiPhraseLength);
50 
51 void vBkr(parser* spCtx, const opcode* spOp) {
52  spCtx->sState.uiHitCount++;
53  spCtx->uiTreeDepth++;
54  if(spCtx->uiTreeDepth > spCtx->sState.uiMaxTreeDepth){
55  spCtx->sState.uiMaxTreeDepth = spCtx->uiTreeDepth;
56  }
57  TRACE_DOWN(spCtx->vpTrace, spOp, spCtx->uiOffset);
58  aint uiState = ID_NOMATCH;
59  aint uiPhraseLength = 0;
60  bkr_phrase sPhrase = {};
61  if (spOp->sBkr.uiMode == ID_BKR_MODE_U) {
62  sPhrase = sBkruFetch(spCtx->vpBkru, spOp->sBkr.uiRuleIndex);
63  } else if (spOp->sBkr.uiMode == ID_BKR_MODE_P) {
64  sPhrase = sBkrpFetch(spCtx->vpBkrp, spOp->sBkr.uiRuleIndex);
65  } else {
66  XTHROW(spCtx->spException,
67  "back reference mode must be ID_BKR_MODE_U or ID_BKR_MODE_P");
68  }
69  if (spOp->sBkr.uiCase == ID_BKR_CASE_I) {
70  uiState = uiIMatch(spCtx, spCtx->uiOffset, sPhrase.uiPhraseOffset, sPhrase.uiPhraseLength);
71  } else if (spOp->sBkr.uiCase == ID_BKR_CASE_S) {
72  uiState = uiSMatch(spCtx, spCtx->uiOffset, sPhrase.uiPhraseOffset, sPhrase.uiPhraseLength);
73  } else {
74  XTHROW(spCtx->spException,
75  "back reference case must be ID_BKR_CASE_I or ID_BKR_CASE_S");
76  }
77  uiPhraseLength = uiState == ID_MATCH ? sPhrase.uiPhraseLength : 0;
78  spCtx->uiOpState = uiState;
79  spCtx->uiPhraseLength = uiPhraseLength;
80  spCtx->uiOffset += uiPhraseLength;
81  TRACE_UP(spCtx->vpTrace, spOp, spCtx->uiOpState, (spCtx->uiOffset - spCtx->uiPhraseLength), spCtx->uiPhraseLength);
82  STATS_HIT(spCtx->vpStats, spOp, spCtx->uiOpState);
83  spCtx->uiTreeDepth--;
84 }
85 
86 static aint uiIMatch(parser* spCtx, aint uiOffset, aint uiPhraseOffset, aint uiPhraseLength) {
87  if (uiOffset + uiPhraseLength > spCtx->uiSubStringEnd) {
88  return ID_NOMATCH;
89  }
90  const achar* acpInputBeg = &spCtx->acpInputString[uiOffset];
91  const achar* acpPhraseBeg = &spCtx->acpInputString[uiPhraseOffset];
92  const achar* acpPhraseEnd = acpPhraseBeg + uiPhraseLength;
93  for (; acpPhraseBeg < acpPhraseEnd; acpPhraseBeg++, acpInputBeg++) {
94  // compare lower case, character by character
95  achar acInput = *acpInputBeg;
96  achar acPhrase = *acpPhraseBeg;
97  if (acInput >= (achar) 65 && acInput <= (achar) 90) {
98  acInput += (achar) 32;
99  }
100  if (acPhrase >= (achar) 65 && acPhrase <= (achar) 90) {
101  acPhrase += (achar) 32;
102  }
103  if (acInput != acPhrase) {
104  return ID_NOMATCH;
105  }
106  }
107  return ID_MATCH;
108 }
109 static aint uiSMatch(parser* spCtx, aint uiOffset, aint uiPhraseOffset, aint uiPhraseLength) {
110  if (uiOffset + uiPhraseLength > spCtx->uiSubStringEnd) {
111  return ID_NOMATCH;
112  }
113  const achar* acpInputBeg = &spCtx->acpInputString[uiOffset];
114  const achar* acpPhraseBeg = &spCtx->acpInputString[uiPhraseOffset];
115  const achar* acpPhraseEnd = acpPhraseBeg + uiPhraseLength;
116  for (; acpPhraseBeg < acpPhraseEnd; acpPhraseBeg++, acpInputBeg++) {
117  if (*acpInputBeg != *acpPhraseBeg) {
118  return ID_NOMATCH;
119  }
120  }
121  return ID_MATCH;
122 }
123 #endif /*APG_BKR*/
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.
ID_BKR_CASE_I
#define ID_BKR_CASE_I
the back reference is case insensitive
Definition: parser.h:121
apg.h
The APG header file.
parserp.h
Private header for the SABNF parser.
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
bkr_phrase::uiPhraseOffset
aint uiPhraseOffset
The offset to the matched phrase.
Definition: backref.h:64
ID_BKR_CASE_S
#define ID_BKR_CASE_S
the back reference is case sensitive
Definition: parser.h:120
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
backref.h
Private declarations common to both universal and parent modes.
bkr_phrase::uiPhraseLength
aint uiPhraseLength
The matched phrase length.
Definition: backref.h:65
ID_MATCH
#define ID_MATCH
indicates a matched phrase parser state on return from parse tree below this node
Definition: parser.h:73
tracep.h
Private header file for the trace functions.
vBkr
void vBkr(parser *spCtx, const opcode *spOp)
Definition: operators-bkr.c:51
bkr_phrase
Defines one frame on the back reference stack.
Definition: backref.h:63
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
astp.h
Private header file for the AST functions.
sBkrpFetch
bkr_phrase sBkrpFetch(void *vpCtx, aint uiIndex)
Definition: backrefp.c:326
sBkruFetch
bkr_phrase sBkruFetch(void *vpCtx, aint uiIndex)
Definition: backrefu.c:358
backrefu.h
The universal-mode back reference object.
ID_BKR_MODE_U
#define ID_BKR_MODE_U
the back reference is universal mode
Definition: parser.h:118
operators.h
Header file for the suite of the parser's operator functions.
statsp.h
Private header file for the statistics gathering functions.
ID_BKR_MODE_P
#define ID_BKR_MODE_P
the back reference is parent mode
Definition: parser.h:119
TRACE_UP
#define TRACE_UP(x, o, s, f, p)
Definition: apg.h:168
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.