Здравствуйте, Sinclair, Вы писали:
M>>Я плюсики раскрашиваю вроде норм. S>Скорее всего ключевое слово тут "вроде". В частности, лексером невозможно корректно раскрасить код с макросами, т.к. вплоть до раскрытия макроопределений неизвестно даже, является ли код частью юнита компиляции.
Да. Но в большинстве случаев это не нужно. Например, у меня в перспективе маячит раскраска кода листингов в документации, того, который в маркдауне ограничен тремя бэктиками, а на кывте обрамляется тэгом code.
S>Ну, то есть вопрос в постановке задачи. Если хочется просто красить лексемы — то "кому и кобыла невеста".
Часто большее и не нужно
S>А вот делать полноценную современную семантическую разметку — увы.
Да, это не самое простое.
S>Вот у вас уже внутри лексера используется парсер, который, надо полагать, внутри использует лексер. Ну и нафига это всё, спрашивается, когда можно просто перестать себя обманывать и притворяться, что существует какой-то отдельный от "парсера" "токенизатор"?
Есть токенизатор, есть ручки, которые можно дергать. К токенизатору можно прикрутить надстройки, и да, он становится не совсем честным. И что?
Внутри мой токенизатор устроен как куча говнокода, там без тонких материй
Да, я до возможностей IDE сильно не дотягиваю, но у меня уже гораздо лучше, чем том же notepad++.
Когда я на говне запилил свой первый DSL, который локально хорошо взлетел (но не первый мой DSL вообще), то был вопрос, а где его редактировать, чтобы красиво. Получилось в NPPP и Кейле. В NPPP — через его настройки кстомной раскраски, в Кейле — через правки конфигов какого-то движка, который я перепутал с тем, что наша местная терраинформатика делает. И там и там всё было на пределе возможностей, приходилось извращаться. А сейчас у меня уже гораздо лучше.
S>Проблема всех таких решений — write-only code, в котором совершенно невозможно понять, что и как разбирает результат всех этих применений фильтров к фильтрам и каскадов парсеров.
Моё решение предлагает задание операторов оптом, задание различных типов скобок, и наборы фильтров. Всё это можно варьировать при настройке и получать результат лучше, чем в NPP. Уже годно для тупого лексера.
write-only code... Ну, хз...
Так-то, почти любое решение — дерьмо. С начала ты трескаешь то, что тебе дали разработчики решения, и тебя всё устраивает, и ты не паришься, что там под капотом. Потом ты упираешься в ограничения этого решения, но ты ничего не можешь изменить...
S>Во-во, об этом я и говорю. В теории вы даже можете сделать фильтр, который проверяет, попадает ли выхлоп IFDEF в компиляцию, или нет. Но зачем называть это токенизатором?
Это уже не совсем токенизатор, конечно, это доп фичи, на него навешанные. Последовательность установки фильтров и их настройки можно сохранять как конфиги, и это гораздо гибче, чем раскраска в NPP
S>Ну, если вы пишете токенизатор для конкретного языка — то да, можно делать примерно всё, что угодно.
Мой "токенизатор" писался с упором на то, чтобы можно было в первую очередь распарсить существующие языки. Что может придумать воспалённый мозг, я не знаю. Например, что a--b, это не полная хрень, а a минус b с унарным минусом. Если нужно такое — это не ко мне. У меня жадный алгоритм токенизации. И он выплюнет a, --, b, для примитивной раскраски этого достаточно, как в прочем, и для дальнейшего разбора.
S>Всё равно это write-only код, который потом никто не будет проверять или поддерживать.
Не очень понятно, что ты хотел сказать.
M>>Я пока с IDE не работаю, у меня текст в одной строке, и все ссылки на исходный текст идут как индекс в этой строке S>Когда начнёте работать с инкрементальностью, неизбежно перейдёте на древовидное хранение. Аккурат потому, что O(N) операции вас задолбают.
Мне до этого ещё далеко. Но не вижу особых проблем. Не уверен, что на каждое нажатие клавиши надо делать вставки в единственный глобальный string с текстом. На вскидку — будет глобальный текст, и список строк, которые ссылаются индексами на глобальный текст. Если пошло редактирование строки, то глобальный текст не перестраивается при каждом вводе, просто для строки выделяется отдельный буфер и строка маркируется признаком своего буфера. Потом вставляем, пробегаем и обновляем индексы после нашей строки, переделываем раскарску. Раскраску при вводе/удалении можно сдвигать/удалять по месту, на базе старой, без перескана, при паузах и в фоне можно всё перестраивать/пересканивать как угодно. В общем, что-то не вижу особых проблем. Мои варианты решений конечно далеки от дедовских, которые шуршали даже на XT, но, как минимум не хуже того, что сейчас в тренде.