В принципе, к Фантому можно пришлёпать почти любой язык программирования, но я попытаюсь описать тут некоторый процедурный язык, наиболее адекватный концепту.
Где это уместно язык будет использовать конструкции из Си и Си++ - ввиду того, что я их люблю. Это никаким местом, очевидно, несущественно и может быть заменено на Паскалевские аналоги. :-) Впрочем, кое-что из него и так уже взято.
Было бы любопытно выполнить привязку к Фантому Лиспа и Пролога, но мне это не осилить, увы. Практическая ценность такой привязки была бы довольно велика, тем не менее. Люди, способные к Лиспу легче, как мне кажется, воспримут своеобычность Фантома.
Основное.
1. Это не БНФ, а так... :-) 2. тут бардачок-с, надо подметать и чистить.
{} - ноль или несколько раз
[] - ноль или один раз
() - группировка
| - или
строка - выражение, возвращающее строку.
имя - дык. Идентификатор.
декларация - "var" тип ":" имя { "," имя }
тип - строка | array of тип | pointer to тип | "void"
(да, я знаю, что array of void - маразм, это детали, не хочу закапываться в них сейчас)
оператор - декларация ";" | выражение ";" | управление | блок
блок - "{" оператор { оператор } "}"
управление - if | while | for | do | switch
выражение - "{" { оператор } выражение "}" | присваивание
присваивание - (lvalue "=" присваивание) | rvalue
выражения расписывать сейчас не буду - лень.
вызов - выражение типа указатель на объект "." выражение типа указатель на метод "(" [ выражение ] { "," выражение } ")"
Тривиальщина:
if - "if" "(" выражение ")" оператор
while - "while" "(" выражение ")" оператор
for - "for" "(" выражение ";" выражение ";" выражение ")" оператор
do - "do" оператор "while" "(" выражение ")" ";"
switch - "switch" "(" выражение ")" - ну, ты понял. :-)
Трактовка выражений
Все операторы в выражениях - псевдонимы для методов своего левого аргумента.
a = b преобразуется в a.op_assign( b ), a + b - в a.op_plus( b ) и т.п.
Список:
= | assign |
=+ | add |
=- | subtract |
=* | multiply |
=/ | divide |
+ | plus |
- | minus |
/ | slash |
* | asterisk |
|| | or |
&& | and |
Наверное и достаточно этого. Остальное - специфические методы соответствующих классов. int::bitwise_or( int ), etc.
Сомнения
Есть подозрение, что тип type был бы более уместен, чем строковая переменная, содержащая имя типа. Причина - эффективность. Ничто не мешает создать type::type( string ) и потому иметь возможность указывать строку везде, где нужен тип, так что потерь в удобстве нет.