Написание синтаксического маркера


Я надеялся написать свой собственный синтаксический маркер для летнего проекта, над которым я думаю работать, но я не уверен, как написать свой собственный синтаксический маркер.

Я знаю, что существует множество реализаций, но я хотел бы узнать о регулярных выражениях и о том, как работает подсветка синтаксиса.

Как работает подсветка синтаксиса и каковы некоторые хорошие ссылки для ее разработки? Выполняет ли синтаксический маркер сканирование каждого символа по мере его ввода или он выполняет сканирование область документа / текста в целом после ввода каждого символа?

Любое озарение будет весьма оценено.

Спасибо.

PS: я планировал написать его в ActionScript

8 20

8 ответов:

Синтаксические маркеры могут работать двумя очень общими способами. Первый реализует полный лексер и синтаксический анализатор для выделяемого языка(языков), точно идентифицируя тип каждого токена (ключевое слово, имя класса, имя экземпляра, тип переменной, директива препроцессора)...). Это предоставляет всю информацию, необходимую для точного выделения кода в соответствии с некоторой спецификацией (ключевые слова красным цветом, имена классов синим цветом, что у вас есть).

Второй способ-это что-то вроде одного кода Google Prettify использует, где вместо реализации одного лексера / синтаксического анализатора на язык используется пара очень общих синтаксических анализаторов, которые могут выполнять приличную работу на большинстве синтаксисов. Этот маркер, например, сможет достаточно хорошо анализировать и выделять любой C-подобный язык, потому что его лексер/парсер может идентифицировать общие компоненты этих типов языков.

Это также имеет то преимущество, что в результате вам не нужно явно указывать язык, так как двигатель будет определите сами, какой из его общих анализаторов может сделать лучшую работу. Недостатком, конечно, является то, что подсветка менее совершенна, чем при использовании специфичного для языка синтаксического анализатора.

В подкастеStackOverflow номер 50 Стив Йегге немного рассказывает о своем проекте по созданию некоторого общего механизма выделения. Не готовый продукт и, возможно, более сложный, чем вы ищете, но там может быть что-то интересное.

Это может помочь, если вы объясните, для чего предназначен этот синтаксический маркер. Если вы пишете его в actionscript, есть ли у вас идея иметь текстовое поле во флэш-фильме и выделять синтаксис после нажатия кнопки Отправить? Или вы хотите прочитать текст из какого-то веб-сервиса, а затем отобразить выделенный синтаксис? ..мне трудно помочь, потому что мне трудно представить, что вы делаете

Однако синтаксический маркер считывает текст, а затем сравнивает строки кодов с некоторыми регулярные выражения, которые помогают синтаксическому маркеру понять, что означают слова. Например, он может прочитать слово" function "или" int " как зарезервированные слова и заменить их текстом html:

<span class="reserved">function</span>, <span class="reserved"></span>

Предполагая, что у вас есть css и вы хотите зарезервировать слова красным цветом,

.reserved{
  color: #ff0000;
}
Это основная концепция, и вы можете взять идеи из Геши, так как вы можете просмотреть источник.

Сначала следует рассматривать весь документ как единое целое. Я думаю (не будучи экспертом), что вы хотите разбить каждый токен и сделать дерево синтаксического анализа.

Затем, если у вас есть все эти настройки, вы можете сначала запускать синтаксический анализатор каждый раз, когда вы вводите новый символ. Это может быть достаточно хорошо для вашего usecase, но если вы хотите сохранить вещи быстро, вам нужно будет внести изменения в дерево синтаксического анализа по мере получения дополнительной информации.

К сожалению, я никогда не использовал Actionscript, поэтому я не могу помочь с этой частью.

Но помимо этого, хорошим началом написания синтаксического маркера было бы взглянуть на существующие. Например, vim имеет синтаксические файлы в виде обычных текстовых файлов, так что вы можете посмотреть на них для начала. Там есть куча регулярных выражений (регулярные выражения бывают разных вкусов, но они не так уж и отличаются ...), так что для этой части вы можете взглянуть на какую-нибудь книгу.

Лично я нашел начало регулярных выражений хорошим. овладение регулярными выражениями также полезно для более продвинутых субъектов. регулярные выражения pocket reference , с другой стороны, хороши для определения различий в вышеупомянутых ароматах, так как он также включает главу о регулярном выражении vim.

Хорошим началом одного подхода для этого является курсUdacity CS262 . Название строит веб-браузер, но на самом деле класс фокусируется именно на тех задачах, которые вы ищете - как разобрать и лексировать набор текста. В вашем случае вы бы использовали эту информацию для выделения. Я просто взял его, и он был очень хорош. Теперь курс "закончен", но видео и практические задачи/домашние задания все еще доступны для просмотра.

Построение синтаксического маркера - это поиск определенных ключевых слов в коде и придание им определенного стиля (шрифт, стиль шрифта, цвет и т. д.).). Для этого вам нужно будет определить список ключевых слов, специфичных для языка программирования, на котором написан код, а затем проанализировать текст (например, с помощью регулярных выражений), найти конкретные маркеры и заменить их правильно оформленными HTML-тегами.

Очень простой маркер, написанный на JavaScript, будет выглядеть так: это:

var keywords = [ "public", "class", "private", "static", "return", "void" ];
for (var i = 0; i < keywords.length; i++)
{
        var regex = new RegExp("([^A-z0-9])(" + keywords[i] + ")([^A-z0-9])(?![^<]*>|[^<>]*</)", "g");
        code = code.replace(regex, "$1<span class='rm-code-keyword'>$2</span>$3");
}

Некоторое время назад я опубликовал в своем блоге инструмент для раскрашивания кода SQL: http://gruchalski.com/2009/04/26/flex-textrange-performance-issue-on-linux/

Вы можете найти ссылку на sqlcodecoloring.ЗИП с источником. Он реализуется с помощью tokenizer и TextRange класса.

Еще одна ссылка, раскраска кода sql как часть прототипа приложения: http://github.com/radekg/mysqlinterface/tree/master