Здравствуйте, VladD2, Вы писали:
VD>Что нужно для подключения твоего стайлера?
_rsdnEdit.Document.Formatter = new как_то_там;
VD>И что нужно чтобы добавить новые языки?
Для подключения языков нужно написать описание грамматики в XML. Есть пример такой грамматики для си-шарпа. Затем лексер нужно зарегистрировать:
LexerManager.Instance.RegisterLexer(lexer, "LEXER_CODE");
LEXER_CODE — это уникальный код лексера по к-му на него можно ссылаться. Например, при создании вложенных лексеров. Выглядит это примерно так:
<Block Key="Key1" LexerCode="LEXER_CODE"/>
Такой блок будет уже обрабатываться внешним лексером. Есть также возможность двойного прохода — сначала другим лексером, затем основным. В таком случае нужно будет прописать грамматику внутри блока. И выглядеть это будет так:
<Block Key="Key1" LexerCode="LEXER_CODE" ReparseRule="OwnGrammar|ParentGrammar">
<!- grammar -->
</Block>
При значение OwnGrammar при повторном проходе блока будет использоваться грамматика самого блока, при значении ParentGrammar — родительского.
Начало каждого блока можно записывать двумя путями — как "простой" набор символов:
<Start Type="Literal">///</Start>
Как последовательность кейвордов:
<Start Type="KeywordSet">script language javascript</Start>
Кейворды должны быть заранее зарегистрированы внутри каких-либо блоков и могут принадлежать любому блоку. Например, script — это кейворд распознаваемый только вначале блока "<" ">", javascript — только внутри кавычек и пр. У одно блока может быть произвольное количество "начал".
Также у каждого бока есть свой "сканер". Сканер на примитивном уровне отвечает за токенизацию. Если сканер явно не указан, то используется встроенный — простой и шустрый — сканер. Например, для строк к-е также представляют из себя отдельный блок другого и не нужно. Но для блоков с более сложной грамматикой нужно писать свой сканер. Делается это так:
<Scanners>
<Scanner Key="CSharpScanner">
<Pattern Type="Operator" Value="{'<>/[]|&!=-+*^%.:'}" />
<Pattern Type="Numeric" Value="<N>['LDF.']['x']<N'ABCDEF+'>" />
<Pattern Type="Identifier" Value="(A'_'){X'_'}" />
</Scanner>
</Scanners>
затем референсится из блока:
<Block ... Scanner="CSharpScanner"/>
При написании паттернов используются простенькие вилдкарды:
символы —
A — альфа
N — нумбер
X — альфанумер
B — одинарные кавычки
блоки —
() — группа элементов (объединяемых через "ИЛИ")
'' — литерал
[] — опциональная группа
{} — повторяющаяся группа
<> — опциональная повторяющаяся группа
Например, идентификатор в шарпе:
(A'_'){X'_'}
Первая группа указывает с каких символов он может начинаться — это или альфа или подчеркивание. Но внутри идентификатора могут быть альфанумер и подчеркивание. Т.е.:
1str — неправильный идент
str1 — правильный
Стили описываются отдельно внутри тега Stylesheet. Любой блок может иметь по три стиля — начало, конец блока и сам блок. Также стили можно назначать группам кейвордов и пр. Кол-во групп кейвордов внутри блока не ограничено. Да. У блоков обычно бывают родители. Родитель задается через тег Parent. Родителей у одно блока может быть несколько. Если родителей нет — то блок восрпинимается как корневой.
Вкратце все. В проекте есть схема, если ее подключить то при написании новых грамматик будет автокомплит.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>