Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
|
Go to the documentation of this file.
47 static void vPushInvalidChar(
api* spCtx,
aint uiCharIndex, uint8_t ucChar,
const char* cpMsg);
49 static const char* s_cpMsgInvalid =
50 "valid ABNF characters are, 0x09, 0x0A, 0x0D and 0x20-7E only";
51 static const char* s_cpMsgCRLF =
"invalid line ending - must be CRLF (\\r\\n, 0x0D0A) - strict specified";
52 static const char* s_cpMsgEOF =
"invalid line ending - last line has no line ending";
53 static char s_cZero = 0;
121 api* spCtx = (
api*) vpCtx;
125 char caReadBuf[1024];
126 size_t iBufSize = 1024;
136 spFile = fopen(cpFileName,
"rb");
138 snprintf(caBuf,
BUF_SIZE,
"unable to open file name %s for reading", cpFileName);
143 while((uiRead = (
aint)fread(caReadBuf,
sizeof(
char), iBufSize, spFile)) > 0){
169 api* spCtx = (
api*) vpCtx;
179 uiLen = (
aint)strlen(cpString);
208 api* spCtx = (
api*) vpCtx;
210 aint ui, uii, uiLines, uiEndLen;
215 "no input grammar, see bApiInFile() & uiApiInString()\n");
221 for (ui = 0; ui < uiLines; ui += 1) {
222 spThis = &spLines[ui];
226 if (ucChar < 32 || ucChar > 126) {
229 vPushInvalidChar(spCtx, (spThis->
uiCharIndex + uii), ucChar, s_cpMsgInvalid);
237 vPushInvalidChar(spCtx, (spThis->
uiCharIndex + uii - 1), 0, s_cpMsgEOF);
238 }
else if (uiEndLen == 1) {
265 api* spCtx = (
api*) vpCtx;
267 FILE* spFile = stdout;
272 spFile = fopen(cpFileName,
"wb");
274 snprintf(caBuf,
BUF_SIZE,
"can't open file %s for writing", cpFileName);
284 fprintf(spFile,
"\\t");
285 }
else if (ucChar >= 32 && ucChar <= 126) {
286 fprintf(spFile,
"%c", ucChar);
288 fprintf(spFile,
"\"\\x%02X\"", ucChar);
293 fprintf(spFile,
"\\EOF\n");
295 fprintf(spFile,
"%s", ucChar ==
LF ?
"\\n" :
"\\r");
298 fprintf(spFile,
"%s", ucChar ==
LF ?
"\\n" :
"\\r");
300 fprintf(spFile,
"\n");
304 if (spFile != stdout) {
319 void vApiInToHtml(
void* vpCtx,
const char* cpFileName,
const char* cpTitle) {
323 api* spCtx = (
api*) vpCtx;
332 spFile = fopen(cpFileName,
"wb");
334 snprintf(caBuf,
BUF_SIZE,
"fopen() failed for file name %s for writing", cpFileName);
338 cpTitle =
"SABNF Grammar";
341 fprintf(spFile,
"%s",
"<table>\n");
342 fprintf(spFile,
"%s",
"<table><tr><th>line<br/>index</th><th>char<br>offset</th><th>line<br/>text</th></tr>\n");
345 fprintf(spFile,
"%s%"PRIuMAX
"%s%"PRIuMAX
"%s",
"<tr><td>", (
luint) spLine->
uiLineIndex,
"</td><td>",
350 fprintf(spFile,
"%s",
"<var>TAB</var>");
351 }
else if (ucChar >= 32 && ucChar <= 126) {
352 fprintf(spFile,
"%c", ucChar);
354 fprintf(spFile,
"%s%02X%s",
"<kbd>\\x", ucChar,
"</kbd>");
359 fprintf(spFile,
"%s",
"<kbd>EOF</kbd>");
361 fprintf(spFile,
"%s%s%s",
"<var>", ((ucChar ==
LF) ?
"LF" :
"CR"),
"</var>");
364 fprintf(spFile,
"%s%s%s",
"<var>", ((ucChar ==
LF) ?
"LF" :
"CR"),
"</var>");
367 fprintf(spFile,
"%s\n",
"</td></tr>");
370 fprintf(spFile,
"%s\n",
"</table>");
384 aint uiLine, uiRelIndex;
385 aint uiBufSize = 2014;
388 char caBuf[uiBufSize];
393 void* vpVecTemp = NULL;
401 spLine = &spLine[uiLine];
405 snprintf(caBuf, uiBufSize,
"%s: line index: %"PRIuMAX
": rel char index: %"PRIuMAX
": %s",
406 cpSrc, (
luint) uiLine, (
luint) uiRelCharIndex, cpMsg);
412 int len = (int)strlen(cpSrc);
423 if (ucChar >= 32 && ucChar <= 126) {
425 }
else if (ucChar ==
TAB) {
428 }
else if (ucChar ==
LF) {
431 }
else if (ucChar ==
CR) {
435 sprintf(caBuf,
"\\x%02X", ucChar);
441 snprintf(caBuf, uiBufSize,
"%s: char index out of range: %"PRIuMAX
": %s",
442 cpSrc, (
luint) uiCharIndex, cpMsg);
451 static void vPushInvalidChar(
api* spCtx,
aint uiCharIndex, uint8_t ucChar,
const char* cpMsg) {
454 snprintf(caBuf, 256,
"invalid character: 0x%"PRIXMAX
": %s", (
luint) ucChar, cpMsg);
455 vLineError(spCtx, uiCharIndex,
"validate", caBuf);
void vMsgsLog(void *vpCtx, const char *cpMsg)
Logs a message.
uint8_t * ucpPpptEmptyMap
Common PPPT character map for an operator that is an empty match on the next alphabet character.
aint uiUdtCount
The number of UDTs referenced in the SABNF grammar.
aint uiLineLength
The number of characters in the line, including the line end characters.
abool bApiValidate(void *vpCtx)
Validates an API context pointer.
uint8_t * ucpPpptUndecidedMap
Common PPPT character map for an operator that is indeterminate on the next alphabet character.
void vHtmlHeader(FILE *spFile, const char *cpTitle)
Prints an HTML header to an open file.
api_rule * spRules
Points to an array of rule structures.
void * vpLinesCtor(exception *spEx, const char *cpInput, aint uiLength)
The lines object constructor.
api_op * spOpcodes
Pointer to the array of opcodes for the SANF grammar.
void * vpLog
A msglog context for error reporting.
void * vpOutputParserInit
Storage for variable integer width output parser init data.
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.
abool bLinesFindLine(void *vpCtx, aint uiOffset, aint *uipLine, aint *uipRelOffset)
Find the line that the given character is in.
void * vpAttrsCtx
context handle to the attributes object
char * cpStringTable
Pointer to a list of null-terminated ASCII strings representing the rule and UDT names.
#define XTHROW(ctx, msg)
Exception throw macro.
void * vpVecPop(void *vpCtx)
Pops one element from the end of the array.
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 vMsgsClear(void *vpCtx)
Clears the object of all messages.
aint uiChildIndexTableLength
The number of indexes (integers) in the child index table.
void vHtmlFooter(FILE *spFile)
Prints an HTML footer to an open file.
aint uiVecLen(void *vpCtx)
Get the vector length. That is, the number of elements on the vector.
void * vpLines
Context pointer to a lines object.
void vMemFree(void *vpCtx, const void *vpData)
Free memory previously allocated with vpMemAlloc().
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.
aint uiLineIndex
The zero-based line index.
abool bSyntaxValid
APG_TRUE if the input syntax is valid, APG_FALSE otherwise.
aint uiTextLength
The number of characters in the line, excluding the line end characters.
void * vpVecFirst(void *vpCtx)
Get the first element one the vector. The vector is not altered.
void * vpVecPushn(void *vpCtx, void *vpElement, aint uiCount)
Adds one or more elements to the end of the array.
Defines the characteristics of a single line.
Header file for the attributes functions.
line * spLinesNext(void *vpCtx)
Returns the next line of text from the iterator.
void * vpVecInput
The (ASCII) input grammar files and/or strings accumulate here. Always a NULL-terminated string.
aint uiInputLength
The number of input characters.
void * vpOutputAcharTable
Storage for variable character width output parser achar table.
aint uiAcharTableLength
Number of alphabet characters in the Achar Table.
uint8_t * ucpPpptTable
Pointer to the PPPT table of operator maps.
line * spLinesFirst(void *vpCtx)
Initialize an iterator over the lines.
abool bAttributesValid
APG_TRUE if there the rule attributes have been computed and have no fatal errors,...
void * vpVecTempChars
Temporary vector of characters. Here for clean up on unusual exit.
void vLinesDtor(void *vpCtx)
The lines object destructor.
void vParserDtor(void *vpCtx)
Clears the parser component's context and frees all heap memory associated with this parser.
abool bUsePppt
True of PPPT are being used.
uint8_t abool
abool is the APG bool type.
void * vpAltStack
A temporary vector for the AST translator.
void * vpParser
context handle to the SABNF grammar parser object
void * vpMem
Pointer to the memory context used for all memory allocations and exceptions thrown.
char caLineEnd[3]
The actual, null-terminated string of line ending character(s), if any.
abool bSemanticsValid
APG_TRUE if the the input semantics are valid. That is, the opcodes for the parser have been generate...
void vAttrsDtor(void *vpCtx)
The API object destructor.
void * vpVecPush(void *vpCtx, void *vpElement)
Adds one element to the end of the array.
void vVecClear(void *vpCtx)
Clears all used elements in a vector component.
aint uiCharIndex
The zero-based index of the first character of the line.
Public header file for the APG API suite of functions.
aint uiLinesCount(void *vpCtx)
Returns the number of lines of text.
APG Version 7.0 is licensed under the
2-Clause BSD License,
an Open Source Initiative Approved License.