История изменений
Исправление 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 = `