Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
|
Go to the documentation of this file.
45 #define THROW_ERROR(msg, off) vThrowError(spJson, (msg), (off), __FILE__, __func__, __LINE__)
55 uiChar = ((uint32_t)cpBytes[0] & 0x1f) << 6;
56 uiChar += (uint32_t)cpBytes[1] & 0x3f;
61 uiChar = ((uint32_t)cpBytes[0] & 0xf) << 12;
62 uiChar += ((uint32_t)cpBytes[1] & 0x3f) << 6;
63 uiChar += (uint32_t)cpBytes[2] & 0x3f;
68 uiChar = ((uint32_t)cpBytes[0] & 0x7) << 18;
69 uiChar += ((uint32_t)cpBytes[1] & 0x3f) << 12;
70 uiChar += ((uint32_t)cpBytes[2] & 0x3f) << 6;
71 uiChar += (uint32_t)cpBytes[3] & 0x3f;
76 *uipChar = (uint32_t)strtol(cpHex, &cpPtr, 16);
77 if(*uipChar >= 0xD800 && *uipChar < 0xE000){
84 uint32_t uiHigh = (uint32_t)strtol(cpHex, &cpPtr, 16);
85 if(uiHigh < 0xD800 || uiHigh >= 0xE000){
92 uint32_t uiLow = (uint32_t)strtol(&cpHex[5], &cpPtr, 16);
93 if(!(uiLow >= 0xDC00 && uiLow < 0xE000)){
97 uiHigh = (uiHigh - 0xd800) << 10;
99 *uipChar = uiHigh + uiLow + 0x10000;
104 static void vThrowError(
json* spJson,
char* cpMsg,
aint uiOffset,
105 const char* cpFile,
const char* cpFunc,
unsigned int uiCodeLine){
106 aint uiLine, uiRelOffset;
109 snprintf(caBuf, 1024,
110 "%s: near: line: %"PRIuMAX
": character: %"PRIuMAX
" (0x%"PRIXMAX
")",
113 snprintf(caBuf, 1024,
114 "%s: character offset out of range: %"PRIuMAX
" (0x%"PRIXMAX
")",
123 memset((
void*)spCurrent, 0,
sizeof(
frame));
129 spValuer->
uiKey = spPrev->uiNextKey;
153 THROW_ERROR(
"vector index out of range", uiOffset);
157 static abool bMultiplyUint(uint64_t uiL, uint64_t uiR, uint64_t* uipA){
158 if(uiL == 0 || uiR == 0){
162 uint64_t uiTest = uiL * uiR;
163 uint64_t uiCheck = uiTest / uiR;
171 static abool bSumUint(uint64_t uiL, uint64_t uiR, uint64_t* uipA){
172 uint64_t uiTest = uiL + uiR;
176 uint64_t uiCheck = uiTest - uiR;
183 static abool bMultiplyInt(int64_t iL, int64_t iR, int64_t * ipA){
184 if(iL == 0 || iR == 0){
188 int64_t iTest = iL * iR;
195 static abool bSumInt(int64_t iL, int64_t iR, int64_t* ipA){
196 int64_t iTest = iL + iR;
203 static abool bStringToInt(
char* cpString, int64_t* ipInt){
207 char* cpEnd = cpString + strlen(cpString);
208 int64_t iVal = *cpString++ - 48;
209 while(cpString < cpEnd){
210 if(!bMultiplyInt(iVal, 10LL, &iVal)){
213 if(!bSumInt(iVal, (int64_t)(*cpString++ - 48), &iVal)){
224 static abool bStringToUint(
char* cpString, uint64_t* uipInt){
228 char* cpEnd = cpString + strlen(cpString);
229 uint64_t uiVal = *cpString++ - 48;
230 while(cpString < cpEnd){
231 if(!bMultiplyUint(uiVal, 10LL, &uiVal)){
234 if(!bSumUint(uiVal, (int64_t)(*cpString++ - 48), &uiVal)){
275 string_r* spStringrBeg = spStringsr;
280 value_r* spValuerBeg = spValuesr;
293 for(; spStringrBeg < spStringrEnd; spStringrBeg++,
spString++){
301 json_value* spValue = spJson->
spValues;
302 aint uiChildPointerTop = 0;
303 for(; spValuerBeg < spValuerEnd; spValuerBeg++, spValue++){
304 spValue->uiId = spValuerBeg->
uiId;
306 spValue->spKey = NULL;
310 spValue->sppChildren = NULL;
311 spValue->uiChildCount = 0;
312 switch(spValuerBeg->
uiId){
329 for(ui = 0; ui < spValuerBeg->
uiChildCount; ui++, uipChildList++){
334 snprintf(caBuf, 64,
"unrecognized value type: %"PRIuMAX
"", (
luint)spValuerBeg->
uiId);
347 vPushFrameAndValue(spData);
360 while(uipIndex < uipEnd){
361 *uipIndex++ = *uipChildIndex++;
580 caHex[0] = (
char)acpDigits[2];
581 caHex[1] = (char)acpDigits[3];
582 caHex[2] = (char)acpDigits[4];
583 caHex[3] = (char)acpDigits[5];
595 caHex[0] = (
char)acpDigits[2];
596 caHex[1] = (char)acpDigits[3];
597 caHex[2] = (char)acpDigits[4];
598 caHex[3] = (char)acpDigits[5];
600 caHex[5] = (char)acpDigits[8];
601 caHex[6] = (char)acpDigits[9];
602 caHex[7] = (char)acpDigits[10];
603 caHex[8] = (char)acpDigits[11];
640 cpNumber[ui] = (char)acpParsed[ui];
646 if(cpPtr > cpNumber){
650 snprintf(caBuf, 128,
"Unable to convert floating point string with \"strtod()\": %s", cpNumber);
656 snprintf(caBuf, 128,
"Integer value too large to convert to int: %s", cpNumber);
664 snprintf(caBuf, 128,
"Integer value too large to convert to unsigned int: %s", cpNumber);
701 THROW_ERROR(
"Leading plus (+) sign not allowed for decimal portion of floating point number (REF8259)", spData->
uiParserOffset);
721 memset((
void*)cb, 0,
sizeof(cb));
aint uiUtf16_2(char *cpHex, uint32_t *uipChar)
int64_t iSigned
If uiType = JSON_ID_SIGNED, the signed int value.
double dFloat
If uiType = JSON_ID_FLOAT, the floating point value.
#define JSON_GRAMMAR_SOLIDUS
u32_phrase * spString
Pointer to the string value if uiId = JSON_ID_STRING.
#define JSON_GRAMMAR_UTF16_2
void * vpVecAscii
A scratch vector for constructing ASCII strings on the fly.
#define JSON_UTF16_NOMATCH
#define JSON_GRAMMAR_UTF8_3
#define JSON_GRAMMAR_ASCII
#define JSON_GRAMMAR_STRING_BEGIN
#define JSON_UTF16_BAD_LOW
The object context. For intenrnal use only.
#define JSON_GRAMMAR_NAME_SEPARATOR
#define JSON_GRAMMAR_LINE_FEED
aint uiParserOffset
[read only] Offset from acpString to the first character to match
The structure of a JSON number value.
aint uiCharsOffset
The offset from the vector base of 32-bit character codes to the first character in the string.
#define JSON_GRAMMAR_END_MEMBER_SEPARATOR
#define JSON_GRAMMAR_UTF8_2
const achar * acpString
[read only] Pointer to the input sub-string,
void vVecDtor(void *vpCtx)
The vector component destructor.
uint32_t uiLength
The number of integers in the array.
u32_phrase * spStrings
An array of absolute strings.
aint uiParserState
[read only] ID_ACTIVE if the parser is going down the tree. ID_MATCH or ID_NOMATCH if coming up the t...
#define JSON_GRAMMAR_FRAC
frame * spCurrentFrame
Points to the current stack frame.
#define JSON_GRAMMAR_QUOTE
exception * spException
Pointer to the exception structure for reporting errors to the application catch block.
json_value * spValues
an array of absolute values.
abool bLinesFindLine(void *vpCtx, aint uiOffset, aint *uipLine, aint *uipRelOffset)
Find the line that the given character is in.
#define JSON_GRAMMAR_FALSE
uint_fast8_t achar
achar is the type for the parser's alphabet characters.
void * vpVecChars
A vector of string characters. 32-bit Unicode code points. All strings are in this single vector.
#define JSON_GRAMMAR_CHAR
Each value is a node in the parse tree.
aint uiValue
Index to the value represented by this frame.
#define JSON_ID_STRING
String value.
void vParserSetRuleCallback(void *vpCtx, aint uiRuleId, parser_callback pfnCallback)
Set a call back function for a specific rule.
void * vpVecChildIndexes
A vector of number objects.
#define JSON_GRAMMAR_BEGIN_OBJECT
#define JSON_GRAMMAR_END_ARRAY
#define JSON_GRAMMAR_JSON_TEXT
void * vpVecAt(void *vpCtx, aint uiIndex)
Get a the indexed vector element. The vector is not altered.
void vJsonGrammarRuleCallbacks(void *vpParserCtx)
const uint32_t * uipPhrase
Pointer to an array of 32-bit unsigned integers.
void * vpVecChildPointers
void(* parser_callback)(callback_data *spData)
User-written callback function prototype.
#define JSON_GRAMMAR_STRING_END
#define RULE_COUNT_JSON_GRAMMAR
#define JSON_ID_ARRAY
Array value.
#define JSON_GRAMMAR_FRAC_ONLY
void * vpVecPop(void *vpCtx)
Pops one element from the end of the array.
This is the "relative" value developed during parsing.
aint uiNextKey
Used to keep track of the next available key offset to be used by an object member.
uint_fast32_t aint
The APG parser's unsigned integer type.
void * vpVecLast(void *vpCtx)
Get the last element one the vector. The vector is not altered.
struct json_value_tag ** sppChildPointers
An array of absolute child value pointers.
#define JSON_GRAMMAR_STRING_CONTENT
#define JSON_ID_FALSE
Literal value is false.
aint uiParserPhraseLength
[read only] The parser's matched phrase length if uiParserState is ID_MATCH or ID_NOMATCH....
#define JSON_ID_OBJECT
Object value.
void * vpVecFrames
Frame stack of values to keep track of the current value in the parse tree.
aint uiCallbackState
[input/output] Rule name (RNM) callback functions: If ID_ACTIVE, the parser takes no action....
aint uiChildCount
if uiId is JSON_ID_OBJECT or JSON_ID_ARRAY, the number of members or values.
abool bHasFrac
A working value signaling presence of fractional value for a number value.
aint uiNumber
Offset to a number if JSON_ID_NUMBER.
aint uiVecLen(void *vpCtx)
Get the vector length. That is, the number of elements on the vector.
#define JSON_GRAMMAR_BACKSPACE
uint32_t uiUtf8_2byte(char *cpBytes)
void * vpMem
Pointer to a memory object used for all memory allocations.
void * vpVecCtor(void *vpMem, aint uiElementSize, aint uiInitialAlloc)
The vector object constructor.
#define JSON_ID_TRUE
Literal value is true.
uint32_t uiChar
A working value to hold the value of a single character. Higher level rules will move it to vpVecChar...
This is the "relative" string developed during parsing.
#define ID_ACTIVE
indicates active parser state, parser has just entered the node and is moving down the parse tree
#define JSON_GRAMMAR_FRAC_DIGITS
#define JSON_UTF16_BAD_HIGH
aint uiStringCount
The number of strings in the array.
#define ID_MATCH
indicates a matched phrase parser state on return from parse tree below this node
uintmax_t luint
luint is used to cast integers suitable for the %"PRIuMAX" printf format.
#define JSON_GRAMMAR_TRUE
The data struct passed to each callback function.
aint uiChildCount
The number of child values if uiId is JSON_ID_OBJECT or JSON_ID_ARRAY.
aint uiKey
If uiID is JSON_ID_OBJECT, offset to the key's string. Otherwise, zero and not used.
void * vpVecValues
A vector of relative values.
void * vpVecFirst(void *vpCtx)
Get the first element one the vector. The vector is not altered.
#define JSON_ID_FLOAT
Number value is a double floating point number.
void * vpVecPushn(void *vpCtx, void *vpElement, aint uiCount)
Adds one or more elements to the end of the array.
#define JSON_GRAMMAR_UTF16_1
json_number * spNumber
Pointer to the number value if uiId = JSON_ID_NUMBER.
aint uiChildListOffset
Offset from the base of the vector of child value pointers.
Private JSON component header file.
aint uiValueCount
The number of values in the array.
uint32_t uiUtf8_4byte(char *cpBytes)
#define JSON_GRAMMAR_MINUS
aint uiString
Offset to a string_r if JSON_ID_STRING.
void * vpLines
pointer to a lines object context
aint uiUtf16_1(char *cpHex, uint32_t *uipChar)
void * vpUserData
[input/output] User-defined data passed to to the parser in parser_config.
void * vpVecStrings
A vector of relative strings.
#define JSON_GRAMMAR_NULL
#define JSON_GRAMMAR_END_VALUE_SEPARATOR
#define JSON_GRAMMAR_PLUS
#define JSON_GRAMMAR_END_OBJECT
uint64_t uiUnsigned
If uiType = JSON_ID_UNSIGNED, the unsigned int value.
#define THROW_ERROR(msg, off)
A specialized exception thrower for the callback functions.
uint8_t abool
abool is the APG bool type.
Header file for the JSON component. Defines API prototypes.
#define JSON_ID_SIGNED
Number value is a 64-bit signed integer.
void * vpVecPopi(void *vpCtx, aint uiIndex)
Pops the element at the given zero-based index and all higher indexes.
#define ID_NOMATCH
indicates that no phrase was matched on return from parse tree below this node
#define JSON_ID_UNSIGNED
Number value is a 64-bit unsigned integer.
#define JSON_GRAMMAR_KEY_BEGIN
aint uiId
The value identifier, JSON_ID_OBJECT, etc.
aint uiType
Identifies the number type. One of.
#define JSON_GRAMMAR_FORM_FEED
#define JSON_GRAMMAR_R_SOLIDUS
abool bHasMinus
A working value signaling a minus sign for a number value.
Defines a pointer to an array of 32-bit unsigned integers plus its length. Typically needed by Unicod...
#define JSON_ID_NULL
Literal value is null.
The structure of a JSON value.
aint uiStringLength
[read only] The input string length.
aint uiLength
The number of characters in the string.
#define JSON_GRAMMAR_UTF8_4
uint32_t uiUtf8_3byte(char *cpBytes)
void * vpVecPush(void *vpCtx, void *vpElement)
Adds one element to the end of the array.
#define JSON_ID_NUMBER
Number value.
#define JSON_GRAMMAR_NUMBER
void vVecClear(void *vpCtx)
Clears all used elements in a vector component.
void vExThrow(exception *spEx, const char *cpMsg, unsigned int uiLine, const char *cpFile, const char *cpFunc)
Throws an exception.
#define JSON_GRAMMAR_VALUE
#define JSON_GRAMMAR_BEGIN_ARRAY
APG Version 7.0 is licensed under the
2-Clause BSD License,
an Open Source Initiative Approved License.