Здравствуйте, eaglus, Вы писали:
E>Всем привет!
E>У меня такая задача: нужно написать парсер для текстового редактора, для подсветки синтаксиса, построения свёрток по функциям/классам/циклам в функциях и тому подобного, а также для парсинга по запросу, например, для определения ближайшего блока begin/end, в котором курсор стоит, чтобы парные конструкции подсвечивать...
Тебе можно использовать обычный парсер, но каждый раз при свертке по некоторому правилу можно размечать текст в соответствии с данным правилом. Для этого в грамматике надо сделать один начальный нетерминал, который содержит дочерними все те локальные конструкции, что тебе надо распознавать. Что-то типа
S --> Class_Def | Unit_def | Func_def ...
Каждый раз напускай свой парсер на локальный кусок текста и смотри по какой конструкции будет произведена свертка. Если не хочешь ждать конца конструкции, то надо переделать правило для нее самой. Это же надо сделать и для конструкций с ошибками. Например, для обработки конструкции, где вместо начального "unit" стоит какая-то фигня, надо ввести правило такого вида
Unit_def --> ("фигня" | unit) "остальная часть конструкции"
"фигня" -- это такой специальный токен конечно.
Также можно ввести правила для кусков определений типа
Class_Def_без_скобки --> class { class_internal
Class_Def_без_точки_с_запятой --> class { class_internal }
Class_Def --> class { class_internal };
Все зависит от того, как ты сам захочешь показывать неполные конструкции и в каких случаях. Идея держать состояние парсера мне не нравится, лучше запоминать последовательность токенов и по запросу их распарсивать. Наверняка ты там текст в токенах держишь? Если нет, то это удивительно, т.к. из по любому парсить приходится. Видимая часть текста в токенах распарсивается по требованию, выделяются конструкции и форматируются. Допустимые ошибки заложены в грамматике.