Re: Программирование с помощью таблиц
От: velkin Россия http://blogs.rsdn.org/effective/
Дата: 12.02.21 10:01
Оценка:

Управление изменениями


Переходим к более сложному примеру взятому из статьи Модифицируемость кода (Changeability QA).

Простой исходный код в котором изменениями никак не управляют.
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    printf("Hello World!\n");
    return EXIT_SUCCESS;
}

Далее вводится понятие функционала.
Предположим есть некий функционал:
1. ...
2. …
3. поздороваться с миром
n. …

И наконец одно из решений, заключающееся в установке маркеров изменений.
#include <stdlib.h>
#include <stdio.h> // 3.c

int main(int argc, char* argv[])
{
    printf("Hello World!\n"); // 3.c
    return EXIT_SUCCESS;
}

Сразу вылезают два очевидных недостатка:
1) Код содержит лишние данные, такие как маркеры изменений, и чем они больше, тем больше засорения.
2) Управлять изменениями нужно не только на уровне строк, но и на уровне подстрок, чего не наблюдается.

Упрощение таблицы


Произведены следующие улучшения структуры таблицы.

1) Зелёный цвет обозначает заголовки столбцов


Пример:
функционал
функционал    нетерминал    отступ    1    2    3    4
функционал    нетерминал
функционал    терминал

2) Синий цвет это строки терминальных данных


Просто данные без всяких ссылок.

3) Жёлтый цвет это строки ссылочных нетерминальных данных


Пример:
строка 6
=$B$39    =$C$39

В строке располагаются ссылки на литералы. Номер строки, в данном случае 39, должен совпадать в обоих столбцах, так как есть две ссылки, на описание и на сам терминал. Комментарий должен быть всегда в одном и том же столбце, таком как B. Сама же ссылка на терминал может смещаться для удобства чтения по уровням:
столбец D уровень 1
столбец E уровень 2
столбец F уровень 3
столбец G уровень 4

Знаки доллара в номерах ячеек поставлены для того, чтобы правильно срабатывали операции с блоками ячеек:
1) Вырезать, копировать.
2) Вставить.

4) Оранжевый цвет это строки объединённых нетерминальных данных


ячейка B5
=CONCAT(C6:G37)
ячейка C39
=CONCAT(D40:D41)

Пока ещё думаю в каком столбце их лучше помещать: B, С и так далее.

Разобранный пример


  Вид формул
функционал                        
печатать/приветмир                        
приложение/точкавхода                        
функционал    нетерминал    отступ    1    2    3    4
    =CONCAT(C6:G37)                    
=$A$3    =$B$39        =$C$39            
=$A$3    =$B$44    =$C$47    =$C$44            
=$A$3    =$B$52            =$C$52        
=$A$3    =$B$45        =$C$45            
=$A$2    =$B$39    =$C$49    =$C$39            
=$A$2    =$B$44    =$C$47    =$C$44            
=$A$2    =$B$53            =$C$53        
=$A$2    =$B$45        =$C$45            
=$A$3    =$B$57    =$C$50    =$C$57            
=$A$3    =$B$59    =$C$47    =$C$59            
=$A$3    =$B$62        =$C$62            
=$A$3    =$B$57            =$C$57        
=$A$3    =$B$69    =$C$47            =$C$69    
=$A$3    =$B$58    =$C$48        =$C$58        
=$A$3    =$B$73                =$C$73    
=$A$3    =$B$70    =$C$47            =$C$70    
=$A$3    =$B$71                =$C$71    
=$A$3    =$B$72                =$C$72    
=$A$3    =$B$63        =$C$63            
=$A$3    =$B$54    =$C$49    =$C$54            
=$A$2    =$B$60    =$C$51        =$C$60        
=$A$2    =$B$62            =$C$62        
=$A$2    =$B$65                =$C$65    
=$A$2    =$B$67                    =$C$67
=$A$2    =$B$68                    =$C$68
=$A$2    =$B$66                =$C$66    
=$A$2    =$B$63            =$C$63        
=$A$2    =$B$61            =$C$61        
=$A$3    =$B$64    =$C$51        =$C$64        
=$A$3    =$B$56    =$C$47            =$C$56    
=$A$3    =$B$61            =$C$61        
=$A$3    =$B$55    =$C$49    =$C$55            
функционал    нетерминал                    
    препроцессор/директива/включить    =CONCAT(D40:D41)                
    =$B$43        =$C$43            
    =$B$46        =$C$46            
функционал    терминал                    
    препроцессор/директива/начало    #                
    препроцессор/директива/стандарт/начало    <                
    препроцессор/директива/стандарт/конец    >                
    препроцессор/директива/включить/название    include                
    отступ/обычный                     
    отступ/параметры    ,                 
    отступ/перенос/1    =CHAR(10)                
    отступ/перенос/2    =CONCAT(CHAR(10);CHAR(10))                
    отступ/перенос/уровень/1    =CONCAT(CHAR(10);"    ")                
    библиотека/стандартная/программа    stdlib.h                
    библиотека/стандартная/вводвывод    stdio.h                
    инструкция/блок/начало    {                
    инструкция/блок/конец    }                
    программа/завершение/успех    EXIT_SUCCESS                
    тип/встроенный/целый    int                
    тип/встроенный/символ    char                
    функция/главная/название    main                
    функция/печатать/название    printf                
    инструкция/конец    ;                
    функция/параметры/начало    (                
    функция/параметры/конец    )                
    функция/возврат    return                
    литарал/строка/начало    "                
    литарал/строка/конец    "                
    литерал/строка/приветмир    Hello World!                
    литерал/строка/перенос    \n                
    функция/главная/параметр/1/название    argc                
    функция/главная/параметр/2/название    argv                
    тип/встроенный/массив/начало    [                
    тип/встроенный/массив/конец    ]                
    тип/встроенный/указатель    *

  Вид текста
