Version 6.3
Copyright © 2005 - 2012 Lowell D. Thomas
APG
  … ABNF Parser Generator
All Data Structures Files Functions Variables Typedefs Macros Pages
Parser.c
Go to the documentation of this file.
1 /*******************************************************************************
2  APG Version 6.3
3  Copyright (C) 2005 - 2012 Lowell D. Thomas, all rights reserved
4 
5  author: Lowell D. Thomas
6  email: lowell@coasttocoastresearch.com
7  website: http://www.coasttocoastresearch.com
8 
9  This program is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 2 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program. If not, see
21  <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
22  or write to the Free Software Foundation, Inc.,
23  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 *******************************************************************************/
27 #include "Apg.h"
28 #include "Grammar.h"
29 #include "Private.h"
30 
31 // error reporting and handling
32 #undef PASSERT
33 
40 #define PASSERT(cond) if(!(cond)){spCtx->pfnAlertHandler(__LINE__, __FILE__);}
41 
42 // static declarations
43 static apg_uint uiConvertRules(APG_PARSER_CTX* spCtx, G_RULE* spGRules, apg_uint uiCount);
44 static apg_uint uiConvertUdts(APG_PARSER_CTX* spCtx, G_UDT* spGUddts, apg_uint uiCount);
45 static apg_uint uiConvertOpcodes(APG_PARSER_CTX* spCtx, G_OPCODE* spGOpcodes, apg_uint uiCount);
46 static apg_uint uiRunStartRule(APG_PARSER_CTX* spCtx, apg_uint uiStartRule);
47 static apg_uint uiValidate(APG_PARSER_CTX* spCtx);
48 
50 // PARSER COMPONENT FUNCTIONS
52 
58  void* vpParserCtor(void* vpParserInit ,
59  PFN_ALERT pfnAlertHandler
60  ){
61  void* vpReturn = NULL;
62  void* vpMemCtx = NULL;
63  APG_PARSER_CTX* spCtx = NULL;
64  G_HDR* spHdr = (G_HDR*)vpParserInit;
65  apg_uint i, uiTest;
66  G_UINT* g_uipData;
67  char* cpVersion;
68  G_RULE* spGRules;
69  G_UDT* spGUdts;
70  G_OPCODE* spGOpcodes;
71 
72  // set the alert handler - handles all terminal errors
73  if(pfnAlertHandler == NULL){pfnAlertHandler = vDefaultAlertHandler;}
74  if(!spHdr){pfnAlertHandler(__LINE__, __FILE__);}
75 
76  // get the memory context
77  vpMemCtx = vpMemCtor();
78  if(!vpMemCtx){pfnAlertHandler(__LINE__, __FILE__);}
79 
80  // validate the alphabet character width
81  uiTest = sizeof(apg_achar);
82  if(!(uiTest >= spHdr->uiMinSizeofACharMax)){pfnAlertHandler(__LINE__, __FILE__);}
83 
84  // validate the integer width
85  uiTest = sizeof(apg_uint);
86  if(!(uiTest >= spHdr->uiMinSizeofUintMax)){pfnAlertHandler(__LINE__, __FILE__);}
87 
88  // validate the version
89  cpVersion = (char*)vpMemAlloc(vpMemCtx, sizeof(char) * spHdr->uiVersionLen);
90  if(!cpVersion){pfnAlertHandler(__LINE__, __FILE__);}
91  g_uipData = (G_UINT*)spHdr;
92  g_uipData += spHdr->uiVersionOffset;
93  for(i = 0; i < spHdr->uiVersionLen; i++){cpVersion[i] = (char)g_uipData[i];}
94  uiTest = (apg_uint)strcmp(cpVersion, cpApgVersion());
95  vMemFree(vpMemCtx, (void*)cpVersion);
96  if(!(uiTest == 0)){pfnAlertHandler(__LINE__, __FILE__);}
97 
98  // allocate a context
99  spCtx = (APG_PARSER_CTX*)vpMemAlloc(vpMemCtx, (apg_uint)sizeof(APG_PARSER_CTX));
100  if(!spCtx){pfnAlertHandler(__LINE__, __FILE__);}
101  memset((void*)spCtx, 0, sizeof(APG_PARSER_CTX));
102  spCtx->vpMemCtx = vpMemCtx;
103  spCtx->vpValidate = (void*)spCtx;
104  spCtx->pfnAlertHandler = pfnAlertHandler;
105 
106  // string table
107  spCtx->cpCharTable = (char*)vpMemAlloc(spCtx->vpMemCtx, sizeof(char) * spHdr->uiCharTableLen);
108  PASSERT(spCtx->cpCharTable);
109  g_uipData = (G_UINT*)spHdr;
110  g_uipData += spHdr->uiCharTableOffset;
111  for(i = 0; i < spHdr->uiCharTableLen; i++){
112  spCtx->cpCharTable[i] = (char)g_uipData[i];
113  }
114 
115  // achar table
116  spCtx->acpACharTable = (apg_achar*)vpMemAlloc(spCtx->vpMemCtx, sizeof(apg_achar) * spHdr->uiACharTableLen);
117  PASSERT(spCtx->acpACharTable);
118  g_uipData = (G_UINT*)spHdr;
119  g_uipData += spHdr->uiACharTableOffset;
120  for(i = 0; i < spHdr->uiACharTableLen; i++){
121  spCtx->acpACharTable[i] = (apg_achar)g_uipData[i];
122  }
123 
124  // ALT/CAT child list
125  spCtx->uipChildList = (apg_uint*)vpMemAlloc(spCtx->vpMemCtx, sizeof(apg_uint) * spHdr->uiChildListLen);
126  PASSERT(spCtx->uipChildList);
127  g_uipData = (G_UINT*)spHdr;
128  g_uipData += spHdr->uiChildListOffset;
129  for(i = 0; i < spHdr->uiChildListLen; i++){
130  spCtx->uipChildList[i] = (apg_uint)g_uipData[i];
131  }
132 
133  // allocate opcodes
134  spCtx->spOpcodes = (APG_OPCODE*)vpMemAlloc(spCtx->vpMemCtx, sizeof(APG_OPCODE) * spHdr->uiOpcodesLen);
135  PASSERT(spCtx->spOpcodes);
136 
137  // convert rules
138  spCtx->spRules = (APG_RULE*)vpMemAlloc(spCtx->vpMemCtx, sizeof(APG_RULE) * spHdr->uiRulesLen);
139  PASSERT(spCtx->spRules);
140  spCtx->uiRuleCount = spHdr->uiRulesLen;
141  spGRules = (G_RULE*)((G_UINT*)spHdr + spHdr->uiRulesOffset);
142  uiTest = uiConvertRules(spCtx, spGRules, spHdr->uiRulesLen);
143  PASSERT(uiTest);
144 
145  // convert UDTs
146  spCtx->spUdts = (APG_UDT*)vpMemAlloc(spCtx->vpMemCtx, sizeof(APG_UDT) * spHdr->uiUdtsLen);
147  PASSERT(spCtx->spUdts);
148  spCtx->uiUdtCount = spHdr->uiUdtsLen;
149  spGUdts = (G_UDT*)((G_UINT*)spHdr + spHdr->uiUdtsOffset);
150  uiTest = uiConvertUdts(spCtx, spGUdts, spHdr->uiUdtsLen);
151  if(!spCtx->uiUdtCount){spCtx->uiHaveAllUdtCallbacks = APG_TRUE;}
152  PASSERT(uiTest);
153 
154  // convert opcodes
155  spGOpcodes = (G_OPCODE*)((G_UINT*)spHdr + spHdr->uiOpcodesOffset);
156  uiTest = uiConvertOpcodes(spCtx, spGOpcodes, spHdr->uiOpcodesLen);
157  PASSERT(uiTest);
158 
159  // success
160  vpReturn = (void*)spCtx;
161  return vpReturn;
162 }
163 
168 void vParserDtor(void* vpCtx){
169  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
170  if(uiValidate(spCtx)){
171  void* vpMemCtx = spCtx->vpMemCtx;
172  memset((void*)spCtx, 0, sizeof(APG_PARSER_CTX));
173  vMemDtor(vpMemCtx);
174  }
175 }
176 
187 apg_uint uiParserSyntaxInitCallbacks(void* vpCtx, APG_CALLBACK* spRuleCallbacks, APG_CALLBACK* spUdtCallbacks){
188  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
189  apg_uint uiIndex;
190  APG_RULE* spRules = (APG_RULE*)spCtx->spRules;
191  APG_UDT* spUdts = (APG_UDT*)spCtx->spUdts;
192  PASSERT(uiValidate(spCtx));
193  if(spRuleCallbacks){
194  for(uiIndex = 0; uiIndex < spCtx->uiRuleCount; ++uiIndex){spRules[uiIndex].pfnCBSyntax = spRuleCallbacks[uiIndex];}
195  } else{
196  for(uiIndex = 0; uiIndex < spCtx->uiRuleCount; ++uiIndex){spRules[uiIndex].pfnCBSyntax = NULL;}
197  }
198  spCtx->uiHaveAllUdtCallbacks = APG_TRUE;
199  if(spCtx->uiUdtCount){
200  if(spUdtCallbacks){
201  for(uiIndex = 0; uiIndex < spCtx->uiUdtCount; ++uiIndex){
202  if(!spUdtCallbacks[uiIndex]){spCtx->uiHaveAllUdtCallbacks = APG_FALSE;}
203  spUdts[uiIndex].pfnCBSyntax = spUdtCallbacks[uiIndex];
204  }
205  } else{spCtx->uiHaveAllUdtCallbacks = APG_FALSE;}
206  }
207  return spCtx->uiHaveAllUdtCallbacks;
208 }
209 
228 apg_uint uiParserSyntaxAnalysis(void* vpCtx, apg_uint uiStartRule, const apg_achar* acpSrc, apg_uint uiSrcLen, void* vpData)
229 {
230  apg_uint uiReturn = APG_FALSE;
231  apg_uint uiState = PRE_PARSE;
232  apg_uint uiPhraseLength;
233  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
234  PASSERT(uiValidate(spCtx));
235  PASSERT(acpSrc);
236  PASSERT(uiStartRule < spCtx->uiRuleCount);
237  PASSERT(spCtx->uiHaveAllUdtCallbacks);
238 
239  // set up for this parse
240  spCtx->acpInputString = acpSrc;
241  spCtx->uiInputStringLen = uiSrcLen;
242  spCtx->sCBData.vpCtx = (void*)spCtx;
243  spCtx->sCBData.acpSrc = acpSrc;
244  spCtx->sCBData.uiSrcLen = uiSrcLen;
245  spCtx->sCBData.vpUserData = vpData;
246  memset((void*)&spCtx->sState, 0, sizeof(spCtx->sState));
247 
248  vAstClear(spCtx);
249  APG_TRACE(spCtx, NULL, TRACE_ACTION_BEGIN, P_RNM, 0, 0);
250 
251  // run the start rule
252  spCtx->uiStartRule = uiStartRule;
253  uiPhraseLength = uiRunStartRule(spCtx, uiStartRule);
254  if(uiPhraseLength == APG_UNDEFINED){uiState = NOMATCH;}
255  else if(uiPhraseLength == 0){uiState = EMPTY;}
256  else{uiState = MATCH;}
257 
258  // return the parser state
259  spCtx->sState.uiStringLength = spCtx->uiInputStringLen;
260  spCtx->sState.uiState = uiState;
261  spCtx->sState.uiPhraseLength = (uiPhraseLength == APG_UNDEFINED) ? 0: uiPhraseLength;
262  spCtx->sState.uiSuccess = ((uiState != NOMATCH) && (spCtx->sState.uiPhraseLength == spCtx->uiInputStringLen)) ? APG_TRUE: APG_FALSE;
263 
264  APG_TRACE(spCtx, NULL, TRACE_ACTION_END, P_RNM, 0, (spCtx->sState.uiSuccess)?spCtx->uiInputStringLen:APG_UNDEFINED);
265 
266  // success
267  uiReturn = spCtx->sState.uiSuccess;
268  return uiReturn;
269 }
270 
282 // defines AST nodes
283 void vParserAstInitNodes(void* vpCtx, apg_uint* uipRules, apg_uint* uipUdts){
284  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
285  APG_AST_CTX* spAstCtx;
286  apg_uint i;
287  PASSERT(uiValidate(spCtx));
288  vAstDtor(spCtx);
289  vAstCtor(spCtx);
290  spAstCtx = (APG_AST_CTX*)spCtx->vpAstCtx;
291  if(uipRules){
292  for(i = 0; i < spCtx->uiRuleCount; i++){spAstCtx->uipNodes[i] = uipRules[i];}
293  } else{
294  for(i = 0; i < spCtx->uiRuleCount; i++){spAstCtx->uipNodes[i] = APG_FALSE;}
295  }
296  if(spCtx->uiUdtCount){
297  if(uipUdts){
298  for(i = 0; i < spCtx->uiUdtCount; i++){spAstCtx->uipNodes[i + spCtx->uiRuleCount] = uipUdts[i];}
299  } else{
300  for(i = 0; i < spCtx->uiUdtCount; i++){spAstCtx->uipNodes[i + spCtx->uiRuleCount] = APG_FALSE;}
301  }
302  }
303 }
304 
305 // defines AST callbacks
306 // node records will be generated for non-NULL callbacks whether the nodes are defined true/false or not
316 void vParserAstInitCallbacks(void* vpCtx, APG_CALLBACK* pfnRuleCallbacks, APG_CALLBACK* pfnUdtCallbacks){
317  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
318  APG_AST_CTX* spAstCtx;
319  apg_uint i;
320  PASSERT(uiValidate(spCtx));
321  vAstDtor(spCtx);
322  vAstCtor(spCtx);
323  spAstCtx = (APG_AST_CTX*)spCtx->vpAstCtx;
324  APG_CALLBACK pfnTemp;
325  if(pfnRuleCallbacks){
326  for(i = 0; i < spCtx->uiRuleCount; i++){
327  if(pfnRuleCallbacks[i]){spAstCtx->pfnCallbacks[i] = pfnRuleCallbacks[i];}
328  else{spAstCtx->pfnCallbacks[i] = NULL;}
329  pfnTemp = spAstCtx->pfnCallbacks[i];
330  }
331  }
332  if(spCtx->uiUdtCount && pfnUdtCallbacks){
333  for(i = 0; i < spCtx->uiUdtCount; i++){
334  if(pfnUdtCallbacks[i]){spAstCtx->pfnCallbacks[i + spCtx->uiRuleCount] = pfnUdtCallbacks[i];}
335  else{spAstCtx->pfnCallbacks[i + spCtx->uiRuleCount] = NULL;}
336  pfnTemp = spAstCtx->pfnCallbacks[i + spCtx->uiRuleCount];
337  }
338  }
339 }
340 
341 // void vParserAstTraslation(void* vpCtx, void* vpData);
361 apg_uint uiParserAstTranslate(void* vpCtx, APG_CALLBACK* pfnRuleCallbacks, APG_CALLBACK* pfnUdtCallbacks, void* vpData){
362  apg_uint uiRet = 0;
363  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
364  PASSERT(uiValidate(spCtx));
365  if(spCtx->vpAstCtx){
366  spCtx->sCBData.vpUserData = vpData;
367  uiRet = uiAstTraverse((APG_AST_CTX*)spCtx->vpAstCtx, pfnRuleCallbacks, pfnUdtCallbacks, &spCtx->sCBData);
368  }
369  return uiRet;
370 }
371 
379 apg_uint uiParserState(void* vpCtx, APG_PARSER_STATE* spState){
380  apg_uint uiRet = APG_FALSE;
381  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
382  PASSERT(uiValidate(spCtx));
383  if(spState){
384  *spState = spCtx->sState;
385  uiRet = spState->uiSuccess;
386  }
387  return uiRet;
388 }
389 
403 apg_uint uiParserStatsEnable(void* vpCtx, apg_uint uiEnable){
404  apg_uint uiRet = APG_FALSE;
405  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
406  PASSERT(uiValidate(spCtx));
407  if(uiEnable){APG_STATS_ADMIN(spCtx, STATS_ACTION_ENABLE, NULL, 0, &uiRet);}
408  else{APG_STATS_ADMIN(spCtx, STATS_ACTION_DISABLE, NULL, 0, &uiRet);}
409  return uiRet;
410 }
411 
422 apg_uint uiParserStatsGet(void* vpCtx, APG_PARSER_STATS* spStats, apg_uint* uipBufferSize){
423  apg_uint uiRet = APG_FALSE;
424  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
425  PASSERT(uiValidate(spCtx));
426  APG_STATS_ADMIN(spCtx, STATS_ACTION_GETSTATS, (void*)spStats, uipBufferSize, &uiRet);
427  return uiRet;
428 }
429 
452 apg_uint uiParserTraceEnable(void* vpCtx, apg_uint uiEnable){
453  apg_uint uiRet = APG_FALSE;
454  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
455  PASSERT(uiValidate(spCtx));
456  if(uiEnable){APG_TRACE_ADMIN(spCtx, TRACE_ACTION_ENABLE, 0, 0, &uiRet);}
457  else{APG_TRACE_ADMIN(spCtx, TRACE_ACTION_DISABLE, 0, 0, &uiRet);}
458  return uiRet;
459 }
460 
482 void vParserTraceOp(void* vpCtx, apg_uint uiOpId, apg_uint uiEnable){
483  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
484  PASSERT(uiValidate(spCtx));
485  APG_TRACE_ADMIN(spCtx, TRACE_ACTION_OP, uiOpId, uiEnable, NULL);
486 }
487 
495 void vParserTraceRule(void* vpCtx, apg_uint uiIndex, apg_uint uiEnable){
496  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
497  PASSERT(uiValidate(spCtx));
498  APG_TRACE_ADMIN(spCtx, TRACE_ACTION_RULE, uiIndex, uiEnable, NULL);
499 }
500 
508 void vParserTraceUdt(void* vpCtx, apg_uint uiIndex, apg_uint uiEnable){
509  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
510  PASSERT(uiValidate(spCtx));
511  APG_TRACE_ADMIN(spCtx, TRACE_ACTION_UDT, uiIndex, uiEnable, NULL);
512 }
513 
524 void vParserTraceRange(void* vpCtx, apg_uint uiBegin, apg_uint uiCount){
525  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)vpCtx;
526  PASSERT(uiValidate(spCtx));
527  APG_TRACE_ADMIN(spCtx, TRACE_ACTION_RANGE, uiBegin, uiCount, NULL);
528 }
529 
537 void vExecuteRule(APG_CBDATA* spData, apg_uint uiId, apg_uint uiOffset){
538  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)spData->vpCtx;
539  APG_OPCODE sOp;
540  PASSERT(uiId < spCtx->uiRuleCount);
541  PASSERT(uiOffset < spData->uiSrcLen);
542 
543  // create a dummy RNM opcode
544  sOp.pfnOp = uiRNM;
545  sOp.sUnion.sRnm.spRule = &spCtx->spRules[uiId];
546  sOp.sUnion.sRnm.spNext = sOp.sUnion.sRnm.spRule->spOp;
547 
548  // execute the start rule
549  spData->uiPhraseLength = sOp.pfnOp(spCtx, &sOp, uiOffset);
550 }
551 
559 void vExecuteUdt(APG_CBDATA* spData, apg_uint uiId, apg_uint uiOffset){
560  APG_PARSER_CTX* spCtx = (APG_PARSER_CTX*)spData->vpCtx;
561  APG_OPCODE sOp;
562  PASSERT(uiId < spCtx->uiUdtCount);
563  PASSERT(uiOffset < spData->uiSrcLen);
564 
565  // create a dummy UDT opcode
566  sOp.pfnOp = uiUDT;
567  sOp.sUnion.sUdt.spUdt = &spCtx->spUdts[uiId];
568  sOp.sUnion.sUdt.uiEmpty = spCtx->spUdts[uiId].uiEmpty;
569 
570  // execute the start rule
571  spData->uiPhraseLength = sOp.pfnOp(spCtx, &sOp, uiOffset);
572 }
573 
575 // STATIC HELPER FUNCTIONS
577 static apg_uint uiConvertRules(APG_PARSER_CTX* spCtx, G_RULE* spGRules, apg_uint uiCount){
578  apg_uint uiReturn = APG_FALSE;
579  G_RULE* spGRule = spGRules;
580  APG_RULE* spRule = spCtx->spRules;
581  APG_RULE* spRuleEnd = spRule + uiCount;
582  apg_uint uiIndex = 0;
583  for(; spRule < spRuleEnd; spRule++, spGRule++, uiIndex++){
584  spRule->cpRuleName = spCtx->cpCharTable + spGRule->uiNameOffset;
585  spRule->pfnCBSyntax = NULL;
586  spRule->spOp = spCtx->spOpcodes + spGRule->uiChildOffset;
587  spRule->uiOpcodeCount = (apg_uint)spGRule->uiChildCount;
588  spRule->uiRuleIndex = uiIndex;
589  }
590  uiReturn = APG_TRUE;
591  return uiReturn;
592 }
593 
594 static apg_uint uiConvertUdts(APG_PARSER_CTX* spCtx, G_UDT* spGUdts, apg_uint uiCount){
595  apg_uint uiReturn = APG_FALSE;
596  G_UDT* spGUdt = spGUdts;
597  APG_UDT* spUdt = spCtx->spUdts;
598  APG_UDT* spUdtEnd = spUdt + uiCount;
599  apg_uint uiIndex = 0;
600  for(; spUdt < spUdtEnd; spUdt++, spGUdt++, uiIndex++){
601  spUdt->cpUdtName = spCtx->cpCharTable + spGUdt->uiNameOffset;
602  spUdt->pfnCBSyntax = NULL;
603  spUdt->uiEmpty = (apg_uint)spGUdt->uiEmpty;
604  spUdt->uiUdtIndex = uiIndex;
605  }
606  uiReturn = APG_TRUE;
607  return uiReturn;
608 }
609 
610 static apg_uint uiConvertOpcodes(APG_PARSER_CTX* spCtx, G_OPCODE* spGOpcodes, apg_uint uiCount){
611  apg_uint uiReturn = APG_FALSE;
612  G_OPCODE* spGOp = spGOpcodes;
613  APG_OPCODE* spOp = spCtx->spOpcodes;
614  APG_OPCODE* spOpEnd = spCtx->spOpcodes + uiCount;
615  for(; spOp < spOpEnd; spOp++, spGOp++){
616 // switch(spGOp->sOpType.sRnm.uiType){
617  switch(spGOp->uiType){
618  case G_TYPE_RNM:
619  {
620  G_RNMOP* spG = &spGOp->sOpType.sRnm;
621  APG_OP_RNM* spP = &spOp->sUnion.sRnm;
622  spOp->pfnOp = uiRNM;
623  spP->spRule = spCtx->spRules + spG->uiRuleIndex;
624  spP->spNext = spP->spRule->spOp;
625  spOp->cpName = "G_TYPE_RNM";
626  }
627  break;
628  case G_TYPE_UDT:
629  {
630  G_UDTOP* spG = &spGOp->sOpType.sUdt;
631  APG_OP_UDT* spP = &spOp->sUnion.sUdt;
632  spOp->pfnOp = uiUDT;
633  spP->spUdt = spCtx->spUdts + spG->uiUdtIndex;
634  spP->uiEmpty = (apg_uint)spG->uiEmpty;
635 
636  spOp->cpName = "G_TYPE_UDT";
637  }
638  break;
639  case G_TYPE_REP:
640  {
641  G_REPOP* spG = &spGOp->sOpType.sRep;
642  APG_OP_REP* spP = &spOp->sUnion.sRep;
643  spOp->pfnOp = uiREP;
644  spP->spNext = spCtx->spOpcodes + spG->uiChildOffset;
645  spP->uiMin = (apg_uint)spG->uiMin;
646  spP->uiMax = (apg_uint)spG->uiMax;
647  spOp->cpName = "G_TYPE_REP";
648  }
649  break;
650  case G_TYPE_ALT:
651  {
652  G_ALTOP* spG = &spGOp->sOpType.sAlt;
653  APG_OP_ALT* spP = &spOp->sUnion.sAlt;
654  spOp->pfnOp = uiALT;
655  spP->uipChildList = (apg_uint*)(spCtx->uipChildList + spG->uiChildListOffset);
656  spP->uiChildCount = (apg_uint)spG->uiChildCount;
657  spOp->cpName = "G_TYPE_ALT";
658  }
659  break;
660  case G_TYPE_CAT:
661  {
662  G_CATOP* spG = &spGOp->sOpType.sCat;
663  APG_OP_CAT* spP = &spOp->sUnion.sCat;
664  spOp->pfnOp = uiCAT;
665  spP->uipChildList = (apg_uint*)(spCtx->uipChildList + spG->uiChildListOffset);
666  spP->uiChildCount = (apg_uint)spG->uiChildCount;
667  spOp->cpName = "G_TYPE_CAT";
668  }
669  break;
670  case G_TYPE_AND:
671  {
672  G_ANDOP* spG = &spGOp->sOpType.sAnd;
673  APG_OP_AND* spP = &spOp->sUnion.sAnd;
674  spOp->pfnOp = uiAND;
675  spP->spNext = spCtx->spOpcodes + spG->uiChildOffset;
676  spOp->cpName = "G_TYPE_AND";
677  }
678  break;
679  case G_TYPE_NOT:
680  {
681  G_NOTOP* spG = &spGOp->sOpType.sNot;
682  APG_OP_NOT* spP = &spOp->sUnion.sNot;
683  spOp->pfnOp = uiNOT;
684  spP->spNext = spCtx->spOpcodes + spG->uiChildOffset;
685  spOp->cpName = "G_TYPE_NOT";
686  }
687  break;
688  case G_TYPE_TRG:
689  {
690  G_TRGOP* spG = &spGOp->sOpType.sTrg;
691  APG_OP_TRG* spP = &spOp->sUnion.sTrg;
692  spOp->pfnOp = uiTRG;
693  spP->acMin = (apg_achar)spG->uiMin;
694  spP->acMax = (apg_achar)spG->uiMax;
695  spOp->cpName = "G_TYPE_TRG";
696  }
697  break;
698  case G_TYPE_TBS:
699  {
700  G_TBSOP* spG = &spGOp->sOpType.sTbs;
701  APG_OP_TBS* spP = &spOp->sUnion.sTbs;
702  spOp->pfnOp = uiTBS;
703  spP->acpStrTbl= spCtx->acpACharTable + spG->uiOffset;
704  spP->uiStrLen = (apg_uint)spG->uiLen;
705  spOp->cpName = "G_TYPE_TBS";
706  }
707  break;
708  case G_TYPE_TLS:
709  {
710  apg_achar* acpBeg;
711  apg_achar* acpEnd;
712  G_TLSOP* spG = &spGOp->sOpType.sTls;
713  APG_OP_TLS* spP = &spOp->sUnion.sTls;
714  spOp->pfnOp = uiTLS;
715  spP->acpStrTbl = spCtx->acpACharTable + spG->uiOffset;
716  spP->uiStrLen = spG->uiLen;
717  acpBeg = spP->acpStrTbl;
718  acpEnd = acpBeg + spP->uiStrLen;
719  for(; acpBeg < acpEnd; acpBeg++){ // convert string to lower
720  if(*acpBeg >= (apg_achar)65 && *acpBeg <= (apg_achar)90){*acpBeg += (apg_achar)32;}
721  }
722  spOp->cpName = "G_TYPE_TLS";
723  }
724  break;
725  default:
727  break;
728  }
729  }
730  uiReturn = APG_TRUE;
731  return uiReturn;
732 }
733 
734 static apg_uint uiRunStartRule(APG_PARSER_CTX* spCtx, apg_uint uiStartRule){
735  apg_uint uiRet;
736  APG_OPCODE sOp;
737  PASSERT(uiStartRule < spCtx->uiRuleCount);
738  PASSERT(spCtx);
739 
740  // create a dummy RNM opcode
741  sOp.pfnOp = uiRNM;
742  sOp.sUnion.sRnm.spRule = &spCtx->spRules[uiStartRule];
743  sOp.sUnion.sRnm.spNext = sOp.sUnion.sRnm.spRule->spOp;
744 
745  // execute the start rule
746  uiRet = sOp.pfnOp(spCtx, &sOp, 0);
747  return uiRet;
748 }
749 
750 static apg_uint uiValidate(APG_PARSER_CTX* spCtx){
751  return (spCtx && spCtx->vpValidate == (void*)spCtx);
752 }
vParserTraceOp
void vParserTraceOp(void *vpCtx, apg_uint uiOpId, apg_uint uiEnable)
Definition: Parser.c:482
vpParserCtor
void * vpParserCtor(void *vpParserInit, PFN_ALERT pfnAlertHandler)
Definition: Parser.c:58
APG_PARSER_STATS
full set of statistics gathered during parsing, uiParserSyntaxAnalysis()
Definition: Apg.h:591
vMemDtor
void vMemDtor(void *vpCtx)
Definition: Memory.c:97
PASSERT
#define PASSERT(cond)
Definition: Parser.c:40
APG_PARSER_STATE
the state of the parser after parsing an input string.
Definition: Apg.h:561
vParserTraceRange
void vParserTraceRange(void *vpCtx, apg_uint uiBegin, apg_uint uiCount)
Definition: Parser.c:524
vDefaultAlertHandler
void vDefaultAlertHandler(unsigned int uiLine, const char *cpFile)
Definition: Tools.c:33
vExecuteRule
void vExecuteRule(APG_CBDATA *spData, apg_uint uiId, apg_uint uiOffset)
Definition: Parser.c:537
vExecuteUdt
void vExecuteUdt(APG_CBDATA *spData, apg_uint uiId, apg_uint uiOffset)
Definition: Parser.c:559
apg_uint
unsigned int apg_uint
Definition: Apg.h:169
APG_CALLBACK
apg_uint(* APG_CALLBACK)(APG_CBDATA *spData)
Definition: Apg.h:515
uiParserSyntaxAnalysis
apg_uint uiParserSyntaxAnalysis(void *vpCtx, apg_uint uiStartRule, const apg_achar *acpSrc, apg_uint uiSrcLen, void *vpData)
Definition: Parser.c:228
vParserTraceUdt
void vParserTraceUdt(void *vpCtx, apg_uint uiIndex, apg_uint uiEnable)
Definition: Parser.c:508
uiParserTraceEnable
apg_uint uiParserTraceEnable(void *vpCtx, apg_uint uiEnable)
Definition: Parser.c:452
vpMemCtor
void * vpMemCtor()
Definition: Memory.c:77
PFN_ALERT
void(* PFN_ALERT)(unsigned int uiLine, const char *cpFile)
Definition: Apg.h:276
vMemFree
void vMemFree(void *vpCtx, void *vpData)
Definition: Memory.c:157
vParserTraceRule
void vParserTraceRule(void *vpCtx, apg_uint uiIndex, apg_uint uiEnable)
Definition: Parser.c:495
vpMemAlloc
void * vpMemAlloc(void *vpCtx, apg_uint uiBytes)
Definition: Memory.c:130
PRE_PARSE
#define PRE_PARSE
Definition: Apg.h:526
Apg.h
Required header file for all APG-generated parsers. Contains important configuration macros and decla...
APG_CBDATA::uiPhraseLength
apg_uint uiPhraseLength
Definition: Apg.h:459
EMPTY
#define EMPTY
Definition: Apg.h:538
APG_TRUE
#define APG_TRUE
Definition: Apg.h:187
uiParserState
apg_uint uiParserState(void *vpCtx, APG_PARSER_STATE *spState)
Definition: Parser.c:379
APG_CBDATA::vpCtx
void * vpCtx
Definition: Apg.h:454
apg_achar
unsigned char apg_achar
Definition: Apg.h:183
vParserAstInitNodes
void vParserAstInitNodes(void *vpCtx, apg_uint *uipRules, apg_uint *uipUdts)
Definition: Parser.c:283
uiParserStatsGet
apg_uint uiParserStatsGet(void *vpCtx, APG_PARSER_STATS *spStats, apg_uint *uipBufferSize)
Definition: Parser.c:422
APG_CBDATA
The data structure passed to all syntax and AST callback functions, both rule and UDT.
Definition: Apg.h:453
uiParserStatsEnable
apg_uint uiParserStatsEnable(void *vpCtx, apg_uint uiEnable)
Definition: Parser.c:403
APG_UNDEFINED
#define APG_UNDEFINED
Definition: Apg.h:194
MATCH
#define MATCH
Definition: Apg.h:544
APG_FALSE
#define APG_FALSE
Definition: Apg.h:190
uiParserAstTranslate
apg_uint uiParserAstTranslate(void *vpCtx, APG_CALLBACK *pfnRuleCallbacks, APG_CALLBACK *pfnUdtCallbacks, void *vpData)
Definition: Parser.c:361
vParserDtor
void vParserDtor(void *vpCtx)
Definition: Parser.c:168
vParserAstInitCallbacks
void vParserAstInitCallbacks(void *vpCtx, APG_CALLBACK *pfnRuleCallbacks, APG_CALLBACK *pfnUdtCallbacks)
Definition: Parser.c:316
uiParserSyntaxInitCallbacks
apg_uint uiParserSyntaxInitCallbacks(void *vpCtx, APG_CALLBACK *spRuleCallbacks, APG_CALLBACK *spUdtCallbacks)
Definition: Parser.c:187
NOMATCH
#define NOMATCH
Definition: Apg.h:532
APG_PARSER_STATE::uiSuccess
apg_uint uiSuccess
Definition: Apg.h:562
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/licenses.html or write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.