Здравствуйте, Marty, Вы писали:
M>Я плюсики раскрашиваю вроде норм.
Скорее всего ключевое слово тут "вроде". В частности, лексером невозможно корректно раскрасить код с макросами, т.к. вплоть до раскрытия макроопределений неизвестно даже, является ли код частью юнита компиляции.
Ну, то есть вопрос в постановке задачи. Если хочется просто красить лексемы — то "кому и кобыла невеста".
А вот делать полноценную современную семантическую разметку — увы.
M>Отвечая также на соседнее сообщение, скажу, что у меня наверное не совсем честный лексер. Так, у меня строковые символьные литералы парсятся отдельным классом, который надо "проинсталлить" в лексер. проблема с PHP/PERL в общем-то только с тем, что для DOCUMENT HERE надо написать отдельный парсер этого литерала, мне пока не до этого.
Ну вот я вам и объясняю, что традиционное деление на лексер и парсер — это просто историческое заблуждение.
Вот у вас уже внутри лексера используется парсер, который, надо полагать, внутри использует лексер. Ну и нафига это всё, спрашивается, когда можно просто перестать себя обманывать и притворяться, что существует какой-то отдельный от "парсера" "токенизатор"?
M>Далее, выхлоп токенизера отправляется в пользовательский обработчик, завернутый в std::function. Потом мне показалось этого мало, и я сделал возможность добавлять "фильтры" на выхлоп. Сильно переделывать уже не хотелось, и у меня немножко странно получилось — фильтры устанавливаются в голову, и получается, что раньше отрабатывают фильтры, установленные позже.
Не, если задача — поразвлекаться на плюсах, то вы движетесь к успеху.
Проблема всех таких решений — write-only code, в котором совершенно невозможно понять, что и как разбирает результат всех этих применений фильтров к фильтрам и каскадов парсеров.
M>Ф фильтрах я при необходимости делаю небольшие автоматики, которые делают что-то полезное. Так, например, для числовых литералов, если за ними сразу, без каких-либо пробелов и чего-то другого, следует идентификатор — я это склеиваю, и получаю новомодные плюсовые пользовательские литерали, или как оно там называется. Или препроцессор. Сначала было всё в конечном обработчике, потом сделал фильтр, который умеет посылать токены PP_START/PP_END, по которым я устанавливаю другой цвет фонта при раскраске.
Во-во, об этом я и говорю. В теории вы даже можете сделать фильтр, который проверяет, попадает ли выхлоп IFDEF в компиляцию, или нет. Но зачем называть это токенизатором?
M>Вот так у меня выглядит создание токенизатора: http://files.rsdn.org/2511/cpp.html
M>А так — использование: http://files.rsdn.org/2511/tokenizer_test_011.html
M>Эти файлы раскрашены этим тестом
Ну, если вы пишете токенизатор для
конкретного языка — то да, можно делать примерно всё, что угодно. Всё равно это write-only код, который потом никто не будет проверять или поддерживать.
S>>Регекспы там затем, что они работают быстрее, чем обращение по протоколу LSP.
M>Ну, вот тут не уверен, что это всегда так. В любом случае, мой токенизер гораздо быстрее работает.
Скорость работы токенизатора не очень важна, когда узким местом является передача его результатов в IDE.
M>Я пока с IDE не работаю, у меня текст в одной строке, и все ссылки на исходный текст идут как индекс в этой строке
Когда начнёте работать с инкрементальностью, неизбежно перейдёте на древовидное хранение. Аккурат потому, что O(N) операции вас задолбают.