Парсерный комбинатор не работает быстро в AST с выбором позиции
Я написал несколько комбинаторов синтаксического анализа для создания AST с информацией о местоположении источника. Профилирование указывает, что по меньшей мере 30% процентов выполнения тратится многократно при разборе ненужной информации для генерации данных местоположения источника. Мне нужна помощь в поиске альтернативного подхода для повышения производительности.
проблема
Допустим, я разбираю язык, состоящий только из двух токенов: "A" и "B". Для создания узлов AST в настоящее время я определил комбинатор, который извлекает местоположение и строит узел:
// Parse body and build resulting node from function
// nodeFactory called with position and result from body.
var node = function(body, nodeFactory) {
return bind(
locParser, // get the current location in the token stream
body,
prevEnd, // get the previous end position in the token stream
function(o, x, c) {
return always(f(Location(o, c), x));
});
};
var a = node(char('A'), buildNodeA);
var b = node(char('B'), buildNodeB);
Проблема с этим подходом заключается в том, что locParser
всегда выполняется независимо от того, удастся ли телу:
var element = either(a, b);
var program = many(element);
run(program, "AAABBA");
Ожидаемое поведение
a
терпит неудачу, как только становится ясно, что его body
не удастся.
Фактическое поведение
Для жетонов 'B', сначала locParser
за a
запускается и когда body
выходит из строя, locParser
за b
это запустить. С вложением и большим количеством ветвлений это становится проблемой производительности.
Краевые случаи
Местоположение охватывает весь диапазон потребляемых ресурсов:
var c = node(next(char(' '), char('C')), buildNodeC);
Расположение узла "C" начинается в начале символа пробела.
var d = node(between(char('('), char(')'), char('D')), buildNodeD);
Расположение узла "D" начинается в начале "(" и заканчивается в конце ")". Оба эти случая правильно обрабатываются node
,
Вопрос
Как я могу реорганизовать эти парсеры так, чтобы они быстро выходили из строя, но при этом имели доступ к правильным данным о местоположении?
Я бы предпочел держать каждый синтаксический анализатор достаточно автономным и избегать повторения логики. Кроме того, узлы не должны быть изменены после создания.