Zadanie 5 (termin oddania: 12 stycznia 2006, godz. 23:59) Makrem (od angielskiego słowa "macro") nazywamy przyporządkowanie nazwie pewnego tekstu, nazywanego treścią makra. Rozwinięciem makra w tekście nazywamy zastąpienie jego nazwy treścią. (Uwaga: to definicja uproszczona - często spotykamy mechanizmy makr znacznie bardziej złożone, niż przedstawiony w tym zadaniu). Napisz program który, wywołany z trzema argumentami będącymi nazwami plików tekstowych, nazywanych dalej odpowiednio plikiem makr, plikiem danych i plikiem wynikowym, utworzy plik wynikowy kopiując do niego zawartość pliku danych i rozwijając przy tym makra zdefiniowane w pliku makr. W pliku makr zapisane są kolejno ich definicje, każda w oddzielnym wierszu. Każdy wiersz rozpoczyna się od nazwy makra, będacej małą literą. Reszta wiersza, aż do jego końca, jest treścią makra. Koniec wiersza do treści makra już nie należy. W pliku danych użycie makra oznaczamy pytajnikiem, po którym następuje nazwa. Wystąpienie dwóch pytajników oznacza, że nie mamy tu do czynienia z nazwą makra i do pliku wynikowego należy wpisać jeden pytajnik. Użycie makra może też wystąpić w treści (innego) makra. Podczas rozwijania jednego makra może się pojawic potrzeba rozwinięcia innego. Np. jeśli w pliku makra.txt jest: aAl?x z?a ?m ?k mm?x kkot?x xa a w pliku dane.txt: Czy ?z?? Tak. ?a ?k ?m. to program wywołany poleceniem: ./zad5 makra.txt dane.txt wynik.txt powinien utworzyć plik wynik.txt o zawartości: Czy Ala ma kota? Tak. Ala kota ma. Uwagi: Można założyć, że wiersze w pliku makr nie są długie, a więc całą definicję makra można wczytać na zmienną typu string. Nie wolno jednak przyjmować takiego założenia w stosunku do pliku danych i tym bardziej pliku wynikowego, gdyż w rezultacie rozwinięcia makra możemy otrzymać tekst bardzo długi. Program powinien sprawdzać poprawność danych. Jedynym warunkiem, którego badać nie trzeba, jest brak cyklu w definicji makr (chodzi o sytuację, w której makro korzysta, bezpośrednio lub pośrednio, z siebie samego). Program po stwierdzeniu błędu, powinien wypisać na standardowe wyjście jeden wiersz ze słowem "BLAD" (bez cudzysłowów z L, a nie Ł). Wskazówki: Liczbę argumentów, które program otrzymał w chwili wywołania, daje bezparametrowa funkcja "paramcount", a ich wartości funkcja "paramstr(i)", gdzie "i" jest numerem kolejnym argumentu, liczonym od 1. W rozwiązaniu zadania pomocna może się okazać rekurencja.