функционал                        
печатать/приветмир                        
приложение/точкавхода                        
функционал    нетерминал    отступ    1    2    3    4
    #include <stdlib.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    printf("Hello World!\n");
    return EXIT_SUCCESS;
}                    
приложение/точкавхода    препроцессор/директива/включить        #include            
приложение/точкавхода    препроцессор/директива/стандарт/начало         <            
приложение/точкавхода    библиотека/стандартная/программа            stdlib.h        
приложение/точкавхода    препроцессор/директива/стандарт/конец        >            
печатать/приветмир    препроцессор/директива/включить    
    #include            
печатать/приветмир    препроцессор/директива/стандарт/начало         <            
печатать/приветмир    библиотека/стандартная/вводвывод            stdio.h        
печатать/приветмир    препроцессор/директива/стандарт/конец        >            
приложение/точкавхода    тип/встроенный/целый    

    int            
приложение/точкавхода    функция/главная/название         main            
приложение/точкавхода    функция/параметры/начало        (            
приложение/точкавхода    тип/встроенный/целый            int        
приложение/точкавхода    функция/главная/параметр/1/название                 argc    
приложение/точкавхода    тип/встроенный/символ    ,         char        
приложение/точкавхода    тип/встроенный/указатель                *    
приложение/точкавхода    функция/главная/параметр/2/название                 argv    
приложение/точкавхода    тип/встроенный/массив/начало                [    
приложение/точкавхода    тип/встроенный/массив/конец                ]    
приложение/точкавхода    функция/параметры/конец        )            
приложение/точкавхода    инструкция/блок/начало    
    {            
печатать/приветмир    функция/печатать/название    
            printf        
печатать/приветмир    функция/параметры/начало            (        
печатать/приветмир    литарал/строка/начало                "    
печатать/приветмир    литерал/строка/приветмир                    Hello World!
печатать/приветмир    литерал/строка/перенос                    \n
печатать/приветмир    литарал/строка/конец                "    
печатать/приветмир    функция/параметры/конец            )        
печатать/приветмир    инструкция/конец            ;        
приложение/точкавхода    функция/возврат    
            return        
приложение/точкавхода    программа/завершение/успех                 EXIT_SUCCESS    
приложение/точкавхода    инструкция/конец            ;        
приложение/точкавхода    инструкция/блок/конец    
    }            
функционал    нетерминал                    
    препроцессор/директива/включить    #include                
    препроцессор/директива/начало        #            
    препроцессор/директива/включить/название        include            
функционал    терминал                    
    препроцессор/директива/начало    #                
    препроцессор/директива/стандарт/начало    <                
    препроцессор/директива/стандарт/конец    >                
    препроцессор/директива/включить/название    include                
    отступ/обычный                     
    отступ/параметры    ,                 
    отступ/перенос/1    
                
    отступ/перенос/2    

                
    отступ/перенос/уровень/1    
                    
    библиотека/стандартная/программа    stdlib.h                
    библиотека/стандартная/вводвывод    stdio.h                
    инструкция/блок/начало    {                
    инструкция/блок/конец    }                
    программа/завершение/успех    EXIT_SUCCESS                
    тип/встроенный/целый    int                
    тип/встроенный/символ    char                
    функция/главная/название    main                
    функция/печатать/название    printf                
    инструкция/конец    ;                
    функция/параметры/начало    (                
    функция/параметры/конец    )                
    функция/возврат    return                
    литарал/строка/начало    "                
    литарал/строка/конец    "                
    литерал/строка/приветмир    Hello World!                
    литерал/строка/перенос    \n                
    функция/главная/параметр/1/название    argc                
    функция/главная/параметр/2/название    argv                
    тип/встроенный/массив/начало    [                
    тип/встроенный/массив/конец    ]                
    тип/встроенный/указатель    *

Скачать helloworld.ods


Операции CRUD над фунционалом


CRUD — акроним, обозначающий четыре базовые функции, используемые при работе с базами данных:
1) создание (англ. create, примечание: база данных insert),
2) чтение (read, примечание: база данных select),
3) модификация (update),
3) удаление (delete).


Предположим у нас есть две разновидности функционала:
функционал                        
печатать/приветмир                        
приложение/точкавхода

и ссылки на него.

Таким образом стирая все строки со ссылками на функционал "печатать/приветмир" можно его удалить, ведь новый код будет сгенерирован автоматически. Так же можно ориентироваться на эти метаданные чтобы прочитать, изменить или добавить текущий функционал.

Благодаря микроконтролю можно осуществлять массовые операции в том числе и внутри строк кода.

Управление тегами


Древовидные теги навроде
печатать/приветмир

или
препроцессор/директива/начало

можно использовать для того, чтобы вкладывать один функционал, терминалы и прочее в другие.

Но что, если в код будет включён заголовочный файл для того, чтобы создать функционал, но благодаря нему будет создано несколько видов функционала. В этом случае можно применять точку с запятой для добавления нескольких тегов.
печатать/приветмир;печатать/покамир #include "функционал.hpp"

печатать/приветмир ...
печатать/приветмир использование функционал.hpp
печатать/приветмир ...

печатать/покамир ...
печатать/покамир использование функционал.hpp
печатать/покамир ...

И соответственно при удалении строка включения заголовочного файла не будет удалена пока не будут удалены все теги описывающего её функционала. Такое решение это то, которое первое приходит в голову, но если у кого есть идеи лучше, пишите.

продолжение следует...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.