Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- typedef enum {VAR, OP, EOS} tokenType;
- static char* typeNames[] = {"VAR", "OP", "EOS"}; //debugging purposes
- typedef struct
- {
- tokenType type;
- char* name;
- int value;
- } token;
- void printStream(token** stream)
- {
- int i = 0;
- token* last;
- do
- {
- last = stream[i++];
- printf("Type: %s Name: %s Value: %d Location: %p\n",
- typeNames[last->type], last->type == VAR ? last->name : "Not a var",
- last->value, last);
- } while (last->type != EOS);
- }
- #define SYMBOLSCHUNKSIZE 4
- static int symbolsRemaining = 0;
- static int symbolPointerChunks = 0;
- static int symbolPointerIndex = 0;
- static token** symbols = NULL;
- token* createIdentifier(char name[])
- {
- //check if it's already in the table
- int searchPointer;
- for (searchPointer = 0; searchPointer < symbolPointerIndex; searchPointer++)
- if (!strcmp(name, symbols[searchPointer]->name))
- return symbols[searchPointer];
- if (!symbolsRemaining)
- {
- if ((symbols = realloc(symbols, (++symbolPointerChunks * SYMBOLSCHUNKSIZE) * sizeof(token*))) == NULL)
- {
- fprintf(stderr, "Failed to extend allocated memory for the symbol pointer array!\n");
- free(symbols);
- exit(-1);
- }
- symbolsRemaining = SYMBOLSCHUNKSIZE - 1;
- }
- token* newID = malloc(sizeof(token));
- newID->type = VAR;
- newID->value = -1;
- newID->name = malloc(sizeof(char) * (strlen(name) + 1));
- strcpy(newID->name, name);
- newID->name[strlen(name)] = '\0';
- symbols[symbolPointerIndex++] = newID;
- return newID;
- }
- void assignVariables()
- {
- for (int i = 0; i < symbolPointerIndex; i++)
- {
- printf("Is %s true or false?\n", symbols[i]->name);
- symbols[i]->value = i % 2;
- //getc(stdin); /*UNCOMMENTING THIS CAUSES ISSUES*/
- }
- }
- #define CHUNKLENGTH 8
- token** lex()
- {
- int chunks = 1;
- int tokensRemaining = CHUNKLENGTH;
- int streamPointer = 0;
- token** stream = malloc(sizeof(token*) * CHUNKLENGTH);
- char c;
- while ((c = getc(stdin)) != '\n')
- {
- if (isspace(c)) continue;
- if (isalpha(c))
- {
- char name[9];
- name[0] = c;
- int nPointer;
- for (nPointer = 1; isalpha(c = getc(stdin)) && nPointer < 8; nPointer++)
- name[nPointer] = c;
- name[nPointer] = '\0';
- //consume remaining characters if the identifier is too long
- while (isalpha(c)) c = getc(stdin);
- //ask the symbol table for a token for this identifier
- stream[streamPointer++] = createIdentifier(name);
- if (c == '\n') break;
- ungetc(c, stdin);
- continue;
- }
- //usually I'd check the different operators, trying to minimise this
- token* new = malloc(sizeof(token));
- new->type = OP;
- stream[streamPointer++] = new;
- if (!--tokensRemaining)
- {
- if ((stream = realloc(stream, (++chunks * CHUNKLENGTH) * sizeof(token*))) == NULL)
- {
- fprintf(stderr, "Failed to extend allocated memory for the token stream!\n");
- free(stream);
- exit(-1);
- }
- tokensRemaining = CHUNKLENGTH;
- }
- }
- token* eos = malloc(sizeof(token));
- eos->type = EOS;
- stream[streamPointer] = eos;
- return stream;
- }
- int main()
- {
- token** stream = lex();
- printStream(stream); //fine here, even when done twice
- assignVariables();
- printStream(stream); //segfault due to missing EOS
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment