когда использовать перекрестную ссылку и когда использовать ссылку на сдерживание?

#dsl #xtext #emf #cross-reference

#dsl #xtext #emf #перекрестная ссылка

Вопрос:

Мне нужно реализовать язык, специфичный для домена. У меня есть панель и несколько фигур на ней.

  'panel' name = ID '('  title = STRING',' bgcolor = Color',' width = INT',' height = INT ')''{'((rects  = Rect)| (ellipse  = Ellipse)|(arcs  = Arc)|)*'}'
  

и каждая форма имеет уникальное правило с некоторыми другими функциями. например:

 RoundRect:
'roundrectangle' name = ID '{'
(fill ?= 'filled' (fillpattern?='fillpattern' fillpaint=Paint)?)?
(stroke?='stroke' str=Stroke)?
'paint' paint=Paint
'coordination' x=INT ',' y=INT
'dimention' height=INT ',' width=INT
'arc' archeight=INT ',' arcwidth=INT
'}' 
  

как это очевидно в этом DSL, я использовал некоторые ссылки. Но я не знаю, верны ли эти правила или я должен использовать перекрестные ссылки в них?
Это правило работает нормально, и я получаю правильный результат, который я ожидал. Но я знаю, что когда объект не относится к базовому типу (строка, целое число и т. Д.), На
самом деле Это ссылка (экземпляр EReference), это ссылка на сдерживание, хотя для ссылок, не связанных с сдерживанием, объект, на который ссылается, хранится где-то в другом месте,
например, в другомобъект того же ресурса или даже в другом ресурсе.
И дело в том, что перекрестная ссылка реализована как ссылка без сдерживания.
Мне нужно знать, когда я должен использовать перекрестную ссылку и когда использовать ссылку на сдерживание?

Ответ №1:

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

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

Надеюсь, я достаточно хорошо проиллюстрировал это, чтобы теперь вы знали о различии и значении этих ссылочных типов.

Приветствие Krzmbrzl

Ответ №2:

Ваша грамматика описывает AST вашего языка. Таким образом, метамодель является производной от вашей грамматики. Для описания ссылок между вашими элементами AST вы можете использовать ссылки containmend и перекрестные ссылки. Ссылка на сдерживание используется, если вы хотите описать отношение родитель-потомок, в котором дочерний объект «создается» / объявляется во время создания родительского объекта. Перекрестная ссылка используется, если родительский объект указывает на дочерний объект, который создан / объявлен в другом родительском объекте. Чтобы «нарисовать картинку»: ссылка на сдерживание — это ссылка сверху -> снизу, а перекрестная ссылка — это ссылка слева -> справа.

Например, предположим, что у вас есть объявление field ( private int field = 42; ) или method ( public void foo() {...} ) класса Java. Это объявление моделируется ссылкой на сдерживание, поскольку класс Java содержит объявления полей и методов. С другой стороны, у вас есть оператор field ; в теле метода foo() . Там вы используете прежнее объявленное поле foo, и оно моделируется как перекрестная ссылка.

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