Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
|
Go to the documentation of this file.
39 #ifdef SEMANTICS_DEBUG
47 #include "../utilities/utilities.h"
58 static abool bLCCompare(
const char* cpL,
aint uiLLen,
const char* cpR,
aint uiRLen);
59 static void vPpptSize(
api* spApi);
70 memset((
void*) &sData, 0,
sizeof(sData));
75 "attempted opcodes phase but input grammar not validated");
79 "attempted opcodes phase but syntax not validated");
83 "attempted opcodes phase but opcodes have already been constructed and validated");
87 sData.vpMem = spApi->
vpMem;
89 sData.vpVecAcharsTable =
vpVecCtor(sData.vpMem,
sizeof(
luint), 1000);
90 sData.vpVecChildIndexTable =
vpVecCtor(sData.vpMem,
sizeof(
aint), 1000);
91 sData.vpVecStringTable =
vpVecCtor(sData.vpMem,
sizeof(
char), 1000);
100 vGenerateUdtList(spApi, &sData);
103 vValidateRnmOps(spApi, &sData);
104 vValidateBkrOps(spApi, &sData);
107 vStringTable(spApi, &sData);
111 #ifdef SEMANTICS_DEBUG
112 vPrintSemanticOpcodes(spApi, &sData);
113 vReduceOpcodes(spApi, &sData);
116 vPrintGeneratedOpcodes(spApi);
118 vReduceOpcodes(spApi, &sData);
127 vVecDtor(sData.vpVecChildIndexTable);
132 if(!spRules || !uiRules){
133 XTHROW(spApi->spException,
"no rule names found");
135 for(; ui < uiRules; ui++){
136 vVecDtor(spRules[ui].vpVecAltStack);
137 vVecDtor(spRules[ui].vpVecCatStack);
141 for(; spOp <= spOpEnd; spOp++){
162 for(ui = 0; ui < uiRuleCount; ui++){
174 for(ui = 0; ui < uiUdtCount; ui++){
184 static abool bLCCompare(
const char* cpL,
aint uiLLen,
const char* cpR,
aint uiRLen) {
185 if (uiLLen == uiRLen) {
189 if (l >= 65 && l <= 90) {
193 if (r >= 65 && r <= 90) {
236 memset((
void*) spApi->
cpStringTable, 0, (
sizeof(
char) * uiSize));
262 for (ui = 0; ui < spApi->
uiRuleCount; ui++, spRule++) {
263 memcpy(cpNext, spSemRules[ui].cpName, spSemRules[ui].uiNameLength);
271 for (ui = 0; ui < spApi->
uiUdtCount; ui++, spUdt++) {
272 memcpy(cpNext, spSemUdts[ui].cpName, spSemUdts[ui].uiNameLength);
315 for (ui = 0; ui < uiRuleCount; ui++) {
318 snprintf(caBuf,
BUF_SIZE,
"rule %"PRIuMAX
" has no opcodes", (
luint) ui);
321 uiOpCount =
uiVecLen(spRules[ui].vpVecOps);
322 for (uii = 0; uii < uiOpCount; uii++) {
374 for (ui = 0; ui < uiRuleCount; ui++) {
377 snprintf(caBuf,
BUF_SIZE,
"rule %"PRIuMAX
" has no opcodes", (
luint) ui);
380 uiOpCount =
uiVecLen(spRules[ui].vpVecOps);
381 for (uii = 0; uii < uiOpCount; uii++) {
391 snprintf(caMsg, 256,
"rule name \"%s\" not found", caName);
392 vLineError(spApi, uiIndex,
"invalid RNM", caMsg);
421 for (ui = 0; ui < uiRuleCount; ui++) {
424 snprintf(caBuf,
BUF_SIZE,
"rule %"PRIuMAX
" has no opcodes", (
luint) ui);
427 uiOpCount =
uiVecLen(spRules[ui].vpVecOps);
428 for (uii = 0; uii < uiOpCount; uii++) {
440 snprintf(caMsg, 256,
"back reference rule or UDT name, \"%s\", not found", caName);
441 vLineError(spApi, uiIndex,
"invalid BKR", caMsg);
457 aint uiSeq, uiLen, uiOpcodes, uiOffset;
471 aint* uipChildIndexTable;
491 for (; spRule <= spRuleEnd; spRule++) {
494 for (uiSeq = 0; spOp <= spOpEnd; spOp++) {
501 spOp->
uiSeq = uiSeq++;
509 spOp->
uiSeq = uiSeq++;
512 spOp->
uiSeq = uiSeq++;
519 for (; spRule <= spRuleEnd; spRule++) {
522 for (; spOp <= spOpEnd; spOp++) {
531 for (; uipIndex <= uipIndexEnd; uipIndex++) {
536 *uipIndex = spOpChild->
uiSeq;
549 for (; spRule <= spRuleEnd; spRule++) {
552 for (; spOp <= spOpEnd; spOp++) {
580 for (; spRule <= spRuleEnd; spRule++, spApiRule++) {
584 for (; spOp <= spOpEnd; spOp++) {
587 switch (spOp->
uiId) {
594 *uipChildIndexTable++ = uiOffset + *uipBeg++;
636 uiOffset += uiOpcodes;
641 static void vPpptSize(
api* spApi){
703 switch (spOp->
uiId) {
735 luint luiTemp, luiTest;
756 if(luiTest >= luiTemp){
768 #ifdef SEMANTICS_DEBUG
781 printf(
"RAW OPCODES:\n");
782 for (ui = 0; ui < uiRuleCount; ui++) {
783 spRule = &spRules[ui];
786 printf(
"rule: %"PRIuMAX
": %s\n", (
luint) ui, caName);
789 for (uj = 0; uj < uiOpCount; uj++) {
794 switch (spOp->
uiId) {
798 printf(
"%"PRIuMAX
": ", (
luint) uj);
800 printf(
"children: %"PRIuMAX
":", (
luint) uiCount);
801 for (uk = 0; uk < uiCount; uk++, uipBeg++) {
803 printf(
" %"PRIuMAX
"", (
luint) *uipBeg);
805 printf(
", %"PRIuMAX
"", (
luint) *uipBeg);
814 printf(
"%"PRIuMAX
": ", (
luint) uj);
816 printf(
"children: %"PRIuMAX
":", (
luint) uiCount);
817 for (uk = 0; uk < uiCount; uk++, uipBeg++) {
819 printf(
" %"PRIuMAX
"", (
luint) *uipBeg);
821 printf(
", %"PRIuMAX
"", (
luint) *uipBeg);
828 printf(
"%"PRIuMAX
": ", (
luint) uj);
830 printf(
"min: %"PRIuMAX
": ", spOp->
luiMin);
832 printf(
"max: infinity");
834 printf(
"max: %"PRIuMAX
"", spOp->
luiMax);
841 printf(
"%"PRIuMAX
": ", (
luint) uj);
843 printf(
"%s", caName);
847 printf(
"%"PRIuMAX
": ", (
luint) uj);
852 for (uk = 0; uk < uiCount; uk++, luipBeg++) {
853 if (*luipBeg >= 32 && *luipBeg <= 126) {
854 printf(
"%c", (
char) *luipBeg);
856 printf(
"0x%.2lX", *luipBeg);
862 printf(
"%"PRIuMAX
": ", (
luint) uj);
867 for (uk = 0; uk < uiCount; uk++, luipBeg++) {
868 printf(
"%c", (
char) *luipBeg);
873 printf(
"%"PRIuMAX
": ", (
luint) uj);
875 printf(
"min: %"PRIuMAX
": ", spOp->
luiMin);
876 printf(
"max: %"PRIuMAX
"", spOp->
luiMax);
880 printf(
"%"PRIuMAX
": ", (
luint) uj);
884 printf(
"%s", caName);
888 printf(
"%"PRIuMAX
": ", (
luint) uj);
893 printf(
"%"PRIuMAX
": ", (
luint) uj);
898 printf(
"%"PRIuMAX
": ", (
luint) uj);
903 printf(
"%"PRIuMAX
": ", (
luint) uj);
908 printf(
"%"PRIuMAX
": ", (
luint) uj);
922 printf(
"%s", caName);
926 printf(
"%"PRIuMAX
": ", (
luint) uj);
931 printf(
"%"PRIuMAX
": ", (
luint) uj);
aint uiUdtCount
The number of UDTs referenced in the SABNF grammar.
abool bApiValidate(void *vpCtx)
Validates an API context pointer.
void vApiOpcodes(void *vpCtx)
Parse the SABNF grammar and translate its AST into opcodes for all the rules.
#define ID_BKR_CASE_I
the back reference is case insensitive
aint uiIndex
index of this rule in the rule list
api_rule * spRules
Points to an array of rule structures.
luint luiMax
maximum value for REP and TRG opcodes
aint uiLicenseOffset
Offset into the string table for the License string.
Generalized UDT for first-pass semantic processing.
aint uiOpcodeCount
Number of opcodes.
User data passed to the AST translator for use by the AST callback functions.
api_op * spOpcodes
Pointer to the array of opcodes for the SANF grammar.
aint uiVersionLength
Length of the Version Number string.
aint uiAcharLength
number of characters in TLS/TBS strings
Private header for the SABNF parser.
luint luiAcharEos
The special End-Of-String character. In practice, luiAcharMax + 1.
void * vpLog
A msglog context for error reporting.
aint uiMsgsCount(void *vpCtx)
Get the number of logged messages.
void vVecDtor(void *vpCtx)
The vector component destructor.
#define ID_ALT
alternation
Header file for the semantic translation functions.
#define ID_BKR
back reference to a previously matched rule or UDT name
#define ID_UDT
user-defined terminal
API information about each rule.
Private header file for the APG API suite of functions.
void vExContext()
Handles bad context pointers.
abool bInputValid
APG_TRUE if theer is input and it has been validated, APG_FALSE otherwise.
aint uiChildCount
number of children for this ALT or CAT operator
aint uiFindUdt(semantic_udt *spUdts, aint uiUdtCount, const char *cpName, aint uiNameLength)
void vAstTranslate(void *vpCtx, void *vpUserData)
Do a depth-first traversal of the AST with user-defined callback functions to translate the AST recor...
char * cpStringTable
Pointer to a list of null-terminated ASCII strings representing the rule and UDT names.
#define ID_NOT
negative look ahead
#define ID_AND
positive look ahead
void * vpVecAt(void *vpCtx, aint uiIndex)
Get a the indexed vector element. The vector is not altered.
luint * luipAchar
pointer to the first character in the achar table for this TLS/TBS operator
#define XTHROW(ctx, msg)
Exception throw macro.
luint luiMin
minimum value for REP and TRG opcodes
api_udt * spUdts
Points to an array of UDT structures, if one or more UDTs are referenced in the SABNF grammar.
aint uiRuleCount
The number of rules in the SABNF grammar and in the array.
uint_fast32_t aint
The APG parser's unsigned integer type.
aint * uipChildIndexTable
Pointer to a list of child indexes. ALT & CAT operators have two or more children operators....
void * vpVecLast(void *vpCtx)
Get the last element one the vector. The vector is not altered.
#define ID_CAT
concatenation
aint uiMode
ID_BKR_MODE_U of ID_BKR_MODE_P for BKR.
void vMsgsClear(void *vpCtx)
Clears the object of all messages.
aint uiChildIndexTableLength
The number of indexes (integers) in the child index table.
void * vpMemAlloc(void *vpCtx, aint uiBytes)
Allocates memory.
aint uiCopyrightOffset
Offset into the string table for the Copyright string.
aint uiVecLen(void *vpCtx)
Get the vector length. That is, the number of elements on the vector.
void * vpVecCtor(void *vpMem, aint uiElementSize, aint uiInitialAlloc)
The vector object constructor.
#define ID_TRG
terminal range
char * cpName
pointer to null-terminated string in the string table
luint luiPpptMapCount
The number of operator maps in the table.
aint uiLicenseLength
Length of the License string.
aint uiCase
ID_BKR_CASE_S or ID_BKR_CASE_I for BKR.
aint uiIndex
index of this referenced rule or UDT
luint * luipAcharTable
Pointer to the Achar Table - a table of all of the alphabet characters referenced by the terminal nod...
uintmax_t luint
luint is used to cast integers suitable for the %"PRIuMAX" printf format.
Generalized opcode for first-pass semantic processing.
abool bSyntaxValid
APG_TRUE if the input syntax is valid, APG_FALSE otherwise.
API information about each opcode.
void * vpAst
context handle to the AST object
void * vpVecFirst(void *vpCtx)
Get the first element one the vector. The vector is not altered.
API information about each UDT.
#define ID_BKA
positive look behind
aint uiVersionOffset
Offset into the string table for the Version Number string.
aint uiAcharTableLength
Number of alphabet characters in the Achar Table.
luint luiPpptMapSize
The size, in bytes, of a single operator map.
aint uiId
type of opcode, ID_ALT, etc.
aint uiFindRule(semantic_rule *spRules, aint uiRuleCount, const char *cpName, aint uiNameLength)
Find the index of the named rule in the rule list.
aint uiCopyrightLength
Length of the copyright string.
#define ID_TLS
terminal literal string
aint uiEmpty
APG_TRUE if this UDT can be empty, APG_FALSE otherwise
#define APG_MAX_AINT
Since the maximum unsigned integer value is used to indicate Infinite and Undefined values,...
#define ID_BKN
negative look behind
uint8_t abool
abool is the APG bool type.
char * cpName
pointer to null-terminated string in the string table
aint uiStringTableLength
The number of characters in the string table.
aint uiIndex
index of this UDT in the UDT list
luint luiAcharMin
The minimum alphabet character referenced by the terminal nodes, TLS, TBL & TRG.
aint uiBkrIndex
if BKR, this is the index to the rule or UDT that is being back referenced
void * vpMem
Pointer to the memory context used for all memory allocations and exceptions thrown.
Private header file for the AST functions.
luint luiAcharMax
The maximum alphabet character referenced by the terminal nodes, TLS, TBL & TRG.
Generalized rule for first-pass semantic processing.
aint * uipChildIndex
pointer to the first child index of this ALT or CAT operator
#define ID_ABG
anchor - beginning of string
abool bSemanticsValid
APG_TRUE if the the input semantics are valid. That is, the opcodes for the parser have been generate...
void vLineError(api *spCtx, aint uiCharIndex, const char *cpSrc, const char *cpMsg)
Finds the grammar line associated with a character index and formats an error message to the error lo...
aint uiOpOffset
offset into the opcode table to the first opcode of this rule
#define ID_BKR_MODE_U
the back reference is universal mode
aint uiEmpty
APG_TRUE if this UDT can be empty, APG_FALSE otherwise
#define ID_TBS
terminal binary string
void * vpVecPush(void *vpCtx, void *vpElement)
Adds one element to the end of the array.
luint luiPpptTableLength
The PPPT length.
aint uiOpCount
the number of opcodes in this rule
#define ID_AEN
anchor - end of string
Public header file for the APG API suite of functions.
APG Version 7.0 is licensed under the
2-Clause BSD License,
an Open Source Initiative Approved License.