Translator PFortranu jest programem przetwarzającym kod źródłowy
z rozszerzeniami (operatory @,{,}) do postaci standardowego
kodu w Fortranie, w którym zamienione są one na wywołania funkcji biblioteki
message passing.
Drugą częścią pakietu jest biblioteka (libpf) funkcji
pomocniczych, która pozwala
zmniejszyć rozmiar kodu wynikowego poprzez nie powtarzanie tych samych
konstrukcji w wielu miejscach.
W tym miejscu pokrótce opiszę ogólny układ plików. W dalszej części te
fragmenty, które są istotne dla mojej pracy rozwinę nieco szerzej. Zmienna
${ARCH} w nazwach katalogów oznacza architekturę na którą
jest aktualnie kompilowana dystrybucja - w moim przypadku miała ona wartość
linux.
BIN/${ARCH} - w tym miejscu są umieszczone pliki wykonywalne
translatora
BIN/ISIM - plik wykonywalny symulatora hypercube
DOC - dokumentacja (wersje wynikowe - Postscript)
LIB/${ARCH} - biblioteki pomocnicze PFortranu
LIB/ISIM/${ARCH} - biblioteka pomocnicza ISIM
config/systems/*.h - pliki nagłówkowe zawierające definicje
specyficzne dla konkretnej architektury.
doc - dokumentacja w postaci źródłowej (TeX,troff)
foruser - przykładowe Makefile pozwalające
kompilować programy z użyciem PLanguages
isim - źródła symulatora hypercube
pc - źródła PC
pf - źródła PFortranu
tests - przykładowe programy w PFortranie
lib - biblioteka pomocnicza PFortranu
src - źródła translatora (zostaną dokładniej omówione niżej)
Translator działa według standardowego dla takich programów schematu używając narzędzi typu bison i yacc. Przepływ danych jest mniej więcej taki:
Plik wejściowy trafia do analizatora leksykalnego (pf/src/lex/*)
który dzieli go na elementarne wyrażenia Fortranu - tokeny. Na tym
etapie nie jest jeszcze analizowana logiczna struktura programu, jest
wyłącznie operacja na łańcuchach znaków. Jedynym interfejsem do dalszej
fazy translacji jest funkcja int yyparse(); zdefiniowana w
pliku pf/src/lex/main.c i zwracająca identyfikator
kolejnego tokenu w kodzie źródłowym.
W PFortranie został zastosowany anlizator z pakietu f2c rozbudowany o specyficzne rozszerzenia. Oszczędziło to autorom przepisywania Fortranu na składnię pliku źródłowego lex, a mi znakomicie utrudniło pracę. Gdyby analizator był napisany od zera z użyciem lex'a to moje modyfikacje miałyby miejsce na poziomie 'źródłowym', a tak muszę ręcznie patchować kod, który był w większości generowany automatycznie :)
Będę próbował ominąć ten problem na dwa sposoby: albo spróbuję odtworzyć modyfikacje autorów PFortrana na pliku źródłowym lex, albo (jesli sie to nie uda) spróbuję samodzielnie opisać PFortran w tej postaci - na szczęście zachowany został standardowy interfejs lex <->yacc.
Na tym etapie tokeny zwracane z poprzedniego modułu są analizowane przez
parser gramatyki. Użyte zostało standardowe narzędzie - bison, który
jest darmową wersją yacca. Autorzy ponownie posłużyli się źródłem
pakietu f2c - definicje gramatyki (pf/src/g.in) zostały
zmodyfikowane w następujący sposób:
Dzięki zachowaniu przez autorów w tym miejscu standardowych zasad (kompilacja z użyciem bisona) moja praca w tym miejscu będzie polegała głównie na modyfikacji pliku gramatyki. W związku z tym, że tak naprawdę nie rozszerzam funkcjonalności języka, a tylko nieco "osłabiam" analizator wprowadzając do niego nowe reguły nie będzie chyba konieczne dodawanie nowych fragmentów kodu przetwarzających tekst źródłowy.
Ważniejsze pliki znajdujące się w katalogu pf/src/lex:
defs.h, ftypes.h, defines.h, machdefs.herror.cexpr.cfrexpr(p) zwalniająca pamięć przydzieloną dla
wyrażenia
gram.cintr.cio.clex.cint yylex()
mem.cnames.cparse.cint yyparse(),
sprawdzanie błędów składniowych i wyświetlanie komunikatów
parse_args.cpf.hput.c, putpcc.ctokdefs.hg.inmain.chash.h, pfhash.cpfgen.cpfintr.cpflex.cgetchar(), newline() itp.)
pfu.c, sutil.credop.c{}). Zawiera m.in.
szczególy tłumaczenia redukcji liniowej tablicy z użyciem algorytmu
hypercube.