84 lines
1.5 KiB
C
84 lines
1.5 KiB
C
|
#include "tokens.h"
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#ifdef STANDALONE
|
||
|
#include <stdio.h>
|
||
|
#else
|
||
|
#define printf(...) tokenize(NULL)
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* Grammar:
|
||
|
* token
|
||
|
* expr
|
||
|
* (op expr expr)
|
||
|
* (list expr expr ... )
|
||
|
*/
|
||
|
|
||
|
// Is the char a standalone token?
|
||
|
static const char singleTokens[] = "()+-*/";
|
||
|
int isSingle(const char c) {
|
||
|
int i = 0;
|
||
|
while(singleTokens[i] != '\0'){
|
||
|
if(singleTokens[i] == c)
|
||
|
return singleTokens[i];
|
||
|
i++;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int isDigit(const char c) {
|
||
|
return c >= '0' && c <= '9';
|
||
|
}
|
||
|
|
||
|
struct Slice *tokenize(const char *input)
|
||
|
{
|
||
|
if(!input)
|
||
|
return NULL;
|
||
|
|
||
|
struct Slice *slices = malloc(sizeof(struct Slice) * MAX_TOK_CNT);
|
||
|
|
||
|
int i = 0;
|
||
|
int slice = 0;
|
||
|
|
||
|
int parens = 0;
|
||
|
while(input[i] != '\0') {
|
||
|
printf("input: '%c'\n", input[i]);
|
||
|
if(input[i] == '(') {
|
||
|
parens++;
|
||
|
} else if (input[i] == ')') {
|
||
|
parens--;
|
||
|
}
|
||
|
|
||
|
if(isSingle(input[i])) {
|
||
|
slices[slice].text = &input[i];
|
||
|
slices[slice].length = 1;
|
||
|
slice++;
|
||
|
i++;
|
||
|
|
||
|
} else if(isDigit(input[i])) {
|
||
|
slices[slice].text = &input[i];
|
||
|
|
||
|
int l = 1;
|
||
|
while(isDigit(input[++i]))
|
||
|
l++;
|
||
|
|
||
|
slices[slice].length = l;
|
||
|
slice++;
|
||
|
|
||
|
} else { // Whitespace or other uncaught
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(parens){
|
||
|
free(slices);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
slices[slice].text = NULL;
|
||
|
slices[slice].length = 0;
|
||
|
|
||
|
return slices;
|
||
|
}
|