Relax NG Compact

27 views
Skip to first unread message

Konstantin Kuzvesov

unread,
Jan 13, 2017, 11:41:29 AM1/13/17
to Колорер по русски
Здравствуйте!

Я тут пытаюсь написать hrc-правила для подсветки компактного синтаксиса Relax NG, и что-то как-то уж очень трудно дело идет. Я заранее прошу прощения за некоторую занудность описания, но я привык писать так, чтобы по возможности исключать ошибочное толкование.

Проблем, которые я могу сформулировать, на данный момент две:
  • в языке (в relax ng) отсутствует обозначение концов строк, и я просто не знаю, что указывать в атрибуте end оператора block; пока что остановился на выражении /\M(\s*)\S/ , т.е.блок заканчивается на любом непробельном символе (при этом и этот символ, и предваряющие его пробелы, если есть, оставляются для последующего анализа);
  • после возврата из блока схема повторяется заново, что приводит к подсветке синтаксически неверных конструкций типа namespace ns ns (повтор идентификатора ns) как верных.
Вот пример фрагмента текста (он искусственный, синтаксису языка не соответствует, но пока и с этим проблемы).

Вариант 1
 namespace ns

Вариант 2
  namespace
    ns

Ввиду того, что Colorer работает с отдельными строками, а идентификатор пространства имен не обязан находиться на той же строке, что и ключевое слово namespace, после распознавания namespace я переключаю контекст:
  <scheme name="decl">
   
<block start="/(^|\s+)(namespace)(\s*$\M|\M\s+)/" end="/\M(\s*)\S/"
     
region02="keyword" scheme="decl.namespace"/>
 
</scheme>

Во вложенной схеме я разбираю идентификатор пространства имен (сущность NCName взята из XML):
  <scheme name="decl.namespace">
   
<block start="/(^|\s+)(%NCName;)(\s*$\M|\M\s*)/" end="/\M(\s*)\S/"
     
region02="identifier"
     
scheme="decl.namespace.identifier"/>
 
</scheme>
Схема decl.namespace.identifier на данный момент пустая. По идее в ней должна разбираться оставшаяся часть конструкции namespace, но пока что я решил остановиться на более простой задаче (однако с прицелом на реализацию подсветки всего синтаксиса).

Топовая схема не содержит ничего интересного:
  <scheme name="relaxng-compact">
    <inherit scheme="documentation"/>
    <inherit scheme="comment"/>
    <inherit scheme="decl"/>
    <block start="/\M(^|\s+)\S/" end="/$never^/" scheme="invalidContent"/>
  </scheme>
Схемы documentation и comment разбирают комментарии, схема invalidContent подсвечивает неразобранные остатки файла как ошибку.

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

Теперь вопросы:
  • после удачного распознавания идентификатора пространства имен в схеме decl.namespace происходит возврат к началу схемы; поэтому, если я пишу namespace ns1 ns2, то ns2 воспринимается тем же блоком как еще один идентификатор (и когда после идентификатора появится знак равно и uri пространства имен, то будет происходить повторный разбор всей конструкции);

    вопрос: каким образом сделать так, чтобы после удачного выполнения блока схемы происходил возврат в родительскую схему (в схему, вызвавшую данную), а не возврат к началу схемы? если для этих целей использовать "безвозвратные" переключения схем, т.е. оператором блок с заведомо невыполнимым регулярным выражением, то такой подход будет есть ресурсы и замедлять работу? будет ли Colorer проверять все эти условия? или будет проверять лишь первое из них? будет ли на самом деле осуществляться рекурсия на программном уровне, или в таком случае будет происходить лишь замена контекста?

  • каким еще образом можно организовать переключение схемы "навсегда", без возврата в родительскую схему? я для этого использую end="/$never^/" в операторе block, но подозреваю, что такой подход кушает ресурсы и замедляет работу Colorer'а;

    необходимость переключения схемы возникает, т.к. верхний уровень синтаксиса Relax NG описывается как
    topLevel  ::=  decl* (pattern | grammarContent*)
    т.е. сначала определения пространств имен и типов данных (decl), а потом паттерны и словарь; во второй части определения пространств имен недопустимы

Синтаксис Relax NG Compact: http://relaxng.org/compact-20021121.html
relaxng-compact.hrc

Igor Russkih

unread,
Jan 16, 2017, 6:05:48 AM1/16/17
to colorer_ru
Здравствуйте Константин.

Я к сожалению давненько уже не занимаюсь этим, но видимо кроме меня некому подсказать )

Вкручивать такие синтаксисы в HRC движок тяжело - пример тому - XML ))
Вообще при этом приходится пользоваться всякого рода хаками чтобы полноценно это разобрать.

Я не очень понял - судя по грамматике правильная структура - 
namespace ns = "asdf"

Если так, то например блок этой конструкции можно попробовать закрывать по завершающей кавычке.

Ваши вопросы:

1. Рекурсия в движке программная, поэтому искуственно вложенные контексты могут убить парсер.

2. Переключение навсегда как вы написали можно делать, но смысла в этом мало учитывая (1).

Если это сделать один раз для topLevel контекста - проблем не будет. Будет просто незакрытый контекст в конце разбора - но это ни на что не влияет.



  Igor

--
Вы получили это сообщение, поскольку подписаны на группу "Колорер по русски".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес colorer_ru+unsubscribe@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages