Archive for July, 2008

IT Recht Ressourcen im Internet

Monday, July 28th, 2008

Hallo,

im IT Freelancer Heft 4/2008 wird auf zwei Webseiten mit Informationen zum Thema IT-Recht hingewiesen:

Arbeitsgemeinschaft Informationstechnologie im Deutschen Anwaltsverein (DAVIT)

Bayreuther Arbeitskreis für IT – Neue Medien – Recht (AKIT)

Nachdem derartige Ressourcen potentiell nützlich sind, habe ich einen Blick darauf geworden, leider mit enttäuschendem Ergebnis. Beider Websites scheinen primär den Interessen der Mitglieder zu dienen und bieten kaum brauchbare Informationen für Selbständige in der IT.

Um dies etwas zu objektivieren, habe ich den Begriff “Viren” in die jeweiligen Suchfelder eingegeben. Hier hätte ich z. B. Informationen erwartet, wann man bei der unbeabsichtigten Verbreitung von Viren – z.B. über emails – verantwortlich ist und eine rechtliche Relevanz entsteht.

Während die Suchmaschinen von DAVIT immerhin keine Treffer brachte, brachte die Suche bei AKIT völlig irrelevante Treffer die über eine phonetische Suche gefunden wurden. Dafür waren die bezahlten Anzeigen relevant, Google sei dank.

Viele Grüße,
Andreas

Anzeige von source code mit syntax highlighting in blog posts (wp-syntax)

Monday, July 28th, 2008

Hallo,

ich wollte schon länger ein plugin für mein blog installieren, mit dem ich source code besser darstellen kann. Ich habe jetzt wp-syntax installiert und bin recht zufrieden damit. Die Benutzung ist einfach und das Ergebnis ist ansprechend (Beispiel). Kleines goodie am Rande: das plugin setzt Sonderzeichen wie etwa < oder > automatisch in HTML entities um.

Ich musste eine Kleinigkeit im source code ändern:

include_once("geshi/geshi.php");

wird zu

include_once("absoluter Pfad zum plugin Verzeichnis/geshi/geshi.php");

Sonst wurde versucht die Datei unter /user/share/php zu laden.

Wer’s nutzt möge nicht vergessen, eine Kleinigkeit für den Autor zu spenden.

Viele Grüße,
Andreas

Technorati Tags: , ,

Erstellung von Parsern in C++ mit der boost::spirit library

Monday, July 21st, 2008

Hallo!

In der Softwareentwicklung steht man regelmäßig vor der Aufgabe, eine Eingabe nach gewissen Regeln zu verarbeiten. Dazu bedient man sich in einfachen Fällen regulärer Ausdrücke, die man in C++ z.B. mit der boost::regex library verarbeiten kann. Wenn die Struktur der Eingabe zu komplex ist, definiert man eine Grammatik und verwendet einen Parser Generator wie lex/yacc oder ANTLR (wobei man in diesem Fall vorsichtig sein muss. Für die aktuelle Version 3.0 ist zum Zeitpunkt der Veröffentlichung dieses postings immer noch kein brauchbares C++ target verfügbar).

Reguläre Ausdrücke sind allerdings schwer zu lesen und eignen sich schlecht für rekursive Strukturen.

Einen Parser Generator aufzusetzen und in ein C++-Projekt einzubinden ist wiederum etwas lästig. Insbesondere wenn man verschiedene Plattformen (etwa, Visual C++ und MinGW unter Windows und gcc unter Linux) unterstützt, wiederholt sich der Aufwand.

Mit der boost::spirit library gibt es noch einen Weg dazwischen, der genau diese Lücke füllt. Man kann mit richtigen Grammatiken arbeiten und braucht trotzdem kein externes tool einzubinden.

Da die Arbeit mit Spirit nicht ganz trivial ist, wollte ich meine Erfahrungen anhand eines kleinen Beispiels festhalten und weitergeben.

Die zu lösende Aufgabe bestand darin, einen String zu parsen, der einen “instantiierten Typ” – i.A. template oder generic genannt – verarbeitet und die verwendeten Typen als Liste zurückgibt. Dabei sollten die in den gängigen Programmiersprachen üblichen Regeln für identifier berücksichtigt werden und die Eingabe sollte wie sonst üblich formatfrei sein, d.h. white space sollte ignoriert werden.

Beispiele für gültige Eingaben wären dann:

Set(String)
Set(Bag(String))
Set ( String )
My_Container1(Integer)

Eine solche Aufgabe ist genau von der richtigen Komplexität für boost::spirit.

Falls sich jemand über die runden Klammern wundert (üblich sind spitze Klammern) – der Parser soll im Kontext der Object Constraint Language (OCL) verwendet werden und dort werden runde Klammern verwendet. Dies ist aber ein irrelevantes Detail.

Spirit ist auf möglichst flexible Verwendbarkeit ausgelegt, es gibt verschiedene alternative Verfahren und es werden intensiv “Policy-Klassen” in der Form von template-Parametern verwendet.
Dies macht die Verwendung nicht gerade leichter, da es sehr viele mögliche Kombinationen der Verfahren und Policies gibt. Deshalb soll dieses posting auch eine Art Kochbuch sein, dass typische Anforderungen abdeckt. Gängige Beispiele wie etwa hier verwenden “semantic actions”, die direkt beim match einer Regel ausgeführt werden. Dieses Vorgehen hat einen grossen Nachteil, der es für viele Fälle unbrauchbar macht: bei einer mehrdeutigen Grammatik, wie sie in der Praxis häufig vorkommen, versucht der Parser durch “probieren” eine zur Eingabe passende Regel zu finden. Falls dies nicht klappt wird der Versuch abgebrochen und nochmal von vorne begonnen (”backtracking“). Dummerweise werden semantic actions die mit einer Regel assoziiert sind bei jedem versuchten match aufgerufen. Es kann aber sein, dass diese Aufrufe gar nicht relevant sind, weil der Parser später erkennt dass die aktuelle Regel nicht matcht und ein backtracking vornimmt.

Spirit bietet die Möglichkeit einen “tree parser” zu verwenden, der dieses Problem nicht hat. Ein solcher tree parser liefert einen Syntax Baum der immer gleich aussieht und exakt der Eingabe entspricht, unabhängig davon wie oft ein backtracking auftrat. Davon abgesehen ist es generell eine gute Idee, die Grammatik von der semantischen Verarbeitung zu trennen, was mit einem tree parser implizit gegeben ist.
Zusammenfassend würde ich also bei der Verwendung von Spirit immer einen Tree Parser empfehlen.

Angesichts der schweren Zugänglichkeit von Spirit ist man für Beispiele immer dankbar, z.B. hier für die Verwendung eines tree parsers. Wenn man sich an diesem Beispiel anlehnt, wird man aber feststellen, dass der Parser white space nicht ignoriert, ein Verhalten dass im allgemeinen unerwünscht ist. Die Lösung besteht darin, die Zeile

typedef scanner_policies<iteration_policy, match_policy_t, action_policy> scanner_policy_t;

in

typedef scanner_policies<skip_parser_iteration_policy<space_parser>, match_policy_t, action_policy> scanner_policy_t;

zu ändern. Auch wenn man herausgefunden hat, dass der erste template Parameter, die “iteration policy”, für das ignorieren von white space zuständig ist, ist es noch ein weiter Weg bis man den korrekten Wert kennt den man für diese policy angeben muss.

Nachdem ich in diesem posting die wichtige Festlegung auf einen tree parser empfohlen habe und die Hürde des ungünstigen Beispiels eines parser der white space nicht ignoriert genommen habe, werde ich im nächsten posting den konkreten code und insbesondere die Definition der Grammatik zeigen.

Knifflig wird es dann wieder beim Auswerten des parse trees, was leider keine triviale Aufgabe ist.

Viele Grüße,
Andreas

Technorati Tags: , ,