Здравствуйте, Sinclair, Вы писали:
S>Я вообще скептически отношусь к этим всем двухфазным парсерам, потому что есть вменяемые альтернативы. S>У лексеров есть принципиальная проблема: не всегда удаётся опознать токен без информации от парсера, т.к. в разных контекстах одни и те же токены могут означать разные вещи.
Это вообще не проблема. Цепочка символов же одна? Значит, и айди будет один, просто в зависимости от контекста по разному будет обрабатываться. У меня, кстати, есть обратная связь, я её обдумывал, когда вспоминал о проблеме >> vs > и > в плюсовых шаблонах.
S>По поводу перерасхода памяти и прочих штук: как всегда, всё очень зависит от задачи. S>Например, если нас не интересует инкрементальный парсинг, то можно использовать одну стратегию оптимизации. А если интересует — то другую. S>Вот PEG в частности прекрасен как раз тем, что легко обобщается на инкрементальность, что очень хорошо для построения языковых инструментов для IDE. S>И в нём вполне прозрачным образом можно определить, что вообще нам нужно, а что нет. S>В простом предельном случае нас вообще интересует только финальное AST, в котором нет никаких паразитных токенов вроде пунктуации. S>В более сложном случае мы хотим сэкономить на повторном парсинге, когда какие-то фрагменты исходного грамматического дерева, ненужные в исходном варианте, становятся нужны после внесения правки. S>Пока что всё, что я видел из коммерчески-пригодного, работает одним из трёх способов: S>- никогда не мемоизируем (читай — оставляем при разборе только то, что нужно для AST) S>- всегда мемоизируем (читай — тратим память на примитивные узлы, которые дешевле было бы распарсить заново) S>- вручную управляем мемоизацией (читай — программист должен быть достаточно умным, чтобы корректно оценить стоимость повторного парсинга и выбрать между затратами памяти и затратами процессора) S>Интуитивно кажется, что можно прикрутить некоторую автоматику, которая сама по коду правила понимает его стоимость и решает, мемоизировать его или нет.
У меня задумывается как универсальное средство: 1) для разбора сорцов и построения AST, с выдачей диагностических сообщений с указанием места ошибки/предупреждения — в этом варианте доп нагрузку на токенах можно дропать, когда она больше не требуется; 2) хочется иметь возможность репарсинга с определенной позиции, для реализации хотя бы подсветки синтаксиса в редакторе
S>Да, во всех перечисленных случаях, наиболее конструктивный способ хранить информацию про положение в исходниках — это собственно пара чисел "начало, конец". С учётом того, что после разбора у нас остаётся только "полезная" часть AST, оверхед на них не особо большой.