Задать вопрос
@sakair

Почему мой лексер выдает неизвестные токены?

Я пишу простой лексер для перевода русских инструкций на стандартные nasm инструкции...
Мой sasm.c код
#include <stdio.h>

#include "lexer.h"

int main() {
	char text[] = "пер ар 10";
    char *content = text;

	printf("%s\n\n", text);

    Token token;
    while ((token = lexer(&content)).type != TOKEN_EOF) {
        printf("Token: Type = %d, Name = '%s'\n", token.type, token.name[0] ? token.name : "Empty");
    }

	return 0;
}

А вот мой lexer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "lexer.h"

static int pos = 0; // Позиция для лексера

static void skip_whitespace_and_comments(char **input) {
    while (isspace((*input)[pos]) || ((*input)[pos] == ';')) {
        if ((*input)[pos] == ';') {
            while ((*input)[pos] != '\n' && (*input)[pos] != '\0') {
                pos++;
            }
        } else {
            pos++;
        }
    }
}

Token lexer(char **input) {
    Token token;
    memset(&token, 0, sizeof(Token)); // Обнуляем структуру токена

    skip_whitespace_and_comments(input); 

    if ((*input)[pos] == '\0') {
        token.type = TOKEN_EOF;
        return token;
    }

    // Обработка команд
    if (strncmp(&(*input)[pos], "пер", 3) == 0) {
        token.type = MOV;
        strncpy(token.name, "mov", sizeof(token.name));
        pos += 3;
    } 
    else if (strncmp(&(*input)[pos], "ар", 2) == 0) {
        token.type = RAX; 
        strncpy(token.name, "rax", sizeof(token.name));
        pos += 2;
    } 
    else if (isdigit((*input)[pos])) {
        token.type = TOKEN_NUMBER;
        char num[50];
        int i = 0;

        while (isdigit((*input)[pos])) {
            if (i < sizeof(num) - 1) {
                num[i++] = (*input)[pos];
            }
            pos++;
        }
        num[i] = '\0';
        strncpy(token.name, num, sizeof(token.name)); 
    } else {
        // Обработка неизвестного токена
        pos++; // пропуск неизвестного символа
    }
    return token;
}

Вывод bash
./sasm
пер ар 10

Token: Type = 0, Name = 'mov'
Token: Type = 0, Name = 'Empty'
Token: Type = 0, Name = 'Empty'
Token: Type = 0, Name = 'Empty'
Token: Type = 7, Name = 'rax'
Token: Type = 0, Name = 'Empty'
Token: Type = 0, Name = 'Empty'
Token: Type = 16, Name = '10'

Сначало я подумал, что проблема в кодировки, но все файлы в UTF-8 кодировки, так же вместо "пер" я попробовал сравнивать напрямую в код UTF-8, вот пример strncmp(&(*input)[pos], "\xD0\xBF\xD0\xB5\xD1\x80", 6) == 0.
Я использую clang, но и с gcc такая же проблема, просьба помочь.
  • Вопрос задан
  • 38 просмотров
Подписаться 1 Средний 2 комментария
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Разработчик C++
    9 месяцев
    Далее
  • Нетология
    Специалист по информационной безопасности + нейросети
    12 месяцев
    Далее
  • Компьютерная академия «TOP»
    Учебная программа “Разработка программного обеспечения”
    30 месяцев
    Далее
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы