F diff --git a/doc/bulgarian/.project.mg.swp b/doc/bulgarian/.project.mg.swp new file mode 100644B Binary files /dev/null and b/doc/bulgarian/.project.mg.swp differF diff --git a/doc/bulgarian/makefile b/doc/bulgarian/makefile new file mode 100644 --- /dev/null +++ b/doc/bulgarian/makefile+ install:+ cat project.mg | preconv | groff -mg -Tps > a.ps+ ps2pdf a.ps a.pdfF diff --git a/doc/bulgarian/project.mg b/doc/bulgarian/project.mg new file mode 100644 --- /dev/null +++ b/doc/bulgarian/project.mg+ .ps +1+ .vs +1+ .start+ .ds C \f[B]C\f[]+ .title "Проект по компютърни системи за управление на роботи"+ .title "Език за улесняване на програмиране на вградени устройства"+ .author "Галин Симеонов Ф.Н. 81635" "gtsimeonov@uni-sofia.bg"+ .heading "Увод"+ .paragraph+ При програмирането на вградени устройства,+ някои от проблемите се моделират чрез автомати.+ Също е практика да се програмира на езици от ниско ниво, като \*[C],+ при които ръчното имплементиране на автомати с каквито и да е размери+ често е неинтуитивно, предразполагащо към грешки и трудоемко.+ С цел да помогна разработването на програми, чийто модел е ориентиран околу+ състоянията на системата, предлагам и имплементирам експериментален миниатюрен език транспилиращ до \*[C].+ .paragraph+ За цели имам той да е прост, интуитивен и евентуално лесен за генериране от инстурменти с графичен интернфейс+ .footnote+ Макар, че директното генериране на код без този език да действа като посредник би било по-смислено.+ .footnote end+ \&.+ .heading "Описание на езика"+ .heading "Общ поглед" 2+ Една 'програма' съдържа един или повече 'машини', които действат като контейнери за състояния,събития и преходи.+ Всяка машина си има име и има отделно пространство за имена на състояния и събития.+ Чрез преходите може да се извикват външни функции.+ Ето най-простият пример за това как изглежда кодът:++ .code+ machine light_bulb+ [+ states [ ON , OFF ];+ events [ TURN_ON , TURN_OFF , SWITCH_STATE ];+ starting on OFF;+ transitions+ [+ from ON to OFF on event TURN_OFF;+ from ON to OFF on event SWITCH_STATE;++ from OFF to ON on event TURN_ON;+ from OFF to ON on event TURN_ON;+ ];++ ];+ .code end++ След транспилация се генерират 3 файла - xxx.h xxx.c и xxx_external.h, който съответно съдържат+ декларациите на служебните функции, тяхната имплементация и декларациите на външните функции, които са използвани от някой преход.+ Подаването на събития към тези 'автомати' става посредством служебната функция - \f[B]push_event_to_machine\f[]++ Горният пример не е много функционален, защото комуникацията е само в една посока.+ За да може да връща информация и да има функционалност, на всеки преход може да се сложат функции, които да бъдат изпълнени преди преходът да е завършил+ .footnote+ Това свойство е важно и авторът се е стремил да го запази. Това позволява, например, да се подават събития от функции изпълнени по време на преход+ .footnote end+ \&.+ Taка горният пример може да бъде преработен да вика функция, която действително да включва и изключва някаква лампа:++ .code+ machine light_bulb+ [+ states [ ON , OFF ];+ events [ TURN_ON , TURN_OFF , SWITCH_STATE ];+ starting on OFF;+ transitions+ [+ from ON to OFF on event TURN_OFF+ execute light "off";+ from ON to OFF on event SWITCH_STATE+ execute light "off";++ from OFF to ON on event TURN_ON+ execute light "on";+ from OFF to ON on event TURN_ON+ execute light "on";+ ];++ ];+ .code end++ Тук също е демонстрирано как се подават аргументи към тези функции.+ Символните низове са избрани като единствен начин да се подават аргументи, защото е предвидено да се транспилира до езици, различни от \*[C],+ а въвеждането на типова система или нещо, което да описва различните аргументи би натоварило езикът твърде много и би донесло само минимална печалба.+ .paragraph+ Възможно е да има повече от една 'машина' в кодът. Например, нека към горния пример добавим:++ .code+ machine light_controler+ [+ states [ STATIC , BLINKING ];+ events [ SIGNAL , GO_STATIC, START_BLINKING ];+ starting on STATIC;+ transitions+ [+ from STATIC to BLINKING on event START_BLINKING;+ from BLINKING to STATIC on event GO_STATIC;++ from BLINKING to BLINKING on event SIGNAL+ execute prod_light_bulb;++ ];++ ];++ machine timer+ [+ states [ ON , OFF ];+ events [ TICK , START , STOP ];+ starting on OFF;+ transitions+ [+ from ON to OFF on event STOP;+ from OFF to ON on event START+ execute prod_timer;+ from ON to ON on event TICK+ execute prod_timer | prod_light_controler;+ ];++ ];+ .code end++ Тук може да се види и 'навързване' на различни функции.+ timer 'машината' праща сигнал до себе си и до light_controler, а light_controler праща сигнал до light_bulb.+ Тук можем да прескочим предаването на събития между 'машините' чрез използването на \f[B]if\f[].+ Променяме третия преход от timer:++ .code+ from ON to ON on event TICK+ if(light_controler.BLINKING)+ execute prod_timer | prod_light_bulb;++ .code end++ Това е условно изпълнение на командите, преходът се случва и състоянието е променено независимо от истинността на условието.+ За реализацията на условен преход, в езикът има \f[B]granted\f[] ключовата дума.+ Горното може да се опитаме да имплементираме по следния начин:++ .code+ from ON to ON on event TICK granted (light_controler.BLINKING)+ execute prod_timer | prod_light_bulb;+ .code end++ Тук има проблема, че timer спира да работи ако light_controler не е в състояние BLINKING,+ защото преходът няма да се случи и \f[B]execute prod_timer\f[] няма да се изпълни.+ .footnote+ Това, че този пример може да бъде имплементиран на \*[C] под 10 реда, е забелязано от автора.+ .footnote end+ .paragraph+ \f[B]prod_timer\f[],\f[B]prod_light_bulb\f[],\f[B]prod_timer\f[] и \f[B]light\f[] са функции, чиято имплементация трябва да бъде предоставена от програмиста.+ Всички външни функции се събират и се записват в генерирания xxxx_exter.h файл. Този пример би генерирал:++ .code+ #ifndef XXXX_EXTERN_H+ #define XXXX_EXTERN_H XXXX_EXTERN_H++ extern machine_buffer_t* light(machine_buffer_t *arguments,machine_buffer_t *input);+ extern machine_buffer_t* prod_light_bulb(machine_buffer_t *arguments,machine_buffer_t *input);+ extern machine_buffer_t* prod_light_controler(machine_buffer_t *arguments,machine_buffer_t *input);+ extern machine_buffer_t* prod_timer(machine_buffer_t *arguments,machine_buffer_t *input);++ #endif++ .code end++ Ето и една примерна тяхна импелементация заедно с \f[B]main\f[] функцията:++ .code+ machine_buffer_t* light(machine_buffer_t *arguments,machine_buffer_t *input)+ {+ printf("light %s\n",arguments->buffer);+ return NULL;+ }+ machine_buffer_t* prod_light_bulb(machine_buffer_t *arguments,machine_buffer_t *input)+ {+ push_event_to_machine(light_bulb,light_bulb_EVENT_SWITCH_STATE,NULL);+ return NULL;+ }+ machine_buffer_t* prod_light_controler(machine_buffer_t *arguments,machine_buffer_t *input)+ {+ push_event_to_machine(light_controler,light_controler_EVENT_SIGNAL,NULL);+ return NULL;+ }+ machine_buffer_t* prod_timer(machine_buffer_t *arguments,machine_buffer_t *input)+ {+ push_event_to_machine(timer,timer_EVENT_TICK,NULL);+ sleep(1);+ return NULL;+ }+ int main()+ {+ push_event_to_machine(light_controler,light_controler_EVENT_START_BLINKING,NULL);+ push_event_to_machine(timer,timer_EVENT_START,NULL);+ return 0;+ }++ .code end+ Това ни дава изхода:+ .code+ light on+ light off+ light on+ light off+ light on+ light off+ light on+ light off+ light on+ \&...+ \&...+ .code end++ .heading "Формално описание на езика" 2+ Със затъмнените думи и символи обозначавам думи и символи, които трябва да се интерпретират директно.+ .heading "Програма" 3+ .right+ .nf+ програма : машина [ програма ]+ .fi+ .right end+ Програмата е поредица от машини. Всяка машина има уникално име.+ .heading "Машина" 3+ .right+ .nf+ машина : \f[BI]machine\f[] име \f[BI][\f[] вътрешна част на машината \f[BI] ] ; \f[]+ вътрешна част на машината : \f[BI]states [\f[] поредица от състояния \f[BI] ] ; \f[] [ вътрешна част на машината ]+ \f[BI]events [\f[] поредица от събития \f[BI] ] ; \f[] [ вътрешна част на машината ]+ \f[BI]transitions [\f[] поредица от преходи \f[BI] ] ; \f[] [ вътрешна част на машината ]+ \f[BI]starting on \f[] име на състояние \f[BI];\f[] [ вътрешна част на машината ]+ .fi+ .right end++ В една машина може да се срещне само веднъж декларация на състоянията, събитията, преходите и посочване на стартиращо състояние.+ Декларацията на стартиращо състояние трябва да е след декларацията на състоянията. То трябва да е сред декларираните състояния.+ Декларацията на преходите трябва да е след декларациите на състоянията и на събитията.+ Сред декларираните състояния и събития не трябва да има повтарящи се.+ Сред преходите не трябва да има две различни, които излизат от едно състояние и имат за етикет едно събитие.+ .heading "Преход" 3+ .right+ .nf+ преход : \f[BI] from \f[] име-на-състояние+ \f[BI] to \f[] име-на-състояние \f[BI] on \f[] име-на-събитие [ опашка-на-прехода ] \f[BI];\f[]+ опашка-на-прехода : [ \f[BI] granted \f[] израз ] [ условно-изпълнение ]+ условно-изпълнение : \f[BI] if \f[] израз условно-изпълнение [ \f[BI] else \f[] условно-изпълнение ]+ условно-изпълнение : \f[BI] execute \f[] опашка на изпълнението+ опашка-на-изпълнението : име-на-външна-функция \f[BI]"\f[]символен-низ\f[BI]"\f[] [ \f[BI] | \f[] опашка-на-изпълнението ]+ .fi+ .right end++ Ако изразът след \f[BI]granted\f[] е истина то преходът се реализира и командите в условното изпълнение се изпълняват спрямо семантиката,+ иначе преходът не се изпълнява и опашката на преходът не се изпълнява.+ Ако изразът след \f[BI]if\f[] е истина то условното изпълнение след изразът се изпълнява, иначе, ако има \f[BI]else\f[]+ съответстващ на \f[BI]if\f[]-а то условното узпълнение след \f[BI]else\f[] се изпълнява.+ Ако условното изпълнение е от типа започващ с \f[BI]execute\f[] то външните функции се изпълняват в ред на срещане+ като изходът на всяка се подава на следващата. Изходът на последната изпълнена функция се изхвърля.+ .heading "Израз" 3+ .right+ .nf+ израз : израз-или+ израз-или : израз-и [ \f[BI]|| \f[] израз-или ]+ израз-и : израз-не [ \f[BI]&& \f[] израз-и ]+ израз-не : [\f[BI]!\f[]]базов-израз+ базов-израз : име-на-машина\f[BI].\f[]име-на-състояние | \f[BI](\f[]израз\f[BI])\f[]+ .fi+ .right end++ Израз може да се оцени до истина или лъжа.+ Логическите оператори имат обичайната семантика.+ В базовия израз е позволено да се посочват състояния на други машини, но не е позволено да се посочват състояния на машината,+ в която се намира изразът. Тези посочвания се оценяват до истина ако посочената машина е заела посоченото състояние.+ Могат да се посочват имена на машини, които са декларирани след сегашната, но те трябва да съществуват. Това важи и за състоянията, те трябва също и да принадлежат на посочената машина.++ .heading "Детайли на имплементацията"+ За да се реализира обмена на информация между генерирания код и написания,+ е дефинирана структура \f[B]machine_buffer_t\f[], в която се записват данните и техният размер.+ Генерират се и няколко помощни функции, които улесняват работата с такива структури.+ За да се запази свойството - командите на преходът да се изпълнят преди състоянието да се смени,+ се използва опашка, в която се записват+ .heading "Описание на командните аргументи"+ Имплементацията на този език предадена от автора приема следните аргументи.++ .code+ --print-tokens+ .code end+ Извежда разпознатите лексеми+ .code+ --print-ast+ .code end+ Извежда разпознатите структури в текста. ( Абстрактното синтактично дърво )+ .code+ -o име-на-файл | --output име-на-файл+ .code end+ Посочва префиксът на генерираните файлове. Например \f[B]xxxx.h xxxx.c xxxx_external.h\f[].+ .code+ --extern-mutex+ .code end+ Добавя мутекс преди и след подаването на събитие. Този мутекс трябва да се имплементира външно.+ .code+ --extern-queue+ .code end+ Дава възможност на програмиста да даде собствена имплементация на опашката използвана при задържането на събития.+ .code+ --extern-buffer+ .code end+ Дава възможност на програмиста да даде собствена имплементация на структурата използвана за пренос на данни.++ .heading "Забележки"+ За имплементацията е използвана само стандартната \*[C] библиотека, което би помогнало този транспилатор да бъде+ компилиран до много операционни системи.+ .heading "Бъдещи насоки"+ .list+ .item+ Да се добави ключова дума \f[B]signal\f[] която да праща сигнал до определена машина, за да не трябва да го имплементира програмистът.+ .item+ Да се добави семанитка за състояния и събития, като например - 'при пристигане до това състояние изпълни ... '.+ .item+ Да се направи така, че отделните машини да могат да бъдат на различни физически устройства, т.е. да бъде направен разпределен.+ .item+ Да се направи на пълен език за програмиране.+ .list end+ .finishF diff --git a/doc/en.txt b/doc/en.txt new file mode 100644 --- /dev/null +++ b/doc/en.txt+ MEGATRON transpiler for a language describing automatas++ Here is a description of the language++++ Things encased with "" are to be taken literally, things encased in [] are optional,+ things encased with () are grouped and are to be taken as a unit,+ things encased in {} can appear zero or more times and things encased in {}+ can appear one+ or more times++ Syntax:+ <program> := { <machine definition> }+++ <machine definition> := <id> "[" <machine internals> "]" ";"++ <machine internals> := { <states definition> ";" | <events definition> ";" | <transitions definition> ";" \+ | "starting" "on" <id> ";" }++ <states definition> := "states" "[" { <id> [ "on" "entering" <execute statement> ] \+ [ "on" "exiting" <execute statement> ] }+ "]"++ <events definition> := "events" "[" { <id> }+ "]"+ <transitions definition> := "transitions" "[" { <transition> ";" }+ "]"+ <transition> := "from" <id> "to" <id> "on" "event" <id> [ <granted statement> ] [ <if statement> ] ";"++ <if statement> := <execute statement>+ <if statement> := "if" "(" <expression> ")" <if statement> [ "else" <if statement> ]++ <granted statement> := "granted" "(" <expression> ")"++ <execute statement> := "execute" <pipeline>+ <pipeline> := <id> [ <string> ] [ "|" <pipeline> ]++ <primary expression> := <id> "." <id> | "(" <expression> ")"+ <not expression> := "!" <not expression> | <primary expression>+ <and expression> := <not expression> "&&" <and expression>+ <or expression> := <and expression> "||" <or expression>+ <expression> := <or expression>++ Constraints:+ The name of each machine id shall be unique in a program.++ The order of the machine declarations do not matter to the constraint checks.++ In the internals of each machine there will be exactly one states definition, events definition, transitions+ definition and starting state declaration.++ State ids shall not have duplicates in the same machine they are defined, meaning you could have a state+ id appear in two machines.++ Event ids shall not have duplicates across all machines, meaning you can not have an event id appear in+ two machines at the same time in the same program. The same goes with machine ids.++ Event ids, machine ids and pipeline ids share a namespace, meaning you can not have an id that is both+ a machine id and an event id at the same time or a pipeline id that is a machine id.++ Let a primary expression be in the form <id> "." <id>. The first id shall be a machine id and the second+ a state id that belongs to the denoted machine.++ Transition ids shall be state id belonging to the machine the transitions declaration apears in.++ The first id in a transition shall not appear as the first id in another transition in the same+ transition definition. Meaning you can not have multiple transitions stemming from the same state.++ Semantics:+ A program describes a set of possibly interdependant automata that execute external code upon certain conditions.++ A machine is always in a single state, starting on the starting state.++ The outside environment can pass events to any machine. The machine switches states and executes+ external functions. The events are processed in the order they arrive.++ If no transition can take an event, the event is dropped.+ A transition of states occurs if there is no granted part to the transition.+ If there is a granted part of the transition then the expression in the granted part must evaluate to 1+ otherwise the transition does not occur and the event is dropped.++ If a transition occurs then and only then is the conditional execution of external functions executed.+ Meaning that the if does not go off if the granted statement fails.++ A primary expression in the form <id> "." <id> evaluates to 1 if the machine with the first id+ is currently in the state with the second id, otherwise it evaluates to 0. For example M.a is 1+ if the machine 'M' is in the state 'a'.F diff --git a/doc/makefile b/doc/makefile deleted file mode 100644 --- a/doc/makefile +++ /dev/null- install:- cat project.mg | preconv | groff -mg -Tps > a.ps- ps2pdf a.ps a.pdfF diff --git a/doc/project.mg b/doc/project.mg deleted file mode 100644 --- a/doc/project.mg +++ /dev/null- .ps +1- .vs +1- .start- .ds C \f[B]C\f[]- .title "Проект по компютърни системи за управление на роботи"- .title "Език за улесняване на програмиране на вградени устройства"- .author "Галин Симеонов Ф.Н. 81635" "gtsimeonov@uni-sofia.bg"- .heading "Увод"- .paragraph- При програмирането на вградени устройства,- някои от проблемите се моделират чрез автомати.- Също е практика да се програмира на езици от ниско ниво, като \*[C],- при които ръчното имплементиране на автомати с каквито и да е размери- често е неинтуитивно, предразполагащо към грешки и трудоемко.- С цел да помогна разработването на програми, чийто модел е ориентиран околу- състоянията на системата, предлагам и имплементирам експериментален миниатюрен език транспилиращ до \*[C].- .paragraph- За цели имам той да е прост, интуитивен и евентуално лесен за генериране от инстурменти с графичен интернфейс- .footnote- Макар, че директното генериране на код без този език да действа като посредник би било по-смислено.- .footnote end- \&.- .heading "Описание на езика"- .heading "Общ поглед" 2- Една 'програма' съдържа един или повече 'машини', които действат като контейнери за състояния,събития и преходи.- Всяка машина си има име и има отделно пространство за имена на състояния и събития.- Чрез преходите може да се извикват външни функции.- Ето най-простият пример за това как изглежда кодът:-- .code- machine light_bulb- [- states [ ON , OFF ];- events [ TURN_ON , TURN_OFF , SWITCH_STATE ];- starting on OFF;- transitions- [- from ON to OFF on event TURN_OFF;- from ON to OFF on event SWITCH_STATE;-- from OFF to ON on event TURN_ON;- from OFF to ON on event TURN_ON;- ];-- ];- .code end-- След транспилация се генерират 3 файла - xxx.h xxx.c и xxx_external.h, който съответно съдържат- декларациите на служебните функции, тяхната имплементация и декларациите на външните функции, които са използвани от някой преход.- Подаването на събития към тези 'автомати' става посредством служебната функция - \f[B]push_event_to_machine\f[]-- Горният пример не е много функционален, защото комуникацията е само в една посока.- За да може да връща информация и да има функционалност, на всеки преход може да се сложат функции, които да бъдат изпълнени преди преходът да е завършил- .footnote- Това свойство е важно и авторът се е стремил да го запази. Това позволява, например, да се подават събития от функции изпълнени по време на преход- .footnote end- \&.- Taка горният пример може да бъде преработен да вика функция, която действително да включва и изключва някаква лампа:-- .code- machine light_bulb- [- states [ ON , OFF ];- events [ TURN_ON , TURN_OFF , SWITCH_STATE ];- starting on OFF;- transitions- [- from ON to OFF on event TURN_OFF- execute light "off";- from ON to OFF on event SWITCH_STATE- execute light "off";-- from OFF to ON on event TURN_ON- execute light "on";- from OFF to ON on event TURN_ON- execute light "on";- ];-- ];- .code end-- Тук също е демонстрирано как се подават аргументи към тези функции.- Символните низове са избрани като единствен начин да се подават аргументи, защото е предвидено да се транспилира до езици, различни от \*[C],- а въвеждането на типова система или нещо, което да описва различните аргументи би натоварило езикът твърде много и би донесло само минимална печалба.- .paragraph- Възможно е да има повече от една 'машина' в кодът. Например, нека към горния пример добавим:-- .code- machine light_controler- [- states [ STATIC , BLINKING ];- events [ SIGNAL , GO_STATIC, START_BLINKING ];- starting on STATIC;- transitions- [- from STATIC to BLINKING on event START_BLINKING;- from BLINKING to STATIC on event GO_STATIC;-- from BLINKING to BLINKING on event SIGNAL- execute prod_light_bulb;-- ];-- ];-- machine timer- [- states [ ON , OFF ];- events [ TICK , START , STOP ];- starting on OFF;- transitions- [- from ON to OFF on event STOP;- from OFF to ON on event START- execute prod_timer;- from ON to ON on event TICK- execute prod_timer | prod_light_controler;- ];-- ];- .code end-- Тук може да се види и 'навързване' на различни функции.- timer 'машината' праща сигнал до себе си и до light_controler, а light_controler праща сигнал до light_bulb.- Тук можем да прескочим предаването на събития между 'машините' чрез използването на \f[B]if\f[].- Променяме третия преход от timer:-- .code- from ON to ON on event TICK- if(light_controler.BLINKING)- execute prod_timer | prod_light_bulb;-- .code end-- Това е условно изпълнение на командите, преходът се случва и състоянието е променено независимо от истинността на условието.- За реализацията на условен преход, в езикът има \f[B]granted\f[] ключовата дума.- Горното може да се опитаме да имплементираме по следния начин:-- .code- from ON to ON on event TICK granted (light_controler.BLINKING)- execute prod_timer | prod_light_bulb;- .code end-- Тук има проблема, че timer спира да работи ако light_controler не е в състояние BLINKING,- защото преходът няма да се случи и \f[B]execute prod_timer\f[] няма да се изпълни.- .footnote- Това, че този пример може да бъде имплементиран на \*[C] под 10 реда, е забелязано от автора.- .footnote end- .paragraph- \f[B]prod_timer\f[],\f[B]prod_light_bulb\f[],\f[B]prod_timer\f[] и \f[B]light\f[] са функции, чиято имплементация трябва да бъде предоставена от програмиста.- Всички външни функции се събират и се записват в генерирания xxxx_exter.h файл. Този пример би генерирал:-- .code- #ifndef XXXX_EXTERN_H- #define XXXX_EXTERN_H XXXX_EXTERN_H-- extern machine_buffer_t* light(machine_buffer_t *arguments,machine_buffer_t *input);- extern machine_buffer_t* prod_light_bulb(machine_buffer_t *arguments,machine_buffer_t *input);- extern machine_buffer_t* prod_light_controler(machine_buffer_t *arguments,machine_buffer_t *input);- extern machine_buffer_t* prod_timer(machine_buffer_t *arguments,machine_buffer_t *input);-- #endif-- .code end-- Ето и една примерна тяхна импелементация заедно с \f[B]main\f[] функцията:-- .code- machine_buffer_t* light(machine_buffer_t *arguments,machine_buffer_t *input)- {- printf("light %s\n",arguments->buffer);- return NULL;- }- machine_buffer_t* prod_light_bulb(machine_buffer_t *arguments,machine_buffer_t *input)- {- push_event_to_machine(light_bulb,light_bulb_EVENT_SWITCH_STATE,NULL);- return NULL;- }- machine_buffer_t* prod_light_controler(machine_buffer_t *arguments,machine_buffer_t *input)- {- push_event_to_machine(light_controler,light_controler_EVENT_SIGNAL,NULL);- return NULL;- }- machine_buffer_t* prod_timer(machine_buffer_t *arguments,machine_buffer_t *input)- {- push_event_to_machine(timer,timer_EVENT_TICK,NULL);- sleep(1);- return NULL;- }- int main()- {- push_event_to_machine(light_controler,light_controler_EVENT_START_BLINKING,NULL);- push_event_to_machine(timer,timer_EVENT_START,NULL);- return 0;- }-- .code end- Това ни дава изхода:- .code- light on- light off- light on- light off- light on- light off- light on- light off- light on- \&...- \&...- .code end-- .heading "Формално описание на езика" 2- Със затъмнените думи и символи обозначавам думи и символи, които трябва да се интерпретират директно.- .heading "Програма" 3- .right- .nf- програма : машина [ програма ]- .fi- .right end- Програмата е поредица от машини. Всяка машина има уникално име.- .heading "Машина" 3- .right- .nf- машина : \f[BI]machine\f[] име \f[BI][\f[] вътрешна част на машината \f[BI] ] ; \f[]- вътрешна част на машината : \f[BI]states [\f[] поредица от състояния \f[BI] ] ; \f[] [ вътрешна част на машината ]- \f[BI]events [\f[] поредица от събития \f[BI] ] ; \f[] [ вътрешна част на машината ]- \f[BI]transitions [\f[] поредица от преходи \f[BI] ] ; \f[] [ вътрешна част на машината ]- \f[BI]starting on \f[] име на състояние \f[BI];\f[] [ вътрешна част на машината ]- .fi- .right end-- В една машина може да се срещне само веднъж декларация на състоянията, събитията, преходите и посочване на стартиращо състояние.- Декларацията на стартиращо състояние трябва да е след декларацията на състоянията. То трябва да е сред декларираните състояния.- Декларацията на преходите трябва да е след декларациите на състоянията и на събитията.- Сред декларираните състояния и събития не трябва да има повтарящи се.- Сред преходите не трябва да има две различни, които излизат от едно състояние и имат за етикет едно събитие.- .heading "Преход" 3- .right- .nf- преход : \f[BI] from \f[] име-на-състояние- \f[BI] to \f[] име-на-състояние \f[BI] on \f[] име-на-събитие [ опашка-на-прехода ] \f[BI];\f[]- опашка-на-прехода : [ \f[BI] granted \f[] израз ] [ условно-изпълнение ]- условно-изпълнение : \f[BI] if \f[] израз условно-изпълнение [ \f[BI] else \f[] условно-изпълнение ]- условно-изпълнение : \f[BI] execute \f[] опашка на изпълнението- опашка-на-изпълнението : име-на-външна-функция \f[BI]"\f[]символен-низ\f[BI]"\f[] [ \f[BI] | \f[] опашка-на-изпълнението ]- .fi- .right end-- Ако изразът след \f[BI]granted\f[] е истина то преходът се реализира и командите в условното изпълнение се изпълняват спрямо семантиката,- иначе преходът не се изпълнява и опашката на преходът не се изпълнява.- Ако изразът след \f[BI]if\f[] е истина то условното изпълнение след изразът се изпълнява, иначе, ако има \f[BI]else\f[]- съответстващ на \f[BI]if\f[]-а то условното узпълнение след \f[BI]else\f[] се изпълнява.- Ако условното изпълнение е от типа започващ с \f[BI]execute\f[] то външните функции се изпълняват в ред на срещане- като изходът на всяка се подава на следващата. Изходът на последната изпълнена функция се изхвърля.- .heading "Израз" 3- .right- .nf- израз : израз-или- израз-или : израз-и [ \f[BI]|| \f[] израз-или ]- израз-и : израз-не [ \f[BI]&& \f[] израз-и ]- израз-не : [\f[BI]!\f[]]базов-израз- базов-израз : име-на-машина\f[BI].\f[]име-на-състояние | \f[BI](\f[]израз\f[BI])\f[]- .fi- .right end-- Израз може да се оцени до истина или лъжа.- Логическите оператори имат обичайната семантика.- В базовия израз е позволено да се посочват състояния на други машини, но не е позволено да се посочват състояния на машината,- в която се намира изразът. Тези посочвания се оценяват до истина ако посочената машина е заела посоченото състояние.- Могат да се посочват имена на машини, които са декларирани след сегашната, но те трябва да съществуват. Това важи и за състоянията, те трябва също и да принадлежат на посочената машина.-- .heading "Детайли на имплементацията"- За да се реализира обмена на информация между генерирания код и написания,- е дефинирана структура \f[B]machine_buffer_t\f[], в която се записват данните и техният размер.- Генерират се и няколко помощни функции, които улесняват работата с такива структури.- За да се запази свойството - командите на преходът да се изпълнят преди състоянието да се смени,- се използва опашка, в която се записват- .heading "Описание на командните аргументи"- Имплементацията на този език предадена от автора приема следните аргументи.-- .code- --print-tokens- .code end- Извежда разпознатите лексеми- .code- --print-ast- .code end- Извежда разпознатите структури в текста. ( Абстрактното синтактично дърво )- .code- -o име-на-файл | --output име-на-файл- .code end- Посочва префиксът на генерираните файлове. Например \f[B]xxxx.h xxxx.c xxxx_external.h\f[].- .code- --extern-mutex- .code end- Добавя мутекс преди и след подаването на събитие. Този мутекс трябва да се имплементира външно.- .code- --extern-queue- .code end- Дава възможност на програмиста да даде собствена имплементация на опашката използвана при задържането на събития.- .code- --extern-buffer- .code end- Дава възможност на програмиста да даде собствена имплементация на структурата използвана за пренос на данни.-- .heading "Забележки"- За имплементацията е използвана само стандартната \*[C] библиотека, което би помогнало този транспилатор да бъде- компилиран до много операционни системи.- .heading "Бъдещи насоки"- .list- .item- Да се добави ключова дума \f[B]signal\f[] която да праща сигнал до определена машина, за да не трябва да го имплементира програмистът.- .item- Да се добави семанитка за състояния и събития, като например - 'при пристигане до това състояние изпълни ... '.- .item- Да се направи така, че отделните машини да могат да бъдат на различни физически устройства, т.е. да бъде направен разпределен.- .item- Да се направи на пълен език за програмиране.- .list end- .finish