Re[2]: Вопрос по синтаксису макросов для v2
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.06.10 20:33
Оценка:
Здравствуйте, Тролль зеленый и толстый, Вы писали:

ТЗИ>Ну первый вариант однозначно плох: сложное выражение редактировать и воспринимать будет сверхнеудобно, и будет крайне легко допустить ошибку.


На мой взгляд — нормально. Но если будет найден более удобный вариант, я буду не против.

ТЗИ>Плюс нехороший мусор для непоименованных элементов (подчеркивания).


Это стандартное соглашение в языке означающие игнорирование имени.

ТЗИ>Второй — тоже не фонтан, так как ухудшается читаемость собственно грамматики, легко запутаться в этом чередовании 'as', все сливается.


+1

ТЗИ>Указание имен в каком-то смысле эквивалентно введению подправил грамматики.


Если только вырожденных. В грамматиках частенько правила используются по много раз в рамках тела другого правила. Собственно задание имени и нужно чтобы отличить разные вхождения.

Однако если это позволяет ввести имена для правил которые можно будет использовать в теле макросов, то в этом появляется смысл. Идея ввести "where" — мне нравится. В принципе с ее помощью можно решить проблемы именования полностью, но при этом грамматике не допустимо будет использовать литералы. Наше пример при этом выродится в:
  macro tagOpen : XmlAst.TagOpen
  syntax: lt identifier attrs gt;
  where 
    attrs = attr*;
    lt    = '<';
    gt    = '>';
  {
    ...
  }

Что мне не нравится. Так что все же именование по месту все равно нужно.

ТЗИ> Названия правил в описании грамматики могут говорить сами за себя (например, attrs), так что и без расшифровки понятно, что это. Если какой-то макрос упоминается только один раз (а таких случаев будет 99%), его можно явно не именовать.


Есть еще одна проблема. Это имена макросов! А они сами могут потребоваться (в коде макроса). Ведь макрос сам может использовать макросы. Так в стандартной библиотеке макросов немерла сейчас во всю используются эти же макросы (из прошлой версии библиотеки). Может возникнуть конфликт имен. В прочем его можно решать или в том же "where" или путем добавления префикса '@'.

ТЗИ>Я убрал из примера сохранение позиции в тексте, так как мне кажется, что этот нудный процесс обязательно должен быть как-то автоматизирован.


"Как-то" это несерьезно! Лично я не вижу как это сделать, по сему пока не появится внятного решения придется делать это вручную.

Тут нужно понимать, что копировать местположение руками нужно довольно редко. Все стандартные правила уже будут содержать корректное местоположение.

ТЗИ>Здесь, кстати, есть какая-то аналогия с регэксповыми "матчами". То есть мы как бы создаем поименованное подвыражение.


Скорее с грамматиками. Твое where — это ни что иное как явное задание имен подправилам которые раньше просто их не имели. В принципе можно на каждый чих создавать мелкий макрос. Но это очень неудобно!

ТЗИ>Вариант синтаксиса со скобками, скобки вроде как визуально выделяют поименованный фрагмент:


ТЗИ>
ТЗИ>  macro tagOpen : XmlAst.TagOpen
ТЗИ>  syntax: '<' identifier {attrs attr*} '>'
ТЗИ>  {
ТЗИ>    TagOpen(identifier.Value, attrs.Map(x => x.Value :> Attr))
ТЗИ>  }
ТЗИ>


Это мне совсем не нравится. Уж лучше двоеточния, но в синтаксисе жетско оговорить, что между двоеточием и подправилом которое оно именует не должно быть пробелов. Тогда можно будет легко отличать то подправило для которого задается имя.

ТЗИ>Можно смешать варианты:


ТЗИ>
ТЗИ>  macro tagOpen : XmlAst.TagOpen
ТЗИ>  syntax: {lt '<'} identifier attrs {gt '>'}
ТЗИ>  where 
ТЗИ>    attrs: attr*
ТЗИ>  {
ТЗИ>    TagOpen(lt.StartPos, gt.EndPos, identifier.Value, attributes.Map(x => x.Value :> Attr))
ТЗИ>  }
ТЗИ>


Пожалуй смешанный вариант твоего where и вольфхаудовского именования через двоеточие будет выглядеть лучше:
  macro tagOpen : XmlAst.TagOpen
  syntax: lt:'<' identifier attrs gt:'>';
  where 
    attrs = attr* // "Равно" здесь более уместно. Как вариант, можно использовать "<-" раз уж мы используем PEG
  {
    ...
  }


ТЗИ>По поводу пробелов (а точнее, разделителей, в которые входят также комментарии). Выписывать явно разделители, тем более с таким именем как "s" — явно некрасиво. Потому что в 99% случаев он будет нужен и только в 1% — не нужен. Скорее, было бы лучше, если бы макрос s вставлялся по умолчанию, если не вставлен кейворд nospace, например:


ТЗИ>
ТЗИ> '<' nospace identifier nospace '>'.
ТЗИ>


Хорошая идея! Еще как вариант, можно ввести соглашение по которому "nospace" подразумевается если несколько литералов и правил записаны без отступов. Таким образом приведенный ниже пример будет эквивалентным твоему:
 '<'identifier'>'.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.