我一直在try 制作一种小型编程语言,但我想不出如何让我的解释器存储和调用变量

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_VARIABLES 10

// Structure to store variables
struct Variable {
    char name[50];
    char value[256];
};

// Array to store variables
struct Variable variables[MAX_VARIABLES];
int variableCount = 0;

// Function to find a variable by name
struct Variable *findVariable(const char *name) {
    for (int i = 0; i < variableCount; ++i) {
        if (strcmp(variables[i].name, name) == 0) {
            return &variables[i];
        }
    }
    return NULL; // Variable not found
}

// Function to interpret commands
void interpretCommand(const char *command) {
    if (strncmp(command, "console:write->", 15) == 0) {
        // Extract the message within double quotes
        const char *messageStart = strchr(command, '"');
        const char *messageEnd = strrchr(command, '"');

        if (messageStart != NULL && messageEnd != NULL && messageStart < messageEnd) {
            // Print the message, replacing variables if present
            for (const char *p = messageStart + 1; p < messageEnd; ++p) {
                if (*p == '*') {
                    ++p; // Move past '*'
                    const char *varStart = p;
                    while (*p != '*' && p < messageEnd) {
                        ++p;
                    }

                    char varName[50];
                    strncpy(varName, varStart, p - varStart);
                    varName[p - varStart] = '\0';

                    struct Variable *variable = findVariable(varName);
                    if (variable != NULL) {
                        printf("%s", variable->value);
                    } else {
                        printf("Undefined variable: %s", varName);
                    }
                } else {
                    putchar(*p);
                }
            }
            putchar('\n');
        } else {
            printf("Invalid message format\n");
        }
    } else if (strncmp(command, "console:read->", 14) == 0) {
      // Extract the prompt within double quotes
      const char *promptStart = strchr(command, '"');
      const char *promptEnd = strrchr(command, '"');

      if (promptStart != NULL && promptEnd != NULL && promptStart < promptEnd) {
          // Print the prompt and read user input
          printf("%.*s", (int)(promptEnd - promptStart - 1), promptStart + 1);

          // Read user input
          char userInput[256]; // Adjust size as needed
          fgets(userInput, sizeof(userInput), stdin);

      } else {
          printf("Invalid prompt format\n");
      }
    } else {
        // Check if the command starts with "variableName->"
        char *arrow = strstr(command, "->");
        if (arrow != NULL) {
            *arrow = '\0'; // Separate variable name and value

            // Find or create a variable with the given name
            struct Variable *variable = findVariable(command);
            if (variable == NULL) {
                if (variableCount < MAX_VARIABLES) {
                    strcpy(variables[variableCount].name, command);
                    variable = &variables[variableCount++];
                } else {
                    printf("Maximum number of variables reached\n");
                    return;
                }
            }

            // Copy the value to the variable
            strcpy(variable->value, arrow + 2);
        } else {
            printf("Unknown command\n");
        }
    }
}

int main() {
    // Open the file
    FILE *file = fopen("King.roar", "r");

    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }

    char line[256]; // Assuming a maximum line length of 255 characters

    // Read and interpret each line from the file
    while (fgets(line, sizeof(line), file) != NULL) {
        // Remove newline character if present
        size_t len = strlen(line);
        if (len > 0 && line[len - 1] == '\n') {
            line[len - 1] = '\0';
        }

        // Interpret the command
        interpretCommand(line);
    }

    // Close the file
    fclose(file);

    return 0;
}

这是我存储在King.roar中的示例代码:

console:read->"Enter your name: "->name
console:read->"Enter your age: "->age
console:write->"Hello *name*!"
console:write->"You are *age* years old!"

由于某种原因,我只得到了未定义的变量,我不知道是数据没有存储,还是召回不起作用

我试着在网上查了一下,但什么也没找到.谢谢你的帮助!

推荐答案

将值存储到变量中的代码似乎是

variable_name->value

但在文件中,您似乎使用了不同的语法:

console:read->"Enter your name: "->name

它似乎更一致地使用

value->variable_name

并使用将由控制台方法和其他语法设置的current value.

以下是修改后的版本:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_VARIABLES 10

// Structure to store variables
struct Variable {
    char name[50];
    char value[256];
};

// Array to store variables
struct Variable variables[MAX_VARIABLES];
int variableCount = 0;

// Function to find a variable by name
struct Variable *findVariable(const char *name, size_t len) {
    for (int i = 0; i < variableCount; ++i) {
        if (memcmp(variables[i].name, name, len) == 0
        &&  variables[i].name[len] == '\0') {
            return &variables[i];
        }
    }
    return NULL; // Variable not found
}

void console_write(const char *s, size_t len) {
    // Print the message, replacing variables if present
    for (const char *p = s, *end = s + len; p < end; p++) {
        if (*p == '*' && ++p < end && *p != '*') {
            const char *varName = p;
            while (p < end && *p != '*') {
                ++p;
            }
            size_t nameLen = p - varName;
            struct Variable *variable = findVariable(varName, nameLen);
            if (variable != NULL) {
                printf("%s", variable->value);
            } else {
                fprintf(stderr, "Undefined variable: %.*s\n", (int)nameLen, varName);
            }
        } else {
            putchar(*p);
        }
    }
}

// Function to interpret commands
int interpretCommand(const char *line) {
    char current_value[250];

    *current_value = '\0';
    for (const char *command = line; *command;) {
        if (strncmp(command, "console:write->", 15) == 0) {
            // Extract the message within double quotes
            const char *messageStart = strchr(command, '"');
            const char *messageEnd = strrchr(command, '"');
            if (messageStart == NULL || messageEnd == NULL || messageStart >= messageEnd) {
                fprintf(stderr, "Invalid message format\n");
                return 1;
            }
            console_write(messageStart + 1, messageEnd - messageStart - 1);
            putchar('\n');
            command = messageEnd + 1;
        } else
        if (strncmp(command, "console:read->", 14) == 0) {
            // Extract the prompt within double quotes
            const char *promptStart = strchr(command, '"');
            const char *promptEnd = strrchr(command, '"');
            if (promptStart == NULL || promptEnd == NULL || promptStart >= promptEnd) {
                fprintf(stderr, "Invalid prompt format\n");
                return 1;
            }
            // Print the prompt and read user input
            console_write(promptStart + 1, promptEnd - promptStart - 1);
            // Read user input
            fgets(current_value, sizeof(current_value), stdin);
            size_t len = strlen(current_value);
            if (len > 0 && current_value[len - 1] == '\n')
                current_value[--len] = '\0';
            command = promptEnd + 1;
        } else
        if (!strncmp(command, "->", 2)) {
            // ->variableName
            const char *name = command + 2;
            size_t len = strlen(name);
            struct Variable *variable = findVariable(name, len);
            if (variable == NULL) {
                if (len >= sizeof(variable->name)) {
                    fprintf(stderr, "Variable name too long: %.*s\n", (int)len, name);
                    return 1;
                }
                if (variableCount >= MAX_VARIABLES) {
                    fprintf(stderr, "Maximum number of variables reached\n");
                    return 1;
                }
                memcpy(variables[variableCount].name, name, len);
                variables[variableCount].name[len] = '\0';
                variable = &variables[variableCount++];
            }
            strcpy(variable->value, current_value);
            command = name + len;
        } else
        if (*command == '\"') {
            // string value
            const char *valueStart = command;
            const char *valueEnd = strrchr(command, '"');
            if (valueStart >= valueEnd) {
                fprintf(stderr, "Unterminated value string: %s\n", command);
                return 1;
            }
            size_t len = valueEnd - valueStart - 1;
            if (len >= sizeof(current_value)) {
                fprintf(stderr, "Value string too long: %.*s\n", (int)len + 1, valueStart);
                return 1;
            }
            memcpy(current_value, valueStart + 1, len);
            current_value[len] = '\0';
            command = valueEnd + 1;
        } else {
            char *arrow = strstr(command, "->");
            if (arrow != NULL) {
                size_t len = arrow - command;
                struct Variable *variable = findVariable(command, len);
                if (variable == NULL) {
                    fprintf(stderr, "Unknown variable: %.*s\n", (int)len, command);
                    return 1;
                }
                strcpy(current_value, variable->value);
            } else {
                fprintf(stderr, "Unknown command: %s\n", command);
            }
        }
    }
    return 0;
}

int main(int argc, char *argv[]) {
    // Open the file
    const char *filename = argc > 1 ? argv[1] : "King.roar";
    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        fprintf(stderr, "Error opening file %s: %s", filename, strerror(errno));
        return 1;
    }

    char line[256]; // Assuming a maximum line length of 255 characters

    // Read and interpret each line from the file
    while (fgets(line, sizeof(line), file) != NULL) {
        // Remove newline character if present
        size_t len = strlen(line);
        if (len > 0 && line[len - 1] == '\n') {
            line[len - 1] = '\0';
        }

        // Interpret the command
        if (interpretCommand(line))
            break;
    }

    // Close the file
    fclose(file);

    return 0;
}

C++相关问答推荐

C/C++中的状态库

编译SDL 2时缺少SDL_ttf

使用单个字节内的位字段

为什么在Linux(特别是Ubuntu 20.04LTS)上,POSIX共享内存对象在重启后仍然存在,然后突然变成了根用户?

在传统操作系统上可以在虚拟0x0写入吗?

Ruby C Api处理异常

C中的指针增量和减量(*--*++p)

当输入负数时,排序算法存在问题

在Rust和C之间使用ffi时如何通过 struct 中的[U8;1]成员传递指针

如何按顺序将所有CSV文件数据读入 struct 数组?

如何使用FSeek和文件流指针在C中查找文件的前一个元素和前一个减go 一个元素

C整型和_泛型.哪些类型是兼容的?

Tic-tac-toe:从文件加载存储

如何在VSCode中创建和使用我自己的C库?

如何使这个While循环在新行上结束

从BIOS(8086)中读取刻度需要多少?

我可以创建适用于不同endian的 colored颜色 struct 吗?

静态初始化顺序失败是否适用于C语言?

C23标准是否向后兼容?

`void foo(int a[static 0]);` 有效吗?