Weblog @ rebex.cz

Weblogy na webu Rebexu
Welcome to Weblog @ rebex.cz Sign in | Help
in Search

Problems presenting features of interest

ANTLR v základech softwarové komponenty

Před pár měsíci jsem se tu šířil o generátoru parserů ANTLR a jeho použití při tvorbě front-endu transformujícího SQL do formátu vyžadovaného různými databázovými backendy (teoreticky je SQL standartizovaný jazyk, ovšem v praxi vidí prodejci databází příliš mnoho výhod v produktové diferenciaci, než aby standartizovali úplně všechno). Předchozí post se omezil na obecný přehled a první dojmy, ale jelikož jsem od doby jeho napsání zmiňovanou komponentu nejen úspěšně dokončil, ale dokonce ukecal zákazníka aby ji uvolnil jako Open Source, mám příležitost vrátit se k tématu podrobněji.

Komponenta se jmenuje MacroScope, a zvenčí se tváří jako víceméně obyčejný datový provider. Interně ovšem nepracuje přímo s databází, nýbrž deleguje na "opravdového" providera, a při té příležitosti přepisuje SQL specifikované aplikací tak, aby mu vnitřní provider rozumněl. Úpravy SQL jsou specifikovány nad jeho gramatikou ("Oracle nezná SELECT TOP, ale zato má funkci ROWNUM, pomocí které se dá zkonstruovat tentýž výsledek"), takže pro jejich implementaci je prakticky nezbytné SQL parsovat - a tam právě přišel ke slovu ANTLR.

Pro parsování SQL se ANTLR rozhodně osvědčil - už proto že je to úloha dost běžná, aby ji už někdo skoro udělal (pravda, pro starou verzi ANTLR, pouze SELECT a pouze pro MS SQL Server - MacroScope podporuje i Oracle a na zvláštní přání publika dokonce MS Access - ale pořád mnohem lepší než vynalézat kolo). Další velká výhoda formální gramatiky je dokumentační: podporovaná varianta SQL je přesně to co specifikuje soubor MacroScope.g. Popsat tu variantu slovně je fakticky dost obtížné - je to podmnožina definic INSERT, SELECT, UPDATE a DELETE v SQL 92, s přidanými nekompatibilními konstrukcemi z podporovaných backendů, takže když člověka zajímají detaily, řekněme jak napsat datum, je formální definice nezastupitelná:

MAccessDateTime :
	'#' Digit Digit Digit Digit '-'
		Digit Digit '-' Digit Digit ' '
		Digit Digit ':' Digit Digit ':' Digit Digit
		'#'
	;

Iso8601DateTime :
	Digit Digit Digit Digit '-'
		Digit Digit '-' Digit Digit ( 't' | ' ' )
		Digit Digit ':' Digit Digit ':' Digit Digit
	;

A je to jasné... Nad lexikálními pravidly buduje MacroScope objektový model, tj. např. pro to datum

educationalSimplification returns [ INode value ] :
	// subset of an MS Access-specific format
	| MAccessDateTime {
		$value = new LiteralDateTime($MAccessDateTime.text);
	}
	// subset of ISO 8601 recommended for SQL Server 2005
	| Iso8601DateTime {
		$value = new LiteralDateTime($Iso8601DateTime.text);
	}
	;

INode je základní interface definující protokol společný pro všechny podstromy SQL, od konstant až po kompletní příkaz. Protokol je to velmi prostý:

    public interface INode
    {
        INode Clone();

        void Traverse(IVisitor visitor);
    }
}

Veškeré transformace, včetně transformace stromu na řetězec, dělají Návštěvníci. Technicky by visitor mohl dělat i to klonování, ale rozhodl jsem se že než být purista, napíšu to radši srozumitelně. Testy na živých programátorech bylo zjištěno, že výsledný model je v zásadě použitelný pro automatizované úpravy SQL (typicky přidávání podmínek - je mnohem čistší, srozumitelnější a bezpečnější přidat objekt než hledat v řetězci "WHERE"), akorát je dost velký a uživatelé ne vždy vědí kterou třídu instancializovat - ale to už nemá s ANTLR moc společného...

Samozřejmě neexistuje jídlo zdarma a generátor kódu přináší kromě výhod i komplikace. Například takový build funguje pro jednoduché projekty úplně automaticky z IDE Visual Studia, ale s generováním kódu moc nepočítá. Visual Studio má jakési háky, ale logiku dodatečných kroků bych stejně musel programovat ručně v nějakém dalším jazyce, "podporované" .BAT soubory používat nebudu a NAnt nové uživatele zarazí IMHO méně než řekněme Perl. Kromě toho jsem stejně chtěl integrovat i unit testy používající NUnit, takže build komponenty dělá NAnt. Na druhé straně pro ruční práci s projektem (tj. hlavně debugování) má IDE Visual Studia své výhody, takže jsem se ho pokusil do buildu zahrnout: na nejvyšší úrovní je build kontrolován ručně psaným skriptem, ale všechny ostatní buildovací skripty jsou generované pomocí XSLT (NAnt na to má příkaz) z projektových souborů Visual Studia. Transformace bohužel není dost obecná aby se dala beze změn používat i v dalších projektech - vždycky se najde nějaký speciální případ, který je třeba hardcodovat - nicméně v rámci jednoho projektu je celkem stabilní. Tato organizace umožňuje používat IDE Visual Studia pro veškerý vývoj (včetně přidávání souborů do projektu) kromě změn gramatiky a spouštění unit testů. Celkem se osvědčila - největší nevýhodou je že po přidání souboru musím před spuštěním NAntu uložit projekt - a rozhodně ji zkusím i při dalších příležitostech.

Jak už jsem se zmiňoval v předchozím postu, ANTLR je živý projekt, bouřlivě se vyvíjí a není vždycky možné izolovat MacroScope od jeho nekompatibilních změn, jakkoli by to bylo žádoucí. Pro překlad existujících zdrojáků není ANTLR nezbytný (generovaný kód a binární verze ANTLR runtimu jsou součástí distribuce), ale jakékoli změny gramatiky vyžadují jeho instalaci - na Windows není automatická, ale na druhé straně na aplikaci v Javě to není tak hrozné. Co se cílové platformy týče, MacroScope jsem zkoušel na XP a Vistě, které celkem žádné problémy nedělaly. Pro frontend k mnoha databázím Windows CE asi není až tak zajímavou platformou, ale viděl jsem projekt na PDA, ve kterém by se ANTLR uplatnil, konkrétně pro parsování konfigurace obsahující jakési vzorečky. Takové projekty by ovšem vyžadovaly otestování a možná i úpravy ANTLR runtimu pro .NET CF, a jeho rekompilace z nových zdrojáků by skoro určitě nefungovala s ANTLR 3.01, což je poslední release ANTLR. Zdrojáky pro C# bohužel nejsou jeho součástí - nějak se u nich zrovna měnil maintainer, a identifikovat použitelnou verzi v repozitáři by byla pěkná otrava - takže na drastické úpravy asi bude lepší počkat na ANTLR 3.1, jehož release se očekává každým dnem. Podle toho co jsem z nové verze viděl, určitě bude obsahovat mnoho zajímavých změn.

Published 18. ledna 2008 12:17 by vbarta

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
(optional)
(required) 
Submit
Powered by Community Server (Personal Edition), by Telligent Systems