LINUX.ORG.RU

История изменений

Исправление alysnix, (текущая версия) :

вот парсер на нем самом написал. за 10 сек. проверять код конечно стоит.


// Определение токенов
const TokenType = {
    IDENTIFIER: "IDENTIFIER",
    NUMBER: "NUMBER",
    STRING: "STRING",
    KEYWORD: "KEYWORD",
    OPERATOR: "OPERATOR",
    PUNCTUATION: "PUNCTUATION",
    EOF: "EOF"
};

// Лексер
function lexer(input) {
    let tokens = [];
    let current = 0;

    while (current < input.length) {
        let char = input[current];

        // Пропустить пробелы
        if (/\s/.test(char)) {
            current++;
            continue;
        }

        // Обработка идентификаторов и ключевых слов
        if (/[a-zA-Z_]/.test(char)) {
            let value = '';
            while (/[a-zA-Z0-9_]/.test(char)) {
                value += char;
                char = input[++current];
            }
            tokens.push({
                type: TokenType.KEYWORD,
                value: value
            });
            continue;
        }

        // Обработка чисел
        if (/\d/.test(char)) {
            let value = '';
            while (/\d/.test(char)) {
                value += char;
                char = input[++current];
            }
            tokens.push({
                type: TokenType.NUMBER,
                value: parseInt(value, 10)
            });
            continue;
        }

        // Обработка строк
        if (char === '"') {
            let value = '';
            char = input[++current];
            while (char !== '"' && current < input.length) {
                value += char;
                char = input[++current];
            }
            tokens.push({
                type: TokenType.STRING,
                value: value
            });
            current++; // Пропустить закрывающую кавычку
            continue;
        }

        // Обработка операторов и знаков препинания
        if (['=', ';', '(', ')', '{', '}'].includes(char)) {
            tokens.push({
                type: TokenType.PUNCTUATION,
                value: char
            });
            current++;
            continue;
        }

        // Обработка операторов
        if (['+', '-', '*', '/'].includes(char)) {
            tokens.push({
                type: TokenType.OPERATOR,
                value: char
            });
            current++;
            continue;
        }

        throw new Error(`Неизвестный токен: ${char}`);
    }

    tokens.push({ type: TokenType.EOF });
    return tokens;
}

// Парсер
function parser(tokens) {
    let current = 0;

    function parseStatement() {
        if (tokens[current].type === TokenType.KEYWORD && tokens[current].value === 'let') {
            current++; // Пропустить 'let'
            const identifier = tokens[current++];
            if (tokens[current].type !== TokenType.PUNCTUATION || tokens[current].value !== '=') {
                throw new Error("Ожидался '=' после объявления переменной.");
            }
            current++; // Пропустить '='
            const expression = parseExpression();
            if (tokens[current].type !== TokenType.PUNCTUATION || tokens[current].value !== ';') {
                throw new Error("Ожидалась ';' в конце выражения.");
            }
            current++; // Пропустить ';'
            return {
                type: 'VariableDeclaration',
                identifier: identifier.value,
                value: expression
            };
        }

        throw new Error("Неизвестное выражение.");
    }

    function parseExpression() {
        if (tokens[current].type === TokenType.NUMBER) {
            return {
                type: 'Literal',
                value: tokens[current++].value
            };
        }
        if (tokens[current].type === TokenType.STRING) {
            return {
                type: 'Literal',
                value: tokens[current++].value
            };
        }
        if (tokens[current].type === TokenType.KEYWORD) {
            return {
                type: 'Identifier',
                name: tokens[current++].value
            };
        }
        throw new Error("Неизвестное выражение.");
    }

    function parseProgram() {
        const statements = [];
        while (tokens[current].type !== TokenType.EOF) {
            statements.push(parseStatement());
        }
        return {
            type: 'Program',
            body: statements
        };
    }

    return parseProgram();
}

