Xtext и EMF моделирование - разбор противоположных отношений
В настоящее время я играю с XText и EMF и зашел в тупик.
У меня есть модель ecore, которую я создал с помощью редактора диаграмм. Я не предоставляю представление XML; это должно быть ясно из примера. Некоторые отношения противоположны друг другу (например, отношения родитель-дети).
Эта привязка прекрасно работает, когда я создаю экземпляры программно. Ниже я показываю тестовый пример, который успешно пройден.
Однако когда я анализирую модель с использованием XText, эти противоположные отношения не устанавливаются. Я не могу найти способ это исправить. Отношения строго однонаправлены, поскольку они появляются во входном файле. Есть ли способ заставить Xtext установить их? или я должен разрешить это вручную?
Пройдя тест
WordsFactory factory = WordsFactory.eINSTANCE;
// Prepare a simple dictionary hierarchy
Dictionary d = factory.createDictionary();
Synset s = factory.createAdjectiveSynset();
s.setDescription("A brief statement");
s.setExample("He didn't say a word.");
WordSense ws = factory.createAdjectiveWordSense();
Word w = factory.createWord();
w.setName("word");
ws.setWord(w);
s.getWordSenses().add(ws);
d.getWords().add(w);
d.getSynsets().add(s);
// Now check the bidirectional links
Assert.assertTrue(ws.getSynset() == s);
Assert.assertTrue(w.getSenses().get(0) == ws);
XMI представление этого примера
<?xml version="1.0" encoding="ASCII"?>
<words:Dictionary xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:words="http://www.example.com/dstahr">
<words senses="//@synsets.0/@wordSenses.0" name="word"/>
<synsets xsi:type="words:AdjectiveSynset" description="A brief statement" example="He didn't say a word.">
<wordSenses xsi:type="words:AdjectiveWordSense" word="//@words.0"/>
</synsets>
</words:Dictionary>
Определение грамматики (некоторые несущественные правила удалены)
grammar ocs_assignment.dsl.DSL with org.eclipse.xtext.common.Terminals
import "platform:/resource/ocs_assignment.model/model/words.ecore"
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
Dictionary returns Dictionary:
{Dictionary}
'dict' name=EString
('add words' '[' words+=Word* ( "," words+=Word)* ']')?
synsets+=Synset*
;
Synset returns Synset:
AdjectiveSynset | NounSynset | VerbSynset;
WordSense returns WordSense:
AdjectiveWordSense | NounWordSense | VerbWordSense;
Word returns Word:
name=EString;
EString returns ecore::EString:
STRING | ID;
NounWordSense returns NounWordSense:
word=[Word|EString];
NounSynset returns NounSynset:
{NounSynset}
'(N)' name=EString
'{'
'content' '[' (wordSenses+=NounWordSense ( "," wordSenses+=NounWordSense)*)? ']'
'description' description=EString
'example' example=EString
('hyponym' hyponym=[Synset|EString])?
('hypernym' hypernym=[Synset|EString])?
('similarTo' '(' similarTo+=[Synset|EString] ( "," similarTo+=[Synset|EString])* ')' )?
'}';
Разобранный файл
dict dict
add words test1 test2 test3
(N) test1
{
content [ test1 test2 ]
description "test1"
example "test1"
}
(N) test2
{
content [ test3 ]
description "test2"
example "test2"
hypernym test1
}
XMI представление проанализированного файла (отсутствующие ссылки на слова)
<?xml version="1.0" encoding="ASCII"?>
<words:Dictionary xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:words="http://www.example.com/dstahr">
<words name="test1"/>
<words name="test2"/>
<words name="test3"/>
<synsets xsi:type="words:NounSynset" description="test1" example="test1" name="test1">
<wordSenses xsi:type="words:NounWordSense">
<word href="importedFile1.wdsl#xtextLink_::0.1.0.2.0::1::/0"/>
</wordSenses>
</synsets>
<synsets xsi:type="words:NounSynset" description="test2" example="test2" name="test2">
<hypernym xsi:type="words:AdjectiveSynset" href="importedFile1.wdsl#xtextLink_::0.1.1::1::/21"/>
<wordSenses xsi:type="words:NounWordSense">
<word href="importedFile1.wdsl#xtextLink_::0.1.1.2.0::1::/0"/>
</wordSenses>
</synsets>
</words:Dictionary>
1 ответ
Xtext не поддерживает встроенные обратные отношения. Если вы сгенерируете метамодель из вашей грамматики, вы увидите, что для соответствующих отношений не установлено обратное. Однако, если ваша модель Ecore имеет свойство обратного отношения, Xtext сохранит это.
Есть два способа использовать такую метамодель:
- Создайте свою собственную модель Ecore и опишите ее.
- Вы можете определить экземпляр IXtext2EcorePostProcessor, который может обновить сгенерированную метамодель до ее сериализации. Подробности смотрите в соответствующем сообщении в блоге Кристиана Дитриха.
Первое решение довольно простое, но вы потеряете автоматически сгенерированные модели EMF. Во втором случае вы должны написать код, который обновляет модель Ecore (meta), прежде чем она будет сериализована, что может быть очень сложно достичь. Мы применили второй подход для EMF-IncQuery (для другого вида настройки), поскольку в тот момент автогенерация была действительно важной, однако с тех пор настройщик стал действительно трудным для понимания.