Creating a parser in C for DSL calculator

61 views Asked by At

I tried to fix the error on line 137 of the code. As a result I get an exit code -1. And error:

note: expected 'const char * const' but argument is of type 'int'
 1917 | CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string)
      |                                                                                    ~~~~~~~~~~~~~~~~~~~^~~~~~
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: cannot open output file D:\C\DSL\parser.exe: Permission denied
collect2.exe: error: ld returned 1 exit status

Build finished with error(s).

How can I solve it? Is my code good or something must be changed?

#include <stdio.h>
#include <stdlib.h>
#include <limits.h> 
#include "cJSON.h"
#include "cJSON.c"

enum TokenType {
    TOKEN_INT_DECL,
    TOKEN_DOUBLE_DECL,
    TOKEN_INT_LITERAL,
    TOKEN_DOUBLE_LITERAL,
    TOKEN_IDENTIFIER,
    TOKEN_PLUS,
    TOKEN_MINUS,
    TOKEN_MULTI,
    TOKEN_DIVISION,
    TOKEN_ASSIGN,
    TOKEN_LESS,
    TOKEN_GREATER,
    TOKEN_EQUAL,
    TOKEN_LESS_OR_EQUAL,
    TOKEN_GREATER_OR_EQUAL,
    TOKEN_OPEN_PAREN,
    TOKEN_CLOSE_PAREN,
    TOKEN_OPEN_BRACE,
    TOKEN_CLOSE_BRACE,
    TOKEN_PRINT,
    TOKEN_INPUT,
    TOKEN_WHILE,
    TOKEN_CONDITION,
    TOKEN_THEN,
    TOKEN_ELSE,
    TOKEN_IF,
    TOKEN_EOF,
    TOKEN_ERROR
};

typedef struct Node {
    enum TokenType type;
    char lexeme[50];
    struct Node* left;
    struct Node* right;
} Node;

Node* parseTokens(cJSON *tokens, int start, int end);

Node* parse(cJSON *json_data_parsed) {
    cJSON *tokens = cJSON_GetObjectItemCaseSensitive(json_data_parsed, "tokens");
    if (cJSON_IsArray(tokens)) {
        int array_size = cJSON_GetArraySize(tokens);
        if (array_size > 0) {
            return parseTokens(tokens, 0, array_size - 1);
        } else {
            fprintf(stderr, "Error: Empty array of tokens.\n");
            return NULL;
        }
    } else {
        fprintf(stderr, "Error: field 'tokens' isn't an array.\n");
        return NULL;
    }
}

Node* parseTokens(cJSON *tokens, int start, int end) {
    if (start > end) {
        return NULL; // Base case: no tokens to process
    }

    // Finding the lowest-precedence operator
    int lowestPrecedence = INT_MAX; // Using INT_MAX for initialization
    int lowestPrecedenceIndex = -1;

    for (int i = end; i >= start; i--) {
        cJSON *token = cJSON_GetArrayItem(tokens, i);

        if (cJSON_IsObject(token)) {
            cJSON *type = cJSON_GetObjectItemCaseSensitive(token, "type");

            if (cJSON_IsString(type)) {
                enum TokenType tokenType = (enum TokenType)atoi(type->valuestring);

                int currentPrecedence = 0;

                // Determining the precedence of the current operator
                switch (tokenType) {
                    case TOKEN_MULTI:
                    case TOKEN_DIVISION:
                        currentPrecedence = 2;
                        break;
                    case TOKEN_PLUS:
                    case TOKEN_MINUS:
                        currentPrecedence = 1;
                        break;
                    default:
                        currentPrecedence = 0;
                        break;
                }

                // Checking for the lowest precedence
                if (currentPrecedence <= lowestPrecedence) {
                    lowestPrecedence = currentPrecedence;
                    lowestPrecedenceIndex = i;
                }
            }
        }
    }

    // If no operator is found, create a leaf node
    if (lowestPrecedenceIndex == -1) {
        cJSON *token = cJSON_GetArrayItem(tokens, start);
        if (cJSON_IsObject(token)) {
            cJSON *type = cJSON_GetObjectItemCaseSensitive(token, "type");
            cJSON *lexeme = cJSON_GetObjectItemCaseSensitive(token, "lexeme");
            if (cJSON_IsString(type) && cJSON_IsString(lexeme)) {
                Node* leafNode = (Node*)malloc(sizeof(Node));
                leafNode->type = (enum TokenType)atoi(type->valuestring);
                snprintf(leafNode->lexeme, sizeof(leafNode->lexeme), "%s", lexeme->valuestring);
                leafNode->left = NULL;
                leafNode->right = NULL;
                return leafNode;
            } else {
                fprintf(stderr, "Error: Token structure is invalid.\n");
                return NULL;
            }
        } else {
            fprintf(stderr, "Error: Token is not an object.\n");
            return NULL;
        }
    }

    // Recursive call for left and right subtrees
    Node* left = parseTokens(tokens, start, lowestPrecedenceIndex - 1);
    Node* right = parseTokens(tokens, lowestPrecedenceIndex + 1, end);

    // Creating an operator node
    Node* expressionNode = (Node*)malloc(sizeof(Node));
   cJSON *typeToken = cJSON_GetObjectItemCaseSensitive(tokens, lowestPrecedenceIndex)->valuestring;
    if (cJSON_IsString(typeToken)) {
        // Use the string directly without converting to integer
        expressionNode->type = getTokenTypeFromString(typeToken);
    } else {
        // Handle the error case
        fprintf(stderr, "Error: Token type is not a string.\n");
        return NULL;
    }
    snprintf(expressionNode->lexeme, sizeof(expressionNode->lexeme), "%s", cJSON_GetObjectItemCaseSensitive(tokens, lowestPrecedenceIndex)->valuestring);

    expressionNode->left = left;
    expressionNode->right = right;

    return expressionNode;
}


int main() {
    FILE *file = fopen("tokens.json", "r");
    if (!file) {
        fprintf(stderr, "Error during opening the file tokens.json\n");
        return 1;
    }

    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    fseek(file, 0, SEEK_SET);
    char *json_data = (char *)malloc(file_size + 1);
    fread(json_data, 1, file_size, file);
    fclose(file);
    json_data[file_size] = '\0';

    cJSON *json_data_parsed = cJSON_Parse(json_data);
    if (!json_data_parsed) {
        const char *error_ptr = cJSON_GetErrorPtr();
        if (error_ptr != NULL) {
            fprintf(stderr, "Error printing JSON: %s\n", error_ptr);
        }
        free(json_data);
        return 1;
    }

    Node* ast = parse(json_data_parsed);
}

I want to parse tokens from json file and return ast for interpretor...

0

There are 0 answers