Jump to content

Archived

This topic is now archived and is closed to further replies.

Sebekkot

Program do szkoły

Recommended Posts

Tak jak w opisie mam do napisania program który przetwarza kod źródłowy programu napisanego w c++ na schematy blokowe. Program ma mieć interfejs tekstowy i ma wyświetlać te schematy za pomocą kodów ascii.

Żeby było jasne nie szukam gotowego kodu. Tylko porad jak to sobie dobrze zaplanować przebieg pisania programu.

"Rozróżnianie" słów kluczowych np. cout, if, itd. zrobiłbym tak: linijka tekstu jest "ładowana" do tablicy char'ów a następnie funkcja wyszukiwania słów kluczowych przetwarza słowa kluczowe na schematy blokowe.

Czyli coś takiego:

cout<<"jakiś tekst"<<endl; funkcja rozpoznała instrukcję cout<< i wyświetla napis zawarty pomiędzy << << czyli:

______

/ \

| start |

\______/

|

|

___________

/ Jakiś tekst /

---------------

|

|

______

/ \

| stop |

\______/

To oczywiście jest prosty przykład z instrukcją cout. Uważam że moja wiedza o c++ pozwala mi na napisania tego programu. Lecz jednak proszę was o pomoc w zaplanowaniu pisania tego programu i jakieś sugestie. Program mam oddać zaraz na początku marca. (na podglądzie posta widzę że schemat bloku start i stop źle się sformatował i nie mogę tego poprawić ale na pewno wiecie o co chodzi)

Link to comment
Share on other sites

Przede wszystkim to dość ambitny projekt.

Nie wiem jak dokładnie brzmi treść zadania, ale ja bym to podzielił na dwa osobne programy:

1) parser, analizuje podany kod i zapisuje strukturę kodu do pliku,

2) przeglądarkę, odczytuje strukturę kodu z pliku i wyświetla.

Dzięki temu masz dwa dość proste programy. Użycie pliku ze strukturą danych powinno Ci ułatwić debuggowanie obu programów.

Co do samego zadania.

Podstawowym blokiem kodu w C/C++ są funkcje. Dlatego proponuje zacząć od napisania programu, który wyszuka w podanych plikach .c/.cpp/itp. wszystkie definicje funkcji (na razie olej deklaracje oraz dyrektywy include) i zapisze je do pliku.

Proponuje taką strukturę danych:

struct Function
{
   unsigned int fileNameSize;            // rozmiar ścieżki
   char * fileName                           //ścieżka do pliku zawierającego funkcję
   unsigned int functionNameSize;     //rozmiar nazwy
   char * functionName;                   //nazwa funkcji
   unsigned int definitionFirstLine;     //linia w której zaczyna się definicja
   unsigned int definitionLineNumber;//liczba linii
};

Najlepiej będzie przechowywać to w jakieś tablicy, np std::vector. Takie rozwiązanie zapewni, że każda funkcja będzie miała indeks, który ją jednoznacznie identyfikuje. Choć działanie programu nie będzie zbyt optymalne, ze względu na dużą liczbę relokacji wektora (można temu nieco zaradzić wstępnie rezerwując większy obszar pamięci).

Mając taką bazę, spróbowałbym rozwiązać dyrektywy include, potem deklaracje funkcji. To uznałbym za pierwszy etap prac.

Drugi etap to podział funkcji na bloki do diagramów. Generalnie stosuje się takie bloki:

- początek funkcji,

- koniec funkcji,

- blok warunkowy,

- blok funkcyjny.

Początek wskazuje na jeden blok.

Koniec nie wskazuje na nic.

Blok warunkowy wskazuje na dwa różne bloki, jeden dla warunku spełnionego drugi dla warunku niespełnionego. Ponadto powinien zawierać informację o samym warunku.

Blok funkcyjny wskazuje na jeden blok oraz zawiera jakiś kod.

W C++ natomiast mamy:

- blok kodu (działania na typach podstawowych),

- warunek if,

- switch,

- "operator warunkowy" warunek ? wyr1 : wyr2,

- wywołanie funkcji,

- pętle while

- pętle do while

- pętle for,

- słowa kluczowe break, continue, return, goto,

- bloki try catch.

Trzeba przygotować parser, który będzie generował strukturę diagramu z kodu C++.

struct Start
{
   unsigned int NextBlock;
};

struct End
{
};

struct If
{
   unsigned int NextBlockSuccess;
   unsigned int NextBlockFailure;
   unsigned int ConditionSize;
   char * Condition;
};

struct Functional
{
   unsigned int NextBlock;
   unsigned int CodeSize;
   char * Code;
};

enum BlockType
{
   BlockType_Start,
   BlockType_End,
   BlockType_If,
   BlockType_Functional,
};

struct Block
{
   BlockType Type;
   union
   {
      Start StartBlock;
      End EndBlock;
      If IfBlock;
      Function FunctionalBlock;
   } Data;
};

struct Function
{
   ...
   unsigned int StartBlock;
};

W etapie trzecim można się pokusić o analizę bloków funkcyjnych pod kątem wywoływanych funkcji. Dopiero w etapie czwartym podjąłbym się wyszukiwania znanych funkcji, jak wypisywanie tekstu.

Kilka uwag:

void fun(); //deklaracja

void fun()   //definicja
{
}

W C++ nazwa funkcji, w przeciwieństwie do C, to nie tylko fun, ale także przestrzenie nazw, klasa/struktura i typy parametrów.

W C++, cout to nie jest słowo kluczowe, tylko obiekt globalny w przestrzeni nazw std.

cout << "blah blah" << endl;

To tak naprawdę:

std::operator << (std::operator << (cout, "blah blah"), std::endl);

Jest to wywołanie dwóch różnych funkcji.

EDIT:

W sumie to nie wiem gdzie są zadeklarowane operatory << dla strumieni. Być może są częścią klas strumieni, wtedy to wywołanie wyglądałoby nieco inaczej.

Link to comment
Share on other sites



  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...