Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include "tokenizer.h"
- //-----------------TOKENIZE LOGIC-----------------
- ops *
- tokenize(char *c) {
- ops *op = malloc(sizeof(ops));
- check_memory(op, "op", "tokenize");
- size_t token_len = strnlen(c, MAX_TOKEN_LENGTH);
- op->value = malloc(token_len + 1);
- strncpy(op->value, c, token_len);
- //if its a token
- size_t len = strnlen(c, MAX_TOKEN_LENGTH);
- unsigned int found = 0;
- for (int i = 0; i < token_co; i++) {
- if (tokens[i].len == len) {
- if (strcmp(tokens[i].name, c) == 0) {
- op->type = tokens[i].type;
- op->prec = tokens[i].prec;
- op->asoc = tokens[i].asoc;
- found = 1;
- }
- }
- }
- //if its a number
- if (!found && is_number(c)) {
- op->asoc = -1;
- op->prec = NONE_P;
- op->type = CONSTANT;
- found = 1;
- }
- return found ? op : NULL;
- }
- int is_number(const char *str)
- {
- char *p = str;
- while (*p != '\0') {
- if ((*p >= '0' && *p <= '9') || *p == '.') {
- *p++;
- }
- else {
- return 0;
- }
- }
- return 1;
- }
- int check_memory(void *pt, const char* name, const char* function) {
- if (!pt) {
- printf("Memory allocation has failed on variable: %s in function: %s\n", name, function);
- exit(1);
- }
- }
- //-----------------STACK LOGIC-----------------
- stack *
- create_stack(unsigned int size) {
- stack *stack = malloc(sizeof(stack));
- check_memory(stack, "stack", "create_stack");
- stack->s = calloc(sizeof(ops*), size);
- check_memory(stack->s, "stack->s", "create_stack");
- stack->count = 0;
- stack->size = size;
- return stack;
- }
- void
- s_push(stack *st, ops *o) {
- st->s[st->count++] = o;
- }
- ops *
- s_pop(stack *st) {
- ops *op = st->s[st->count - 1];
- st->count--;
- st->s[st->count] = NULL;
- return op;
- }
- ops *
- s_peek(stack *st) {
- return st->s[st->count - 1];
- }
- void
- free_stack(stack *st) {
- for (int i = 0; i < st->count;i++) {
- if (st->s[i]) {
- //clear ops struct memory
- if (st->s[i]->value) {
- free(st->s[i]->value);
- }
- //clear pointer to stack node
- free(st->s[i]);
- }
- }
- if (st) {
- //clear stack
- free(st);
- }
- }
- //-----------------QUEUE LOGIC-----------------
- queue *create_queue(unsigned int size) {
- queue *que = malloc(sizeof(queue));
- check_memory(que, "que", "create_queue");
- que->count = 0;
- que->size = size;
- que->s1 = create_stack(size);
- que->s2 = create_stack(size);
- return que;
- }
- void q_enqueue(queue *q, ops *o) {
- while (q->s1->count != 0) {
- s_push(q->s2, s_pop(q->s1));
- }
- s_push(q->s1, o);
- while (q->s2->count != 0) {
- s_push(q->s1, s_pop(q->s2));
- }
- }
- ops *q_dequeue(queue *q) {
- if (q->s1->count > 0) {
- return s_pop(q->s1);
- }
- else {
- return NULL;
- }
- }
- ops *q_peek(queue *q) {
- if (q->s1->count > 0) {
- return s_peek(q->s1);
- }
- else {
- return NULL;
- }
- }
- void free_queue(queue *q) {
- free_stack(q->s1);
- free_stack(q->s2);
- if (q) {
- free(q);
- }
- }
- //-----------------TOKENIZER LOGIC-----------------
- char *next_token(char *exp, char **save) {
- char *pt = exp, *tok = NULL;
- if (exp == NULL) {
- pt = *save;
- }
- //ignore space OR column
- while (*pt == ' ' || *pt == ',') {
- pt++;
- }
- //check for tokens
- for (int i = 0; i < token_co; i++) {
- if (*pt == tokens[i].name[0]) {
- if (tokens[i].len > 1) {
- size_t st = 1, en = tokens[i].len - 1;
- while (st <= en) {
- if (*++pt != tokens[i].name[st++]) {
- //ERROR
- return NULL;
- }
- }
- tok = malloc(tokens[i].len + 1);
- check_memory(tok, "tok", "next_token");
- strncpy(tok, tokens[i].name, tokens[i].len + 1);
- }
- //token size is only 1
- else {
- tok = malloc(2);
- check_memory(tok, "tok", "next_token");
- memcpy(tok, tokens[i].name, 2);
- break;
- }
- }
- }
- //check for numbers
- char buffer[MAX_TOKEN_LENGTH];
- memset(buffer, '\0', MAX_TOKEN_LENGTH);
- size_t i = 0;
- while (isdigit(*pt) || *pt == '.') {
- buffer[i++] = *pt++;
- }
- if (i > 0) {
- tok = malloc(i + 1);
- check_memory(tok, "tok", "next_token");
- strncpy(tok, buffer, i + 1);
- //need to recall one pointer back because of upper while loop
- *pt--;
- }
- *save = pt + 1;
- return tok;
- }
- ----------------------------------------------------------------------------------
- #ifndef _TOKENIZER_H_INCLUDED_
- #define _TOKENIZER_H_INCLUDED_
- //------------TOKENIZER------------
- #define MAX_TOKEN_LENGTH 20
- #define MAX_STACK_SIZE 256
- typedef enum { L_AS = 1, R_AS = 2, NONE_P = 3 } associativity;
- typedef enum { FUNCTION = 1, NUMBER = 2, OPERATOR = 3, CONSTANT = 4, LEFT_P = 5, RIGHT_P = 6 } token_type;
- typedef struct {
- const char *name;
- const int len, prec;
- const associativity asoc;
- const token_type type;
- } token;
- typedef struct {
- char *value;
- int prec;
- associativity asoc;
- token_type type;
- } ops;
- static token tokens[] = {
- { "+", 1, 2, L_AS, OPERATOR },
- { "-", 1, 2, L_AS, OPERATOR },
- { "/", 1, 3, L_AS, OPERATOR },
- { "*", 1, 3, L_AS, OPERATOR },
- { "^", 1, 4, R_AS, OPERATOR },
- { "sin", 3, -1, NONE_P, FUNCTION },
- { "cos", 3, -1, NONE_P, FUNCTION },
- { "tan", 3, -1, NONE_P, FUNCTION },
- { "max", 3, -1, NONE_P, FUNCTION },
- { "(", 1, -1, NONE_P, LEFT_P },
- { ")", 1, -1, NONE_P, RIGHT_P },
- { "x", 1, -1, NONE_P, CONSTANT },
- { "e", 1, -1, NONE_P, CONSTANT },
- { "pi", 2, -1, NONE_P, CONSTANT },
- { "log", 3, -1, NONE_P, FUNCTION },
- { "ln", 2, -1, NONE_P, FUNCTION }
- };
- static unsigned int token_co = sizeof(tokens) / sizeof(tokens[0]);
- char *next_token(const char *exp, char **save);
- ops *tokenize(char *c);
- int is_number(const char *str);
- int check_memory(void *pt, const char* name, const char* function);
- //------------STACK------------
- typedef struct {
- ops **s;
- unsigned int size;
- unsigned int count;
- } stack;
- stack *create_stack(unsigned int size);
- void s_push(stack *st, ops *o);
- ops *s_pop(stack *st);
- ops *s_peek(stack *st);
- void free_stack(stack *st);
- //------------QUEUE------------
- typedef struct {
- stack *s1, *s2;
- unsigned int size;
- unsigned int count;
- } queue;
- queue *create_queue(unsigned int size);
- void q_enqueue(queue *q, ops *o);
- ops *q_dequeue(queue *q);
- ops *q_peek(queue *q);
- void free_queue(queue *q);
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement