XML z lingwistycznego punktu widzenia
Barbara Klunder 24 stycznia 2008 roku
Ostatnio bardzo popularne stały się aplikacje internetowe oparte o tech- nologię języka XML, któremu będzie poświęcony ten wykład.
1 Czym jest XML?
eXtensible Markup Language czyli Rozszerzalny Język Znaczników
jest metajęzykiem służącym do opisu innych języków znacznikowych ta- kich jak HTML. Wyrósł on z SGML (Standard Generalized Markup Lan- gauge, Uogólniony Standaryzowany Język Znaczników), języka powstałego aby zaspokoić potrzeby przechowywania danych niezależnie od używanego oprogramowania.
W XML jak i w SGML konkretny język opisany w tym standardzie zwa- ny jest aplikacją. Opis taki zawary jest zwykle w DTD (Document Type Definition, Definicja Typu Dokumentu), które są wypierane przez schematy pozwalające m.in. na kontrolę typów. XML został stworzony z myślą o Inter- necie i stąd można go używać w istniejących protokołach sieciowych (HTTP, MIME) i przy użyciu tych samych mechanizmów (n.p. adresowania). Należy też pamiętać, że XML ma służyć ogólnie rozumianej wymianie informacji i jej gromadzeniu w sieci.
1. DTD służy określeniu reguł budowy dokumentu XML i weryfikacji jego zgodności z tymi regułami; proces ten zwany jest parsingiem wali- dującym.
2. Dla każdego dokumentu można ale nie trzeba podawać jego DTD; wte- dy proces zwany parsingiem bez walidacji weryfikuje pewne ogólne reguły budowy dokumentu sprowadzające się do kontroli poprawnego użycia znaczników.
Najpierw pokrótce zajmiemy się drugim zagadnieniem, aby następnie skupić się na pierwszym.
2 Użycie znaczników
Dokument XML składa się z elementów, które mogą mieć atrybuty. Z każdym elementem związane są znaczniki: zwykle początkowy i końcowy, choć mogą też być elemnty puste.
Poprawny dokument XML
1. zawiera co najmniej jeden element;
2. zawiera dokładnie jeden element, zawierający wszystkie inne (korzeń);
3. ma poprawnie zagnieżdżone elementy;
4. spełnia wymóg identyczności nazw w zaczniku początkowym i końco- wym oraz nie powtarzania nazw atrybutów w jednym elemencie.
3 Poprawność dokumentu
Zapewne nie są to wszyskie żądania, ale spełnienie ich pociąga, że taki do- kument może być interpretowany jako drzewo. W czasie wykładu pojawiło się pojęcie drzewa wyprowadzenia w gramatyce bezkonteksowej. Będzie ono istotne w dalszych rozważaniach.
Przykład DTD NIEPEŁNY
<!ELEMENT artykul (tytul,podtytul?,((akapit+,sekcl*) |sekcl+))>
<!ELEMENT tytul (#PCDATA)>
<!ELEMENT podtytul (#PCDATA)>
<!ELEMENT akapit (#PCDATA | tabela | rysunek)*>
<!ELEMENT rysunek EMPTY>
Pytanie: po co elementy puste? Zwykle wykorzystuje się je wraz z listą atry- butów do podawania danych nieanalizowanych takich jak obrazy czy dżwięki.
”Dokument” XML zbudowany według tej definicji:
<artykul> <tytul> Moje potyczki z XML </tytul>
<akapit> Po usunieciu z DTD modeli list atrybutow i informacji o typie elementu otrzymujemy gramatyke bezkontekstowa, w ktorej nie ma symboli terminalnych a
definiowane elementy sa symbolami nieterminalnymi. W definicji gramatyki stosuje sie uogolniona notacje Bakhusa-Naura.
</akapit> </artykul>
Umieszczenie słowa dokument w cydzysłowie oznacza, że nie jest to pełny dokument XML bo np. nie ma prologu dokumentu w którym umieszcza się deklarację używanej wersji XML, typu dokumentu (czyli DTD) itp. Struktu- rę tego dokumentu można przedstawić w postaci pełnego drzewa binarnego wysokości 1 o korzeniu o etykiecie artykul i liściach 1, 2 o etykietach tytul i akapit odpowiednio.
Istnieje wiele narzędzi pozwalających weryfikować poprawność dokumen- tów XML np. DXP. Należy postawić sobie pytanie co jest wyznacznikiem tej poprawności? Jak już zaznaczyliśmy wcześniej zależy on od tego czy dys- ponujemy typem dokumentu: możemy przeprowadzić parsing walidujący lub niewalidujący.
Parsing bez walidacji sprowadza się (w warstwie matematycznej) do weryfikacji poprawności użycia znaczników (patrz rozdział drugi) i różnych zastrzeżonych znaków, co zależy tylko od wersji użytego XML. Wydaje się to dosyć prostym zadaniem, choć należy zaznaczyć, że z lingwistycznego punktu widzenia mamy do czynienia z językami, które nie są regularne a bezkontek- stowe: przypomnijmy, że język poprawnie zagnieżdżonych nawiasów nie jest regularny, co bardzo łatwo wykazać stosując twierdzenie Nerode’a.
Parsing walidujący wymaga definicji typu dokumentu i polega na roz- strzygnięciu, czy drzewo odpowiadające dokumentowi jest drzewem wypro- wadzenia w gramatyce bezkontekstowej podanej w tej definicji. Obecnie omó- wimy metody matematyczne pozwalające na zaprogramowanie takiego pro- cesu.
4 Parsing walidujący a automaty na drzewach
Podobnie jak w wypadku budowania drzewa wyprowadzenia w gramatyce bezkontekstowej pojawiają się dwa typy automatów na drzewach: top-down i bottom-up, które analizują drzewo od korzenia do liści i od liści do korze- nia odpowiednio. Wydaje się, że zaprogramowanie działania (deterministycz- nego) top-down automatu jest prostsze niż bottom-up automatu. Niestety bottom-up automaty są ogólniejszym narzędziem niż top-down automaty.
Definicja 4.1 Skończonym bottom-up automatem na drzewach nazywamy układ A = (Q, F , Qf, ∆), gdzie F jest skończonym typem algebraicznym, czyli skończonym zbiorem F symboli działań wraz z funkcją arności ar : F 7→ N przyporządkowującą każdemu symbolowi jego argumentowość, Q skończonym zbiorem stanów, Qf ⊆ Q zbiorem stanów końcowych i ∆ skończonym zbiorem instrukcji postaci
f (q1(x1), . . . , qn(xn)) → q(f (x1, . . . xn))
gdzie n 0 i f jest działaniem arności n, q, q1, . . . , qnsą stanami a x1, . . . , xn są zmiennymi z pewnego ustalonego przeliczalnego zbioru X.
Uwagi
1. Dla stałych, czyli działań arności 0 instrukcje są postaci a → q(a).
2. Automat przetwarza zgodnie z instrukcjami dowolne drzewo termu bazowego w sygnaturze F , czyli termu bez zmiennych.
3. Instrukcję f (q1(x1), . . . , qn(xn)) → q(f (x1, . . . xn)) można zastosować do drzewa, gdy w drzewie znajduje się wierzchołek (o etykiecie) f i wszyscy jego bezpośredni potomkowie mają kolejno etykiety q1, . . . , qn. (Bardziej formalnie instrukcję można stosować w dowolnym kontekście i po dokonaniu dowolnego podstawienia( ważny jest kształt poddrzewa:
taki sam jak f (x1, . . . xn))) o ile zgadzają się stany.)
4. Traktując symbole stanów jako dodatkowe działania jednoargumentowe fakt, że term t0 powstał z termu t po zastosowaniu instrukcji zapisywać będziemy t →At0. Wtedy →?Ajest zwrotnio przechodnim domknięciem tej relacji, a język L(A) akceptowany przez A, to zbiór tych termów bazowych t w sygnaturze F dla których istnieje stan końcowy q taki,
Przykład Rozważmy typ F = {f (, ), g(), a} i automat o instrukcjach a → qa(a) g(qa(x)) → qg(g(x))
g(qg(x)) → qg(g(x)) f (qg(x), qg(y)) → qf(f (x, y))
Oczywiście qf jest stanem końcowym. Wtedy automat akceptuje te termy kształtu f (g(x), g(y)), które nie zawierają właściwego podtermu tego kształ- tu./
Rozważany w przykładzie automat jest deterministyczny. Podobnie jak dla klasycznej teorii zachodzi
Twierdzenie 4.2 Dla każdego bottom-up automatu na drzewach A istnieje deterministyczny bottom-up automat na drzewach A0 taki, że L(A) = L(A0).
Zajmiemy się teraz top-down automatami.
Definicja 4.3 Niedeterministycznym top-down automatem na drzewach na- zywamy układ A = (Q, F , Qi, ∆), gdzie F jest skończonym typem algebraicz- nym, Q skończonym zbiorem stanów, Qi ⊆ Q zbiorem stanów początkowych i ∆ skończonym zbiorem instrukcji postaci
q(f (x1, . . . xn)) → f (q1(x1), . . . , qn(xn))
gdzie n 0 i f jest działaniem arności n, a x1, . . . , xn są zmiennymi z pewnego ustalonego przeliczalnego zbioru X.
Podobnie dla n = 0 instrukcje są postaci q(a) → a.
Analiza drzewa t zaczyna się od korzenia, który etykietuje się jakimś sta- nem początkowym q, co znów zapiszemy q(t). Zakończenie analizy oznacza usunięcie symboli stanów, czyli język L(A) akceptowany przez top-down au- tomat A to zbiór tych termów bazowych t typu F dla których istnieje stan początkowy q taki, że q(t) →?At.
Twierdzenie 4.4 Język jest akceptowany przez top-down automat wtw, gdy jest akceptowany przez bottom-up automat.
Niestety
Twierdzenie 4.5 Istnieje język L rozpoznawalny przez deterministyczny bottom- up automat, który nie jest rozpoznawalny przez żaden deterministyczny top- down automat.
Dowód Niech L = {f (a, b), f (b, a)}, gdzie f jest jedynym symbolem binar- nym, a, b to stałe. Oto deterministyczny bottom-up automat dla tego języka:
a → qa(a) f (qa(x), qb(y)) → qf(f (x, y)) b → qb(b) f (qb(x), qa(y)) → qf(f (x, y))
Odwrócenie instrukcji i uczynienie qf stanem początkowym daje niedetermi- nistyczny top-down automat dla tego języka. Każdy deterministyczny top- down automat akceptujący f (a, b) i f (b, a) musi akceptować f (a, a)! Musi on mieć instrukcje:
q(f (x, y)) → f (q1(x), q2(y)) qi(a) → a qi(b) → b dla i = 1, 2