# XBUP - Popis parserů

### Úvod

Tento dokument je součástí dokumentace projektu eXtensible Binary Universal Protocol. Obsahuje popis implementace funkcí pro parsování dokumentu.

O úroveň výše

### Obsah

1. Úvod
2. Principy parsování
2.1. Typy položek
2.1.1. Rozhraní událostí
2.1.2. Proudové zpracování událostí
2.2. Stav Parseru
3. Parsery
3.1. Krokovací parser
3.1.1. Vyrovnávací proud
3.2. Objektový parser
3.2.1. Záznam zpětných kroků
3.3. Příkazový parser
3.3.1. Příkazy čtení
3.3.2. Příkazy zápisu
3.3.3. Příkazy pohybu
3.3.4. Příkazy manipulace
4. Zpracování typů bloků
4.1. Ukládání typů
4.2. Zpracování transformací
5. Odkazy

### 1. Úvod

Parsovač (parser) je program umožňující procházení strukturovaných dat definovaných gramatikou. Na výstupním rozhraní nabízí funkce ke zpřístupnění zpracovaného výsledku, nejčastěji ve formě stromové struktury.

Parsery se liší především podle způsobu, jakým si ukládají údaje o zpracovávaném dokumentu a podle úrovně protokolu, kterou jsou schopny zpracovat.

### 2. Principy parsování

Parsery se technicky liší především na nejnižší úrovni, ale mají společný základ. Je definováno společné chování a rozhraní, které by měly parsery dodržovat.

### 2.1. Typy položek

Pro úroveň 0 protokolu XBUP jsou rozpoznávány následující 4 typy položek:

- BEGIN (Terminated typu Boolean)
- ATTRIBUTE (Value typu XBAttribute)
- DATA (Data typu Byte[])
- END

Pro úroveň 1 protokolu XBUP je přidána událost TYPE:

- TYPE (Type typu BlockType)

Pro úroveň 2 protokolu XBUP se mění význam události attribute:

- ATTRIBUTE (Value typu UBNumber)

### 2.1.1. Rozhraní událostí

Základem parseru je převod datového proudu na proud rozpoznaných událostí, které se pak následně zpracovávají. Opačným postupem je pak možné i dokument generovat. Pro přístup k jednotlivým typům událostí je definováno rozhraní XBEventHandler:

public void begin(boolean term) throws XBParseException;
public void attrib(XBAttribute value) throws XBParseException;
public void data(byte[] data) throws XBParseException;
public void end() throws XBParseException;

Obdobně jsou definovány metody pro rozhraní na vyšších úrovních.

### 2.1.2. Proudové zpracování událostí

Jsou definována rozhraní XBEventReader, XBEventWriter a XBFilter, která umožňují předávání událostí a jejich modifikaci. Kombinací filtrů je možné sestavit procesní řetězec pro zpracování proudu událostí.

Read(Source: TXBEventHandler)
Write: TXBEventHandler

Dále je k dispozici abstraktní třída XBStream, která definuje posloupnost událostí a umožňuje nad tímto proudem provádět operace. Třída disponuje funkcemi, jako jsou například skok na jinou pozici v proudu a podobně.

Zda je třída převoditelná na proud XBStream indikuje rozhraní XBStreamable:

public void ReadFromXB(XBStream stream);
public void WriteToXB(XBStream stream);

Pokud je možné z dané třídy získat volání posloupnosti událostí, implementuje třída rozhraní XBEventHandler:

Ke každému parseru je možné pomocí metody získat třídu, která zpřístupňuje vnitřní stav parseru a převod na událostní zpracování.

### 2.2. Stav Parseru

Parser úrovně 0 se při čtení proudu dat může nacházet v jednom z následujících stavů - pro potřeby jemnějšího rozpoznání je možné rozlišit zda se parser nachází na začátku nebo uvnitř dané oblasti:

- Start/Head - Parser je na začátku souboru / Parser se nachází uvnitř hlavičky souboru
- Node - Parser se nachází na začátku bloku nebo čte jeho hlavičku (délku)
- Attrib - Parser čte nebo bude číst atribut
- Data - Parser čte nebo bude číst data datového bloku
- Extended - Parser se nachází před (přečetl poslední blok) nebo uvnitř rozšířené oblasti
- Eof (End of file) - Parser se dostal na konec souboru

### 2.3. Chybové stavy

Při parsování dokumentu může dojít k řadě chyb na různých úrovních. Pokud to konstrukce jazyka umožňuje, generuje parser vyjímku (exception), případně běhovou chybu, jejímž ošetřením je možné různé chyby podchytit. Kromě toho bude pravděpodobně k dispozici tolerantní parser, který zpracuje dokument i přesto, že se budou v dokumentu vyskytovat chyby.

### 3. Parsery

