Created
September 12, 2016 14:29
-
-
Save postboy/fb825b9fe813a0a18d04ef4cdf2ac7a0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <stdbool.h> | |
#include "../../include/queue.h" | |
//insert an element in tail queue | |
#define INSERT_TOKEN(STR) \ | |
do { \ | |
/*create new element*/ \ | |
tok_len = strlen(STR); \ | |
telt = malloc(sizeof(struct tentry)); \ | |
telt->name = malloc(tok_len + 1); \ | |
memcpy(telt->name, STR, tok_len); \ | |
telt->name[tok_len] = '\0'; \ | |
\ | |
STAILQ_INSERT_TAIL(thead, telt, pts); \ | |
} \ | |
while (0) | |
//insert an element in tail queue | |
#define INSERT_NONT(STR) \ | |
do { \ | |
bool found;\ | |
\ | |
/*search for new element in tail queue*/ \ | |
found = false; \ | |
STAILQ_FOREACH(nelt, &hnonterminals, pts) \ | |
if (!strcmp(STR, nnelt->name)) { \ | |
found = true; \ | |
break; \ | |
} \ | |
/*if it wasn't found then create and insert it at the head*/ \ | |
if (found == false) { \ | |
/*name of nonterminal*/ \ | |
tok_len = strlen(STR); \ | |
nnelt = malloc(sizeof(struct nentry)); \ | |
nnelt->name = malloc(tok_len + 1); \ | |
memcpy(nnelt->name, STR, tok_len); \ | |
nnelt->name[tok_len] = '\0'; \ | |
nnelt->pruned = false; \ | |
/*head of tokens' tree*/ \ | |
thead = (struct tentryhead *)malloc(sizeof(struct tentryhead)); \ | |
thead->stqh_first = NULL; \ | |
thead->stqh_last = thead->stqh_first; \ | |
STAILQ_INIT(thead); \ | |
nnelt->tokens = thead; \ | |
\ | |
STAILQ_INSERT_TAIL(&hnonterminals, nnelt, pts); \ | |
} \ | |
} \ | |
while (0) | |
//macro for printing error messages easily | |
#define error(...) fprintf(stderr, "error: %name: %i: %name\n", __func__, __LINE__, __VA_ARGS__) | |
struct tentry { | |
STAILQ_ENTRY(tentry) pts; //pointers | |
char *name; //null-terminated string | |
}; | |
struct nentry { | |
STAILQ_ENTRY(nentry) pts; //pointers | |
char *name; //null-terminated string | |
bool pruned; //was this nonterminal definition pruned? | |
struct tentryhead *tokens; //pointer to tail queue of tokens | |
}; | |
int main (int argc, char** argv) | |
{ | |
unsigned tok_len; | |
char buffer[] = "tok1 tok2 tok3 tok4 tok5 tok6"; | |
const char token_seps[] = " "; | |
char *tag; | |
/*element in single-linked tail queue of tokens, new and existing elements in single-linked | |
tail queue of nonterminals*/ | |
struct tentry *telt; | |
struct nentry *nnelt, *nelt; | |
//initialization of sturctures | |
STAILQ_HEAD(tentryhead, tentry); | |
struct tentryhead *thead; | |
STAILQ_HEAD(nentryhead, nentry) hnonterminals = STAILQ_HEAD_INITIALIZER(hnonterminals); | |
STAILQ_INIT(&hnonterminals); | |
//logic goes here------------------------------------------------------------------------------ | |
//begin processing of grammar rules from their start | |
if ( (tag = strtok(buffer, token_seps)) != NULL) { | |
do { | |
//printf("tag = %s\n", tag); | |
if ( (!strcmp(tag, "tok1")) || (!strcmp(tag, "tok4")) ) { | |
INSERT_NONT(tag); | |
} | |
else { | |
INSERT_TOKEN(tag); | |
} | |
} while ( (tag = strtok(NULL, token_seps)) != NULL); | |
} | |
printf("output: \n"); | |
STAILQ_FOREACH(nelt, &hnonterminals, pts) { | |
printf("\n%s: ", nelt->name); | |
STAILQ_FOREACH(telt, (struct tentryhead *)nelt->tokens, pts) | |
printf("%s ", telt->name); | |
} | |
printf("\n"); | |
//free entries and delete tail queue | |
while (!STAILQ_EMPTY(&hnonterminals)) { | |
nelt = STAILQ_FIRST(&hnonterminals); | |
STAILQ_REMOVE_HEAD(&hnonterminals, pts); | |
while (!STAILQ_EMPTY((struct tentryhead *)nelt->tokens)) { | |
telt = STAILQ_FIRST((struct tentryhead *)nelt->tokens); | |
STAILQ_REMOVE_HEAD((struct tentryhead *)nelt->tokens, pts); | |
free(telt->name); | |
free(telt); | |
} | |
free(nelt->tokens); | |
free(nelt->name); | |
free(nelt); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment