Mercurial > pasana
view docs/node.txt @ 2:ff5e493bc9cb default tip
2003-01-29
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Sat, 13 Oct 2012 21:14:50 +0200 |
| parents | |
| children |
line wrap: on
line source
Wewnętrzna truktura drzewa parsowania ===================================== Węzły ----- Możliwych jest kilka podejść. Najbardziej bezpośrednim byłoby zdefiniowanie oddzielnej struktury danych dla każdej z produkcji gramatyki i przypisywanie symbolom powstałym z takiej produkcji takiej właśnie struktury danych jako wartość. Nie trzeba chyba wyjaśniać, że takie podejście jest bardzo uciążliwe dla człowieka. Dlatego też wybrałem początkowo inne podejście -- struktury danych tworzone są tylko dla niektórych symboli nieterminalnych, a mianowicie tych, które reprezentują pewne obiekty w sensie struktury programu, jak typy, zmienne, procedury, funkcje, polecenia, wyrażenia i tym podobne. Nadal jednak każde z nich miało swoją oddzielną strukturę danych. Ostatecznie zrezygnowałem z takiego rozdziału. Podzieliłem zbiór wszystkich rodzajów węzłów na podzbiory o podobnych własnościach i dla każdego z tych podzbiorów zdefiniowałem strukturę danych. Dodatkowe pole informuje o dokładnym rodzaju danego węzła. I tak otrzymałem 3 kategorie węzłow: 1) Symbole -- czyli wszelkie obiekty posiadające nazwę, takie jak: typy, zmienne, stałe nazwane, pola rekordów, procedury, funkcje, unity, oraz sam program. Nie wszystkie jednak symbole koniecznie muszą mieć jakąś nazwę -- dotyczy to głównie typów oraz niektórych zmiennych. 2) Polecenia -- czyli pojedyńcze rozkazy programu, takie jak: blok, instrukcja skoku, instrukcja warunkowa, pętle, przypisanie, instrukcja wiążąca, instrukcja wyboru. 3) Wyrażenia -- czyli wszystko to, co można do czegoś przypisać, co ma jakąś wartość, na przykład: stałe, odwołania do zmiennych i stałych nazwanych, wywołanie funkcji, operatory binarne, operatory unarne, etc. Pole mówiące o rodzaju węzła występuje zawsze jako pierwsze i jest zawsze tego samego typu -- tak aby używając rzutowania na którąkolwiek z kategorii węzłów wskaźnika void* można było poznać właściwą kategorię. Krawędzie --------- Połączenia pomiędzy węzłami to po prostu wskaźniki umieszczone jako pola w odpowiednich strukturach danych. Ich znaczenie zależy częściowo od kategorii i rodzaju węzła, choć są także `uniwersalne', takie jak pola na komentarze. Informacja o połączeniach w drugą stronę -- to znaczy informacja o przodku danego węzła -- jest znacznie prostrza do przechowania i zależy tylko od kaztegorii węzła. 1) Symbole -- mogą być potomkami wyłącznie innych symboli. Wobec tego ich pole `parent' jest wskaźnikiem na symbol. 2) Polecenia -- mogą być potomkami inncyh poleceń (jak w instrukcji warunkowej lub blokowej). Jedyny przypadek gdy tak nie jest dotyczy instrukcji blokowej (BEGIN...END) i jest traktowany jako przypadek szczególny. Jeśli pole parent takiej instrukcji jest równe NULL, to rodzicem takiego węzła jest jakiś symbol, zapisany np. w polu symbol. 3) Wyrażenia -- tutaj jest duży problem. Wyrażenia mogą wystąpić jako części składowe większych wyrażeń, jako parametry poleceń, a także w definicjach stałych nazwanych i typów. Ze względu na dość duży stopień komplikacji, jak i raczej niewielkie możliwości zastosowania, wyrażenia nie będą prawdopodobnie znały swoich przodków. Symbole ------- SymbolNode kind Zmienna wyliczeniowa, opisuje dokładny rodzaj węzła. name Nazwa danego symbolu (z zachowaniem pierwszy raz napotkanej wielkości liter). namespace Tablica symboli-dzieci (zarówno w postaci tablicy hashującej jak i listy dla zachowania kolejności). Ma wartość NULL dla symboli nie mogących mieć dzieci (bezpłodne?). Symbole na liście mogą się powtarzać. Wówczas pierwsze wystąpienie oznacza tylko deklarację, a następne oznacza definicję. parent Wskaźnik na bezpośredniego przodka w drzewie. Ma wartość NULL dla korzenia. Wskazuje w którym miejscu symbol został zadeklarowany. body Wskaźnik na węzeł instrukcji blokowej stanowiącej ciało danego programu, procedury lub funkcji. Także rozkaz przy którym znajduje się dana etykieta. Ma wartość NULL dla pozostałych rodzajów symboli. type Wskaźnik na symbol, w domyśle opisujący typ danego węzła lub jego typ bazowy (dla innych typów). Dla symboli nie mających typu ma wartość NULL. used Lista wskaźników do węzłów w których używany jest ten symbol. Dla programu jest to lista nazw podanych po nazwie. Polecenia --------- StmtNode kind Zmienna wyliczeniowa, opisuje dokładny rodzaj węzła. parent Wskaźnik do instrukcji blokowej w której jest to polecenie zawarte. Dla instrukcji blokowej będącej ciałem programu, funkcji lub procedury -- ma wartość NULL. label Jeśli polecenie jest zaetykietowane jest to wskaźnik do etykiety. W przeciwnym wypadku NULL. list Dla instrukcji blokowej i pętli REPEAT -- lista poleceń zawartych wewnątrz. Dla wywołania procedury lista parametrów aktualnych. Dla instrukcji wyboru -- lista wariantów CASE. Dla instrukcji WITH -- lista zmiennych rekordowych. Dla pozostałych węzłów NULL. stmt1 Dla pętli WHILE, instrukcji WITH i FOR oraz wariantów CASE jest to wskaźnik do zawartego w nich polecenia. Dla instrukcji warunkowej -- polecenia zaraz po THEN. Dla pozostałych węzłow NULL. stmt2 Dla instrukcji warunkowej -- polecenie po ELSE. Dla pozostałych węzłów NULL. symbol Dla instrukcji blokowej -- symbol której jest ona ciałem. Dla instrukcji przypisania -- zmienna do której następuje przypisanie. Dla instrukcji skoku -- etykieta do której nalezy wykonać skok. Dla instrukcji FOR -- licznik pętli. Dla pozostałych węzłów NULL. expr1 Dla instrukcji przypisania -- wyrażenie które należy przypisać. Dla pętli REPEAT i WHILE -- warunek końca (kontynuacji) pętli. Dla pętli FOR -- wartość początkowa licznika. Dla instrukcji wyboru i instrukcji warunkowej -- wyrażenie przełączające. Dla wariantów CASE -- wyrażenie przy którym dany wariant ma zastosowanie. Dla pozostałych NULL. expr2 Dla pętli FOR -- wartość końcowa licznika. Dla pozostałych wartości NULL. Wyrażenia --------- ExprNode kind Zmienna wyliczeniowa, opisuje dokładny rodzaj węzła. list Dla wywołania funkcji -- lista parametrów formalnych. expr1 Dla operatorów binarnych i unarnych -- wartość na jakiej działają. expr2 Dla operatorów binarnych -- druga wartość na jakiej działa. symbol Dla wywołań zmiennych i funkcji -- dana zmienna lub funkcja. Dla operatora @ -- symbol którego adres zwraca. value Dla stałych -- właściwa wartość danej stałej.