Pro potřeby protokolu se předpokládá implementace tří typů parserů, krokovací parser, parser objektového modelu a příkazový parser. Jednotlivé parsery se liší především podle množství využité paměti a tedy také podle složitosti implementace, rychlosti a náročnosti operací, které je možné nad zpracovávanými daty provádět.

### 3.1. Objektový parser

Tyto parsovací třídy zpracují celý soubor a vytvoří v paměti jeho objektovou kopii (DOM - Document Object Model). Vlastní realizace pracuje tak, že se zkontroluje hlavička souboru a zavolá rekurzivní načtení kořenového uzlu, které obstará vše ostatní.

K objektovému modelu je samozřejmě možné také přistupovat pomocí rozložení na události.

V Delphi je funkcionalita třída implementována pomocí třídy TXBTree a TXBNode, které mají metody podobné, jako standardní třídy v Delphi.

V Javě je toto definováno ve třídách XBTree a XBTreeNode balíku net.sf.xbup.omparser.

### 3.1.1. Záznam zpětných kroků

Pro implemtaci návratu poslední změny jsou definovány třídy, které umožňují uchovávat seznam posledních změt a aplikovat reverzní operaci, nebo obnovit předchozí stav.

### 3.2. Krokovací parser

Tzv. Pull Parser, pracuje tak, že převádí vstupní soubor krok po kroku na seznam položek. Základem je jediná přístupová operace, která vrátí následující položku, instanci třídy XBPullItem, která si nese potřebné údaje. Rozhraní pro události je tedy omezeno na jedinou funkci a její postupnou aplikaci. Získané položky je pak možné převádět na události a dále zpracovávat obvyklým způsobem. Opačným postupem je pak možné generovat výstupní soubor. Parsovací nástroje tohoto typu bývají obvykle nejrychlejší a nejjednodušší na implementaci, ponechávají však většinu práce na aplikaci. V případě, že zpracováváme jednoduchý dokument, to však není na škodu. Výstup tohoto parseru je navíc vhodný pro provedení proudového zpracování, které může nad daty provést dodatečné operace.

### 3.2.1. Vyrovnávací proud

Třída XBPullBuffer implementuje třídu XBStream, přičemž jednotlivé položky událostí ukládá jakožto položky typu XBPullItem.

### 3.3. Příkazový parser

Příkazový parser pracuje na základě izolovaných příkazů na něž vrací odpovídající odpovědi. (obdoba příkazového řádku - command shell). Sada těchto příkazů umožňuje jak čtení, tak manipulaci s částmi dokumentu.

Příkazový parser je kombinací parserů předchozích. Pro potřebné části tyto zavádí do paměti jako stromovou strukturu a ukládá je teprve v případě nutnosti. Výhodou je například to, že dokud není dokument měněn, nezavádí se do paměti, pouze se udržují indexy až do maximální povolené velikosti pro rychlejší přechody mezi dokumenty. V případě, že je dokument zpracováván sekvenčně, chová se parser jako krokovací, teprve v případě skákání se vytváří pomocné indexy a v případě úprav se použije objektový model. Konstrukce parseru umožňuje provádět sofistikovanější operace, jako například úpravu souboru bez nutnosti čtení celého obsahu (zpožděný zápis, copy-on-write).

Realizace v Delphi - TXBParser - metody:

Open(Stream: TStream) - otevře pracovní proud
Close - uzavře pracovní proud
Reset - vynuluje vnitřní stavové hodnoty

Přístup ke stavovým informacím

Level - aktuální úroveň zanoření
NodeIndex/Position - aktuální pozice čteného bloku

### 3.3.1. Příkazy čtení

Tyto příkazy slouží primárně pro čtení dokumentu.

Get commands

### 3.3.2. Příkazy zápisu

Další sadou jsou příkazy, které slouží pro zápis

Put commands
Mk

### 3.3.3. Příkazy pohybu

Další série příkazů slouží k pohybu v dokumentu

Go commands
Skip commands

### 3.3.4. Příkazy manipulace

Další jsou příkazy pro složitější manipulaci s daty. Umožňují především přesouvat bloky dat. Je doporuřené v případě, že chceme takovouto operaci provést, použít raději příkaz místo dvou operací vyjmutí a vložení, neboť uvedená operace pak může být provedena efektivněji, například prostou změnou hodnot ukazatelů, nebo s využitím technik typu copy-on-write.

### 4. Zpracování typů bloků

Parsery vyšší úrovní protokolu provádějí zpracování typů bloků, atributů a aplikaci transformací.

### 4.1. Ukládání typů

Zatímco v případě objektového modelu je možné typy bloků u každého bloku uložit

### 4.2. Zpracování transformací

V případě objektového modelu je možné transformace provádět v paměti, obecně jsou však transformace postaveny na zpracování proudu událostí.

### 5. Odkazy

Pull Parsing - XML Pull Parsing
Document Object Model - XML DOM
Copy-on-Write - Wikipedia

Homepage: http://xbup.sf.net
License: GNU Free Documentation License (FDL)
Latest update: 2008-09-19