пример лексера, парсера и генератора AST для арифметических выражений.

1. Лексер:

function lexer(expression) {
    let tokens = [];
    let curr = 0;

    while (curr < expression.length) {
        let char = expression[curr];

        if (/\d/.test(char)) {
            let value = ‘’;

            while (/\d/.test(char) && curr < expression.length) {
                value += char;
                char = expression[++curr];
            }

            tokens.push({ type: ‘number’, value: parseInt(value) });
            continue;
        }

        if (char === ‘+’) {
            tokens.push({ type: ‘plus’ });
            curr++;
            continue;
        }

        if (char === ‘-’) {
            tokens.push({ type: ‘minus’ });
            curr++;
            continue;
        }

        if (char === ‘*’) {
            tokens.push({ type: ‘multiply’ });
            curr++;
            continue;
        }

        if (char === ‘/’) {
            tokens.push({ type: ‘divide’ });
            curr++;
            continue;
        }

        // skip whitespaces
        if (/\s/.test(char)) {
            curr++;
            continue;
        }

        throw new Error(Unrecognized token: ${char});
    }

    return tokens;
}


2. Парсер:

function parser(tokens) {

    function walk() {
        let token = tokens[index++];

        if (token.type === ‘number’) {
            return {
                type: ‘NumberLiteral’,
                value: token.value,
            };
        }

        if ([‘plus’, ‘minus’, ‘multiply’, ‘divide’].includes(token.type)) {
            const node = {
                type: ‘BinaryExpression’,
                operator: token.type,
                left: walk(),
                right: walk(),
            };
            return node;
        }

        throw new Error(Unrecognized token and syntax error);
    }

    let index = 0;
    let ast = {
        type: ‘Program’,
        body: [],
    };

    while (index < tokens.length) {
        ast.body.push(walk());
    }

    return ast;
}


3. Анализатор AST и интерпретатор:

function interpreter(ast) {

    function walk(node) {
        switch (node.type) {
            case ‘NumberLiteral’:
                return node.value;
            case ‘BinaryExpression’:
                let left = walk(node.left);
                let right = walk(node.right);

                switch (node.operator) {
                    case ‘plus’:
                        return left + right;
                    case ‘minus’:
                        return left - right;
                    case ‘multiply’:
                        return left * right;
                    case ‘divide’:
                        return left / right;
                }
        }

        throw new Error(‘Unrecognized AST node’);
    }

    let result = walk(ast.body[0]);
    return result;
}


Теперь можно использовать эти три части вместе, чтобы интерпретировать арифметические выражения:

const expression = “3 + 5 * 2 - 4 / 2”;
const tokens = lexer(expression);
const ast = parser(tokens);
const result = interpreter(ast);
console.log(expression, ‘=’, result);

добавь обьявление переменных, вычисление корня любой степени и вычисление любой степени