#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "pair.h"
#include "lexer.h"
#include "template.h"
#include "translator.h"
#include "parser.h"
Include dependency graph for parser.c:

Go to the source code of this file.
Defines | |
| #define | EVAL(expr, err) if (expr) { errno = err; perror(pcerr); iret = EXIT_FAILURE; goto cleanup; } |
In evaluand's case, assigns errno and initiates cleanup; puts error. | |
| #define | ALLOC(str, vector) EVAL((str = (char *) realloc(str, vector + sizeof('\0'))) == NULL, ENOMEM) |
| Allocates string according to vector; sets adherent error state. | |
| #define | STRCAT(stra, strb) ALLOC(stra, strlen(stra) + strlen(strb)); strcat(stra, strb) |
| Concatenates strings, allocating and setting error states. | |
| #define | STRSUB(stra, strb, offset) ALLOC(stra, offset); sprintf(stra, "%.*s", offset, strb) |
| Creates new string of string's substring. | |
| #define | NONE(a) a = (char *) malloc(0) |
Prepare the char vector for realloc. | |
Functions | |
| int | parse (char *pcin) |
| Parse source as a collection of specific demi-XML legmata, ferreting out the adherent contents. | |
| void | parsetag (char *pc) |
| Parses lectate and funnels adherent content to an appropriate translator. | |
Definition in file parser.c.
|
|
Allocates string according to vector; sets adherent error state.
|
|
|
In evaluand's case, assigns
|
|
|
Prepare the char vector for
|
|
|
Concatenates strings, allocating and setting error states.
|
|
|
Creates new string of string's substring.
|
|
|
Parse source as a collection of specific demi-XML legmata, ferreting out the adherent contents.
Definition at line 38 of file parser.c. References ALLOC, EVAL, template_t::i, lex(), NONE, PARSE_ELEMENT, PARSE_ERR, parsetag(), template_t::pten, STRCAT, te, and templatefree(). Referenced by main(). 00039 {
00040 int i, iret = EXIT_SUCCESS;
00041 const char *pcmaskbase = "<[[:space:]]*?(%s)+?(.*?)>(.*?)</\\%d>";
00042 const char *pcdiv = "|";
00043 const char *pcerr = "parser.c parse()";
00044 char NONE(*pcmaskelement), NONE(*pcmask);
00045
00046 /* Initialize template list. */
00047 EVAL(template(&te) != EXIT_SUCCESS, PARSE_ERR);
00048
00049 /* Goal: element mask of the form `math|chem|music|...'. */
00050 for (i = 0; i < te.i; i++) {
00051 STRCAT(pcmaskelement, (te.pten + i)->pcclass);
00052 STRCAT(pcmaskelement, pcdiv);
00053 }
00054
00055 /* Elide the terminal divider. */
00056 *(pcmaskelement + strlen(pcmaskelement) - strlen(pcdiv)) = '\0';
00057
00058 /* Slight superfluity when %d recombined as integer; and on single-character classes. */
00059 ALLOC(pcmask, strlen(pcmaskelement) + strlen(pcmaskbase));
00060 sprintf(pcmask, pcmaskbase, pcmaskelement, PARSE_ELEMENT);
00061
00062 /* Perform tokenization with callback.
00063 Important implication: class name associated with content is always the first pair! */
00064 EVAL(lex(pcin, pcmask, parsetag) != EXIT_SUCCESS, EINVAL);
00065
00066 cleanup:
00067 templatefree(&te);
00068 free(pcmaskelement);
00069 free(pcmask);
00070 return iret;
00071 }
|
Here is the call graph for this function:

|
|
Parses lectate and funnels adherent content to an appropriate translator.
Definition at line 75 of file parser.c. References addpair(), EVAL, template_t::i, NONE, PAIRNEW, PARSE_ARG, PARSE_ARGS, PARSE_BEGIN, PARSE_CLASS, PARSE_CONTENT, PARSE_END, PARSE_MATCH, PARSE_OPT, PARSE_PAIRS, template_t::pten, STRSUB, te, and translate(). Referenced by parse(). 00076 {
00077 int i, ire, aisub[PARSE_ARGS * PARSE_VECTOR], iret; /* iret: macro placeholder */
00078 pcre *pre;
00079 const char *pcre;
00080 const char *pcmask = "^<[[:space:]]*([^[:space:]]+)(.*?)>(.*)<";
00081 const char *pcerr = "parser.c parsetag()";
00082 char NONE(*pcclass), NONE(*pcpairs), NONE(*pccontent);
00083 pair_t pa;
00084
00085 EVAL((pre = pcre_compile(pcmask, PARSE_OPT, &pcre, &ire, NULL)) == NULL, EINVAL);
00086 EVAL(pcre_exec(pre, NULL, pc, strlen(pc), 0, 0, aisub, 12) < PARSE_MATCH, EINVAL);
00087 STRSUB(pcclass, pc + aisub[PARSE_CLASS * PARSE_ARG + PARSE_BEGIN], aisub[PARSE_CLASS * PARSE_ARG + PARSE_END] - aisub[PARSE_CLASS * PARSE_ARG + PARSE_BEGIN]);
00088 STRSUB(pcpairs, pc + aisub[PARSE_PAIRS * PARSE_ARG + PARSE_BEGIN], aisub[PARSE_PAIRS * PARSE_ARG + PARSE_END] - aisub[PARSE_PAIRS * PARSE_ARG + PARSE_BEGIN]);
00089 STRSUB(pccontent, pc + aisub[PARSE_CONTENT * PARSE_ARG + PARSE_BEGIN], aisub[PARSE_CONTENT * PARSE_ARG + PARSE_END] - aisub[PARSE_CONTENT * PARSE_ARG + PARSE_BEGIN]);
00090
00091 /* Shine constructor. */
00092 PAIRNEW(pa);
00093 /* Construct pair devised of class and content. */
00094 addpair(pcclass, pccontent, &pa);
00095
00096 for (i = 0; i < te.i; i++) {
00097 if (strcmp(pcclass, (te.pten + i)->pcclass) == 0) {
00098 translate((te.pten + i)->pcdigest, &pa);
00099 }
00100 }
00101
00102 cleanup:
00103 free(pcclass);
00104 free(pcpairs);
00105 free(pccontent);
00106 }
|
Here is the call graph for this function:

1.3.9.1