История изменений
Исправление den73, (текущая версия) :
Эх, жаль что ты не на лиспе. Я как раз решал подобную задачу для своего языка программирования и дело вплотную подошло к очередному переписыванию «по-взрослому». Посему:
1. Присоединяюсь к вопросу.
2. Я эту задачу частично решил, и понял, что решил не совсем правильно.
3. То ли эта задача очень сложная, то ли я стал стар.
4. Я разбил парсер на 3 слоя:
-- лексер -- обработчик парных скобок -- парсер
Каждый слой порождает свой набор структур в памяти, а также свой отдельный слой меченных текстовых регионов в редакторе. Я делаю все три слоя парсера с восстановлением после ошибок, возможность восстановления зависит и от структуры твоего языка.
Я пользуюсь tk text, там ты устанавливаешь приоритет между разными тегами, назначаемыми кускам текста и эти слои раскраски сами между собой выясняют отношения согласно приоритету. На теги же назначаются и действия. Т.е. в целом это похоже на сведение картинки. Первым делом лексер красит своим цветом. Потом обработчик скобок красит своим (например, непарные скобки можно красным покрасить). ПОтом парсер красит своим. Это три отдельных процесса. Если сделать по-иному, будет слишком сложно.
5. Попробуй набить текст хотя бы в окне ответа этого форума и посмотри, как браузер будет подчёркивать слова с ошибками при редактировании текста. Ты увидишь, что если ты начинаешь печатать текст с середины слова, браузер не проверяет правильность. Он проверяет её, когда ты выходишь за границу слова. Ошибка в моём текущем алгоритме состоит в том, что я на каждое нажатие пытаюсь проверять и, естественно, почти всегда имею ошибку разбора. Кроме того, пока ты нажимаешь только литеры и backspace (и не двигаешь курсор), умная программа может понять, что пользователь вводит текст и не перекрашивать ничего справа от курсора. Так трудоёмкость (инкрементного) парсинга сокращается на порядки. После того, как двинул курсор, можно красить до конца.
Без распознавания таких шаблонов в действиях пользователя у тебя вряд ли получится что-то хорошее.
6. Для инкрементного парсера пришлось реализовать механизм, подобный continuations, причём с возможностью повторного запуска одного и того же continuation. ПРавда, реализация оказалась медленной и пока что она выпилена, но в будущем мы к ней обязательно вернёмся.
7. В целом для маленьких файлов работает самый простой и дубовый механизм без инкрементного разбора, для больших же существует масса способов вляпаться, поэтому это - не та задача, где оптимизация преждевременна. Я, например, уже в одном месте вляпался в квадратичное замедление при росте файла, в итоге файлы длиннее 100 строчек сильно лагали при редактировании. ПОтом исправил.
8. Я бы смотрел исходники развитых сред разработки, которые могут всё, что тебе нужно. Я отталкивался изначально от hemlock (клона emacs), возможно, тебе подойдёт какой-нибудь атом или что там модно в вашем мире.
9. Вопрос о добавлении ``` не имеет хорошего решения. В любом случае будет смаргивать. Обходной путь - добавлять ``` только парами. Например, notepad++ при вводе открывающей скобки сам добавляет закрывающую, то же для кавычек.
10. Даже инкрементный разбор занимает время. Если за это время пользователь успеет нажать ещё кнопку, понадобится новый разбор. Таким образом, тебе нужна последовательность выполнений разбора, а также механизм отмены устаревшего разбора. При этом разбор должен быть достаточно часто опрашивать свой статус, чтобы отмена происходила быстро. Впрочем, в моём случае это плохо помогает, поскольку у меня что-то плохо со сборкой мусора и всё начинает лагать в любом случае. Но это уже из другой оперы :)
Я реализовал не все из этих пунктов - скорее это работа над ошибками.
Где-то в моих темах был ещё коммент от товарища, к-рый писал свою CAE систему.
Исправление den73, :
Эх, жаль что ты не на лиспе. Я как раз решал подобную задачу для своего языка программирования и дело вплотную подошло к очередному переписыванию «по-взрослому». Посему:
1. Присоединяюсь к вопросу.
2. Я эту задачу частично решил, и понял, что решил не совсем правильно.
3. То ли эта задача очень сложная, то ли я стал стар.
4. Я разбил парсер на 3 слоя:
-- лексер -- обработчик парных скобок -- парсер
Каждый слой порождает свой набор структур в памяти, а также свой отдельный слой меченных текстовых регионов в редакторе. Я делаю все три слоя парсера с восстановлением после ошибок, возможность восстановления зависит и от структуры твоего языка.
Я пользуюсь tk text, там ты устанавливаешь приоритет между разными тегами, назначаемыми кускам текста и эти слои раскраски сами между собой выясняют отношения согласно приоритету. На теги же назначаются и действия. Т.е. в целом это похоже на сведение картинки. Первым делом лексер красит своим цветом. Потом обработчик скобок красит своим (например, непарные скобки можно красным покрасить). ПОтом парсер красит своим. Это три отдельных процесса. Если сделать по-иному, будет слишком сложно.
5. Попробуй набить текст хотя бы в окне ответа этого форума и посмотри, как браузер будет подчёркивать слова с ошибками при редактировании текста. Ты увидишь, что если ты начинаешь печатать текст с середины слова, браузер не проверяет правильность. Он проверяет её, когда ты выходишь за границу слова. Ошибка в моём текущем алгоритме состоит в том, что я на каждое нажатие пытаюсь проверять и, естественно, почти всегда имею ошибку разбора. Кроме того, пока ты нажимаешь только литеры и backspace (и не двигаешь курсор), умная программа может понять, что пользователь вводит текст и не перекрашивать ничего справа от курсора. Так трудоёмкость (инкрементного) парсинга сокращается на порядки. После того, как двинул курсор, можно красить до конца.
Без распознавания таких шаблонов в действиях пользователя у тебя вряд ли получится что-то хорошее.
6. Для инкрементного парсера пришлось реализовать механизм, подобный continuations, причём с возможностью повторного запуска одного и того же continuation. ПРавда, реализация оказалась медленной и пока что она выпилена, но в будущем мы к ней обязательно вернёмся.
7. В целом для маленьких файлов работает самый простой и дубовый механизм без инкрементного разбора, для больших же существует масса способов вляпаться.
8. Я бы смотрел исходники развитых сред разработки, которые могут всё, что тебе нужно. Я отталкивался изначально от hemlock (клона emacs), возможно, тебе подойдёт какой-нибудь атом или что там модно в вашем мире.
9. Вопрос о добавлении ``` не имеет хорошего решения. В любом случае будет смаргивать. Обходной путь - добавлять ``` только парами. Например, notepad++ при вводе открывающей скобки сам добавляет закрывающую, то же для кавычек.
10. Даже инкрементный разбор занимает время. Если за это время пользователь успеет нажать ещё кнопку, понадобится новый разбор. Таким образом, тебе нужна последовательность выполнений разбора, а также механизм отмены устаревшего разбора. При этом разбор должен быть достаточно часто опрашивать свой статус, чтобы отмена происходила быстро. Впрочем, в моём случае это плохо помогает, поскольку у меня что-то плохо со сборкой мусора и всё начинает лагать в любом случае. Но это уже из другой оперы :)
Я реализовал не все из этих пунктов - скорее это работа над ошибками.
Где-то в моих темах был ещё коммент от товарища, к-рый писал свою CAE систему.
Исходная версия den73, :
Эх, жаль что ты не на лиспе. Я как раз решал подобную задачу для своего языка программирования и дело вплотную подошло к очередному переписыванию «по-взрослому». Посему:
1. Присоединяюсь к вопросу.
2. Я эту задачу частично решил, и понял, что решил не совсем правильно.
3. То ли эта задача очень сложная, то ли я стал стар.
4. Я разбил парсер на 3 слоя:
-- лексер -- обработчик парных скобок -- парсер
Каждый слой порождает свой набор структур в памяти, а также текстовых регионов в редакторе. Я делаю все три слоя с восстановлением после ошибок, возможность восстановления зависит и от структуры твоего языка.
Я пользуюсь tk text, там ты устанавливаешь приоритет между разными тегами, назначаемыми кускам текста и эти слои раскраски сами между собой выясняют отношения согласно приоритету. На теги же назначаются и действия.
5. Попробуй набить текст хотя бы в окне ответа этого форума и посмотри, как браузер будет подчёркивать слова с ошибками при редактировании текста. Ты увидишь, что если ты начинаешь печатать текст с середины слова, браузер не проверяет правильность. Он проверяет её, когда ты выходишь за границу слова. Ошибка в моём текущем алгоритме состоит в том, что я на каждое нажатие пытаюсь проверять и, естественно, почти всегда имею ошибку разбора. Кроме того, пока ты нажимаешь только кнопки и backspace, умная программа может понять, что пользователь работает и не перекрашивать ничего справа от курсора. Так трудоёмкость (инкрементного) парсинга сокращается на порядки.
Без распознавания таких шаблонов в действиях пользвателя у тебя вряд ли получится что-то хорошее.
6. Для инкрементного парсера пришлось реализовать механизм, подобный continuations, причём с возможностью повторного запуска одного и того же continuation. ПРавда, реализация оказалась медленной и пока что она выпилена, но в будущем мы к ней обязательно вернёмся.
7. В целом для маленьких файлов работает самый простой и дубовый механизм без инкрементного разбора, для больших же существует масса способов вляпаться.
8. Я бы смотрел исходники развитых сред разработки, которые могут всё, что тебе нужно. Я отталкивался изначально от hemlock (клона emacs), возможно, тебе подойдёт какой-нибудь атом или что там модно в вашем мире.
9. Вопрос о добавлении ``` не имеет хорошего решения. В любом случае будет смаргивать. Обходной путь - добавлять ``` только парами. Например, notepad++ при вводе открывающей скобки сам добавляет закрывающую, то же для кавычек.
10. Даже инкрементный разбор занимает время. Если за это время пользователь успеет нажать ещё кнопку, понадобится новый разбор. Таким образом, тебе нужна последовательность выполнений разбора, а также механизм отмены устаревшего разбора. При этом разбор должен быть достаточно часто опрашивать свой статус, чтобы отмена происходила быстро. Впрочем, в моём случае это плохо помогает, поскольку у меня что-то плохо со сборкой мусора и всё начинает лагать в любом случае. Но это уже из другой оперы :)
Я реализовал не все из этих пунктов - скорее это работа над ошибками.
Где-то в моих темах был ещё коммент от товарища, к-рый писал свою CAE систему.