// Пример использования
const input = `

парсер неполный конечно. у меня бесплатное, размер окна - маленький

Исходная версия alysnix, :

вот парсер на нем самом написал. за 10 сек. проверять код конечно стоит.


// Определение токенов
const TokenType = {
    IDENTIFIER: "IDENTIFIER",
    NUMBER: "NUMBER",
    STRING: "STRING",
    KEYWORD: "KEYWORD",
    OPERATOR: "OPERATOR",
    PUNCTUATION: "PUNCTUATION",
    EOF: "EOF"
};

// Лексер
function lexer(input) {
    let tokens = [];
    let current = 0;

    while (current < input.length) {
        let char = input[current];

        // Пропустить пробелы
        if (/\s/.test(char)) {
            current++;
            continue;
        }

        // Обработка идентификаторов и ключевых слов
        if (/[a-zA-Z_]/.test(char)) {
            let value = '';
            while (/[a-zA-Z0-9_]/.test(char)) {
                value += char;
                char = input[++current];
            }
            tokens.push({
                type: TokenType.KEYWORD,
                value: value
            });
            continue;
        }

        // Обработка чисел
        if (/\d/.test(char)) {
            let value = '';
            while (/\d/.test(char)) {
                value += char;
                char = input[++current];
            }
            tokens.push({
                type: TokenType.NUMBER,
                value: parseInt(value, 10)
            });
            continue;
        }

        // Обработка строк
        if (char === '"') {
            let value = '';
            char = input[++current];
            while (char !== '"' && current < input.length) {
                value += char;
                char = input[++current];
            }
            tokens.push({
                type: TokenType.STRING,
                value: value
            });
            current++; // Пропустить закрывающую кавычку
            continue;
        }

        // Обработка операторов и знаков препинания
        if (['=', ';', '(', ')', '{', '}'].includes(char)) {
            tokens.push({
                type: TokenType.PUNCTUATION,
                value: char
            });
            current++;
            continue;
        }

        // Обработка операторов
        if (['+', '-', '*', '/'].includes(char)) {
            tokens.push({
                type: TokenType.OPERATOR,
                value: char
            });
            current++;
            continue;
        }

        throw new Error(`Неизвестный токен: ${char}`);
    }

    tokens.push({ type: TokenType.EOF });
    return tokens;
}

// Парсер
function parser(tokens) {
    let current = 0;

    function parseStatement() {
        if (tokens[current].type === TokenType.KEYWORD && tokens[current].value === 'let') {
            current++; // Пропустить 'let'
            const identifier = tokens[current++];
            if (tokens[current].type !== TokenType.PUNCTUATION || tokens[current].value !== '=') {
                throw new Error("Ожидался '=' после объявления переменной.");
            }
            current++; // Пропустить '='
            const expression = parseExpression();
            if (tokens[current].type !== TokenType.PUNCTUATION || tokens[current].value !== ';') {
                throw new Error("Ожидалась ';' в конце выражения.");
            }
            current++; // Пропустить ';'
            return {
                type: 'VariableDeclaration',
                identifier: identifier.value,
                value: expression
            };
        }

        throw new Error("Неизвестное выражение.");
    }

    function parseExpression() {
        if (tokens[current].type === TokenType.NUMBER) {
            return {
                type: 'Literal',
                value: tokens[current++].value
            };
        }
        if (tokens[current].type === TokenType.STRING) {
            return {
                type: 'Literal',
                value: tokens[current++].value
            };
        }
        if (tokens[current].type === TokenType.KEYWORD) {
            return {
                type: 'Identifier',
                name: tokens[current++].value
            };
        }
        throw new Error("Неизвестное выражение.");
    }

    function parseProgram() {
        const statements = [];
        while (tokens[current].type !== TokenType.EOF) {
            statements.push(parseStatement());
        }
        return {
            type: 'Program',
            body: statements
        };
    }

    return parseProgram();
}

// Пример использования
const input = `