start implimenting a parser

This commit is contained in:
2025-05-27 17:19:09 +01:00
parent 3dedd7f348
commit 43bc7663fc
14 changed files with 241 additions and 195 deletions

20
src/parser/parser.c Normal file
View File

@@ -0,0 +1,20 @@
#include "parser.h"
TaggedValue parse_token(TokenStruct * tokenStruct, int *index) {
Token token = tokenStruct->tokens[*index];
switch (token.type) {
case TOKEN_STRING:
index++;
return parse_string(token);
default:
perror("unreachable");
exit(0);
}
}
void parser(TaggedValueStruct * taggedValueStruct, TokenStruct * tokenStruct, bool inline_flag) {
int index = 0;
while (index < tokenStruct->count) {
TaggedValueStruct_append(taggedValueStruct, parse_token(tokenStruct, &index));
}
}

9
src/parser/parser.h Normal file
View File

@@ -0,0 +1,9 @@
#include "../lexer/token.h"
#include "string/string.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
void parser(TaggedValueStruct * TaggedValueStruct, TokenStruct * tokenStruct, bool inline_flag);
TaggedValue parse_token(TokenStruct * tokenStruct, int *index);

View File

@@ -0,0 +1,78 @@
#include "string.h"
#include "../../lexer/token.h"
#include <cjson/cJSON.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
char *swap_quotes(const char *input) {
size_t len = strlen(input);
char *result = malloc(len + 1);
if (!result)
return NULL;
for (size_t i = 0; i < len; ++i) {
if (input[i] == '"')
result[i] = '\'';
else if (input[i] == '\'')
result[i] = '"';
else
result[i] = input[i];
}
result[len] = '\0';
return result;
}
char *unquote(const char *str) {
if (*str == '\0')
return NULL;
char quote = str[0];
char *swapped = NULL;
char *unescaped = NULL;
if (quote == '\'') {
swapped = swap_quotes(str);
if (!swapped)
return NULL;
str = swapped;
}
cJSON *json = cJSON_Parse(str);
if (!json || !cJSON_IsString(json)) {
if (swapped)
free(swapped);
return NULL;
}
// Copy unescaped string before freeing JSON object
const char *decoded = cJSON_GetStringValue(json);
if (!decoded) {
cJSON_Delete(json);
if (swapped)
free(swapped);
return NULL;
}
unescaped = strdup(decoded);
cJSON_Delete(json);
if (swapped)
free(swapped);
// If input was single-quoted, swap quotes back in the output
if (quote == '\'') {
char *final = swap_quotes(unescaped);
free(unescaped);
return final;
}
return unescaped;
}
TaggedValue parse_string(Token token) {
return (TaggedValue){
TYPE_STRING,
unquote(token.value)
};
}

View File

@@ -0,0 +1,8 @@
#include "../../lexer/token.h"
#include "../taggedValue.h"
char *swap_quotes(const char *input);
char *unquote(const char *str);
TaggedValue parse_string(Token token);

26
src/parser/taggedValue.c Normal file
View File

@@ -0,0 +1,26 @@
#include "taggedValue.h"
#include <stdlib.h>
TaggedValueStruct init_TaggedValueStruct() {
TaggedValueStruct taggedValueStruct = {
0,
INITIAL_CAPACITY,
malloc(sizeof(TaggedValue)*INITIAL_CAPACITY)
};
return taggedValueStruct;
}
void TaggedValueStruct_append(TaggedValueStruct *TaggedValueStruct,
TaggedValue TaggedValue) {
if (TaggedValueStruct->count >= TaggedValueStruct->capacity) {
TaggedValueStruct->capacity *= 2;
TaggedValueStruct->TaggedValue =
realloc(TaggedValueStruct->TaggedValue,
sizeof(TaggedValue) * TaggedValueStruct->capacity);
}
TaggedValueStruct[TaggedValueStruct->count].TaggedValue->data =
TaggedValue.data;
TaggedValueStruct[TaggedValueStruct->count].TaggedValue->type =
TaggedValue.type;
TaggedValueStruct->count++;
}

23
src/parser/taggedValue.h Normal file
View File

@@ -0,0 +1,23 @@
typedef enum {
TYPE_STRING,
} ValueType;
typedef struct {
ValueType type;
void *data;
} TaggedValue;
#define INITIAL_CAPACITY 64
typedef struct {
int count;
int capacity;
TaggedValue * TaggedValue;
} TaggedValueStruct;
TaggedValueStruct init_TaggedValueStruct();
void TaggedValueStruct_append(TaggedValueStruct *TaggedValueStruct,
TaggedValue TaggedValue);