Re[2]: [Nemerle DSL] Описание конечного автомата
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.02.10 13:54
Оценка:
Здравствуйте, CodingUnit, Вы писали:

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


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

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

CU>здесь

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


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


Так выглядит красивее. Только одно замечание. Вот эти вот "entry" и "exit" ведь к самому автомату отношения не имеют, да? Это ведь реакция?
На мой взгляд лучше не забивать описание автомата действиями которые должны осуществляться при переходах. Действия лучше помещать в методы внутри класса. Метод EnterIn_IdleInGear_State(), который я изобразил в своем примере как раз и был таким действием. Их можно помечать атрибутами или распознавать по имени. В моем случае подразумевалось, что он будет распознаваться оп имени. Можно их описывать и на основании атрибутов. Например, для приведенного выше фрагмента можно описать реакции так:
[OnEnter(State=Sub1)]
{
  Action1 // действие при входе
}

[OnExit(State=Sub1)]
{
  Action2 // действие при выходе
}


Это позволит разгрузить описание самого автомат и иметь интеллисенс (дополнение при вводе, подсветку, хинты, ...) внутри методов.

CU>сложно ли такую структуру считать в макросе?


Макросам без разницы. Они разбирают абстрактный код. Принцип я показал. Если будут какие-то непонимания или вопросы, то можно обращаться сюда или прямо ко мне на Skype (имя в скапе совпадает с ником на форуме).

Естественно, имеет смысл почитать статьи посвященные написанию макросов.

CU> Там видимо понадобится дополнительный рекурсивный разбор каждого вложенного состояния и создание иерархии, при этом надо как то выделить части | name, и вложенные state.


Да, конечно. Вам нужно расширить функцию makeTransition (Ее, собственно, по любому нужно развивать.):
def makeTransition(transitionDef : MatchCase) : void
{
  Message.Hint(transitionDef.Location, $"  Events=$(transitionDef.patterns) Transition=$(transitionDef.body)")
}

В transitionDef.body может находиться произвольный Nemerle-код. Так как мы объявили макрос state, то в transitionDef.body может находиться и он (или даже несколько обращений к нему).

В ваши задачи будет выходить рекурсивный разбор transitionDef.body, проверка корректности его содержимого и выявление вложенных состояний.

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


Это предложение я не понял.
Речь идет о создании объектной модели автомата?
Или о том, что описание одного автомата может использоваться для разных задач?

CU> Сложность пока только в том чтобы распознать конструкции | и state на одном уровне,


Что значит на одном уровне?
Как распознавать state и его вхождения я показал. Вам нужно только немного расширить это распознавание сделав его рекурсивным. Сейчас распознование конструкции "| X => Y" выливается в банальный вывод текста в вывод компилятора:
def makeTransition(transitionDef : MatchCase) : void
{
  Message.Hint(transitionDef.Location, $"  Events=$(transitionDef.patterns) Transition=$(transitionDef.body)")
}

Вам же нужно развить это дело.

CU> остальное дело техники, не могли бы вы Владислав описать примерно как такое можно сделать, и что такое ..$ в цитате, в прошлом посте оно позволило развернуть лист выражений в цитате?


Это синтаксис квази-цирирования. Оно работает в две стороны (на распознавание и на композицию кода). Конкретно "..$x" позволяет распознать набор повторяющихся участов кода в список или сгенерировать код из списока. Такая конструкция может применятся только в скобках (в данном случсе в фигурных). Более подробно о квази-цитировании написано во второй статье
Автор(ы): Чистяков Владислав Юрьевич
Дата: 18.08.2011
Во второй части статьи о макросах Nemerle речь пойдет о макросах уровня выражения, о макросах, изменяющих синтаксис языка, а также о контексте компиляции, доступном в макросах, и тех возможностях, которые он предоставляет (типизации выражений, получении доступа к описанию типов проекта, информации о методах и т.п.).
курса Макросы Nemerle — расширенный курс (см. раздел "Работа с квази-цитированием").

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

CU>В этих конструкциях match с чем конкретно он сравнивает, после switch такая конструкция выглядит странно, как я понимаю там списки из Expression, то есть он сравнивает списки экземпляров Expression?


Там список так называемых PExpr. PExpr — это вариантный тип описывающих код немерла. Грубо говоря — это АСТ немерла. Чтобы не нужно было знать все типы данных в него входящий и писать сложный и громоздкий код была придумана система квази-цитирования. В общем, в указанном курсе все это описано.

ЗЫ

Один полезный совет... Чтобы лучше понимать происходящее на работу макросов лучше смотреть из под отладчика. Просто добавьте в некоторый фрагмент кода макроса:
assert2(false);

и скомпилируйте тестовый проект. Когда появится окно ассерат нажмите Retry и вы окажетесь в отладчике (нужно открыть его в отдельной ссесси, не той в котрой идет компиляция). Далее можно будет идти по коду макроса отладчиком и смоетреть значения и тип переменных. Это резко упрощает понимание (особенно чужого кода).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.