Abdulg

MCVE

Aug 28th, 2016
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.31 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5.  
  6. typedef enum {VAR, OP, EOS} tokenType;
  7. static char* typeNames[] = {"VAR", "OP", "EOS"}; //debugging purposes
  8.  
  9. typedef struct
  10. {
  11.     tokenType type;
  12.     char* name;
  13.     int value;
  14. } token;
  15.  
  16. void printStream(token** stream)
  17. {
  18.     int i = 0;
  19.     token* last;
  20.     do
  21.     {
  22.         last = stream[i++];
  23.         printf("Type: %s    Name: %s   Value: %d   Location: %p\n",
  24.             typeNames[last->type], last->type == VAR ? last->name : "Not a var",
  25.             last->value, last);
  26.     } while (last->type != EOS);
  27. }
  28.  
  29.  
  30. #define SYMBOLSCHUNKSIZE 4
  31. static int symbolsRemaining = 0;
  32. static int symbolPointerChunks = 0;
  33. static int symbolPointerIndex = 0;
  34. static token** symbols = NULL;
  35. token* createIdentifier(char name[])
  36. {
  37.     //check if it's already in the table
  38.     int searchPointer;
  39.     for (searchPointer = 0; searchPointer < symbolPointerIndex; searchPointer++)
  40.         if (!strcmp(name, symbols[searchPointer]->name))
  41.             return symbols[searchPointer];
  42.  
  43.     if (!symbolsRemaining)
  44.     {
  45.         if ((symbols = realloc(symbols, (++symbolPointerChunks * SYMBOLSCHUNKSIZE) * sizeof(token*))) == NULL)
  46.         {
  47.             fprintf(stderr, "Failed to extend allocated memory for the symbol pointer array!\n");
  48.             free(symbols);
  49.             exit(-1);
  50.         }
  51.  
  52.         symbolsRemaining = SYMBOLSCHUNKSIZE - 1;
  53.     }
  54.  
  55.     token* newID = malloc(sizeof(token));
  56.     newID->type = VAR;
  57.     newID->value = -1;
  58.     newID->name = malloc(sizeof(char) * (strlen(name) + 1));
  59.  
  60.     strcpy(newID->name, name);
  61.     newID->name[strlen(name)] = '\0';
  62.  
  63.     symbols[symbolPointerIndex++] = newID;
  64.  
  65.     return newID;
  66. }
  67.  
  68. void assignVariables()
  69. {
  70.     for (int i = 0; i < symbolPointerIndex; i++)
  71.     {
  72.         printf("Is %s true or false?\n", symbols[i]->name);
  73.         symbols[i]->value = i % 2;
  74.         //getc(stdin); /*UNCOMMENTING THIS CAUSES ISSUES*/
  75.     }
  76. }
  77.  
  78. #define CHUNKLENGTH 8
  79. token** lex()
  80. {
  81.     int chunks = 1;
  82.     int tokensRemaining = CHUNKLENGTH;
  83.     int streamPointer = 0;
  84.     token** stream = malloc(sizeof(token*) * CHUNKLENGTH);
  85.  
  86.     char c;
  87.  
  88.     while ((c = getc(stdin)) != '\n')
  89.     {
  90.         if (isspace(c)) continue;
  91.  
  92.         if (isalpha(c))
  93.         {
  94.             char name[9];
  95.             name[0] = c;
  96.  
  97.             int nPointer;
  98.             for (nPointer = 1; isalpha(c = getc(stdin)) && nPointer < 8; nPointer++)
  99.                 name[nPointer] = c;
  100.             name[nPointer] = '\0';
  101.  
  102.             //consume remaining characters if the identifier is too long
  103.             while (isalpha(c)) c = getc(stdin);
  104.  
  105.             //ask the symbol table for a token for this identifier
  106.             stream[streamPointer++] = createIdentifier(name);
  107.  
  108.             if (c == '\n') break;
  109.  
  110.             ungetc(c, stdin);
  111.             continue;
  112.  
  113.         }
  114.  
  115.         //usually I'd check the different operators, trying to minimise this
  116.         token* new = malloc(sizeof(token));
  117.         new->type = OP;
  118.  
  119.         stream[streamPointer++] = new;
  120.  
  121.         if (!--tokensRemaining)
  122.         {
  123.             if ((stream = realloc(stream, (++chunks * CHUNKLENGTH) * sizeof(token*))) == NULL)
  124.             {
  125.                 fprintf(stderr, "Failed to extend allocated memory for the token stream!\n");
  126.                 free(stream);
  127.                 exit(-1);
  128.             }
  129.             tokensRemaining = CHUNKLENGTH;
  130.         }
  131.  
  132.     }
  133.  
  134.     token* eos = malloc(sizeof(token));
  135.     eos->type = EOS;
  136.     stream[streamPointer] = eos;
  137.  
  138.     return stream;
  139. }
  140.  
  141. int main()
  142. {
  143.     token** stream = lex();
  144.  
  145.     printStream(stream); //fine here, even when done twice
  146.  
  147.     assignVariables();
  148.  
  149.     printStream(stream); //segfault due to missing EOS
  150.  
  151.     return 0;
  152. }
Advertisement
Add Comment
Please, Sign In to add comment