Re[3]: [Nemerle DSL] Описание конечного автомата
От: CodingUnit Россия  
Дата: 16.02.10 13:56
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, CodingUnit, Вы писали:


CU>>Спасибо за ответ Владислав и подробное описание, хотел заметить что автомат иерархический, в Boo был описан плоский автомат, на практике чаще автоматы нужны сложные, то есть когда состояния могут быть вложенными друг в друга, как я описал здесь:...


VD>Я показал как можно спроектировать синтаксис и как его разбирать. Думаю, что основные моменты я показал, так что будет не сложно переделать его в иерархический вариант.


CU>>графически они выглядят примерно так

CU>>здесь

CU>>В принципе с метаатрибутом описать весь автомат можно, лишь бы это не сложно было сделать, тогда описание будет выглядеть примерно так:


CU>>
VD>...
CU>>           state Sub1
CU>>           {
CU>>           | entry => {
CU>>                      Action1 // действие при входе
CU>>                      }
CU>>           | exit => Action2 // действие при выходе
CU>>})]
CU>>


VD>Так выглядит красивее. Только одно замечание. Вот эти вот "entry" и "exit" ведь к самому автомату отношения не имеют, да? Это ведь реакция?

VD>На мой взгляд лучше не забивать описание автомата действиями которые должны осуществляться при переходах. Действия лучше помещать в методы внутри класса. Метод EnterIn_IdleInGear_State(), который я изобразил в своем примере как раз и был таким действием. Их можно помечать атрибутами или распознавать по имени. В моем случае подразумевалось, что он будет распознаваться оп имени. Можно их описывать и на основании атрибутов. Например, для приведенного выше фрагмента можно описать реакции так:
VD>[c#]

Все работает замечательно, на Nemerle можно строить неплохие DSL, но вот беда, почему то не хотят создаваться в цикле объявления событий, то есть создаются правильные PExpr объявления члена класса события, но когда начинается конечная компиляция оказывается что члены поля и методов add,remove генерируются с одинаковыми именами, соответствующих названию в той строчке в которой производилось объявление, например если делаешь так:


// функция которая создает события из описания где то списка событий
def create_events(model)
{
model.Events.Map(x =>
 {
 def ename : string =x.Name; // это имя члена
 <[ decl: public event $(ename : usesite) : EventHandler; ]> // на выходе объявление члена события
 });
}

def defs=create_events(model); // создаем список объявлений
defs.Iter(x => typebuilder.Define(x)); // добавляем в typebuilder


при этом возникает ошибка в духе: _N2_ename_usesite_field duplicated identifier, тоже самое и с методами add,remove, исследовав этот вопрос оказывается когда создается с помощью цитаты объявление события оно всегда использует имя объявления в данном случае текст $(ename : usesite), и с помощью него создает имя членов, видимо подразумевая что событие должно объявлятся с константным именем и всегда разным, но что делать если надо объявить на основе динамических данных? Я решил эту задачу только с помощью специального метода, который берет объявление с помощью цитаты, которое преобразуется в ClassMember.Event и создает новый класс ClassMember.Event заменяя имена на новые и оставляя тела такие же как в старом созданном с помощью цитаты, тогда сообщение об ошибке не возникает, но это не выход, надо видимо чтобы имя полей и методов add,remove, при объявлении квази цитаты использовалось уникальное на основе имени которое берется из выражения, а не на основе текста выражения, это надо править компилятор, где бы найти файл где вся эта логика распознавания цитат реализуется? Может ли помочь наш всемогущий Владислав?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.