Re: Вопрос по синтаксису макросов для v2
От: Тролль зеленый и толстый  
Дата: 22.06.10 20:42
Оценка: 95 (2)
Ну первый вариант однозначно плох: сложное выражение редактировать и воспринимать будет сверхнеудобно, и будет крайне легко допустить ошибку. Плюс нехороший мусор для непоименованных элементов (подчеркивания). Второй — тоже не фонтан, так как ухудшается читаемость собственно грамматики, легко запутаться в этом чередовании 'as', все сливается.

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

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

  macro attr : XmlAst
  syntax: identifier '=' attrValue
  {
    Attr(identifier, attrValue)
  }
}


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

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

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

  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))
  }


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

 '<' nospace identifier nospace '>'.


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