Исправление Int64, (текущая версия) :
Можно написать парсер и без конечного автомата, пример рекурсивный спуск. Парсеры из конечных автоматов обычно вручную не пишутся, а используют какой нибудь bison.
пришла открывающая скобка - заводим новый узел EXPR и уходим в него; пришла закрывающая скобрка - смотрим в EXRP ли мы находимся и если да, то финализируем EXPR, иначе же имеем невалидный исходник.
Что мешает при этом не создавать нод, а просто написать что-то вроде:
if (currentToken == '(') {
nextToken(); // Пропускаю скобку
expr = parseExpr();
nextToken();
if (currentToken != ')')
throw ParserError("Ошибка!", pos, line);
return expr; // Вернул только выражение, скобки мне не нужны
}
Исправление Int64, :
Можно написать парсер и без конечного автомата, пример рекурсивный спуск. Парсеры из конечных автоматов обычно вручную не пишутся, а используют какой нибудь bison.
пришла открывающая скобка - заводим новый узел EXPR и уходим в него; пришла закрывающая скобрка - смотрим в EXRP ли мы находимся и если да, то финализируем EXPR, иначе же имеем невалидный исходник.
Что мешает при этом не создавать нод, а просто написать что-то вроде:
if (currentToken == '(') {
expr = parseExpr();
nextToken();
if (currentToken != ')')
throw ParserError("Ошибка!", pos, line);
return expr; // Вернул только выражение, скобки мне не нужны
}
Исходная версия Int64, :
Можно написать парсер и без конечного автомата, пример рекурсивный спуск. Парсеры из конечных автоматов обычно вручную не пишутся, а используют какой нибудь bison.
пришла открывающая скобка - заводим новый узел EXPR и уходим в него; пришла закрывающая скобрка - смотрим в EXRP ли мы находимся и если да, то финализируем EXPR, иначе же имеем невалидный исходник.
if (currentToken == '(') {
expr = parseExpr();
nextToken();
if (currentToken != ')')
throw ParserError("Ошибка!", pos, line);
return expr; // Вернул только выражение, скобки мне не нужны
}