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.