AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte GenPar - Ein [ziemlich] generischer Parser
Thema durchsuchen
Ansicht
Themen-Optionen

GenPar - Ein [ziemlich] generischer Parser

Ein Thema von Khabarakh · begonnen am 28. Mär 2006 · letzter Beitrag vom 12. Aug 2006
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von Khabarakh
Khabarakh
Registriert seit: 18. Aug 2004
(Für alle ohne Framework (und natürlich auch alle anderen) gibt es hier eine Testseite)
GenPar

Assembly: GenPar.dll
Root-Namespace: Kha.GenPar
.NET-Version: 2.0.50727
Größe: 40,0 KB
Signed

Code:
cos(e * 12) / (2 * (e * 6,28 + 1))
Ein mathematischer Ausdruck, wie wir ihn lieben (oder auch nicht) und wie er von tausenden Parsern auf der ganzen Welt zerlegt werden kann. Ergo: Langweilig
Code:
(!Hugo xor pi > e ? cos(e * 12) / (2 * (e * 6,28 + 1)) : log(a; 3)) ^ 3 * 21 / 32
(Default-Expression der Testseite)
Hui, langsam wird es schon etwas außer- und ungewöhnlicher. Aber generisch ist daran noch nichts, das wird es erst beispielsweise mit so etwas:
Code:
using System;
using System.Collections.Generic;
using System.Text;
using Kha.GenPar; // enthält allgemeine Typen wie Variablen oder Basisklassen
using Kha.GenPar.Infix; // enthält den Infixparser und Zugehöriges
using System.Reflection;

namespace ConsoleApplication1
{
   class Program
   {
      interface IGreatForum { } // Ein Forum ist einfach toll, das braucht keine Methoden ;)
      class DP : Object, IGreatForum { } // s.o ^^

      // Fangen wir gleich mal mit dem Ergebnis an, sonst wird es langweilig ;)
      static void Main(string[] args)
      {
         InfixParser parser = new InfixParser();
         // sucht in der angegebenen Klasse nach Parsertypen
         // (= Methoden mit Ableitungen von ParserAttribute)
         parser.RegisteredTypes.IncludeTypes(typeof(Program));
         // und noch eine Variable
         parser.RegisteredTypes.Variables.Add(new Variable(typeof(IGreatForum), "great"));

         parser.Parse("DP is great");
         Console.WriteLine(parser.Root.Evaluate());
         Console.ReadLine();
      }
      // Das Ergebnis versteht sich wohl von selbst :P

      // Und nun die Interna:

      // enthält alle in der Assembly definierten Typen
      static List<Type> classList = new List<Type>(Assembly.GetCallingAssembly().GetTypes());

      // Definieren wir mal schnell ein Literal...
      // God bless attributes
      //
      // Parst einen Typenbezeichner im String und gibt ein Type-Objekt zurück
      [SimpleLiteral()]
      public static Type ToType(string s, out int length, out bool succeeded)
      {
         foreach (Type t in classList)
            if (s.StartsWith(t.Name)) {
               length = t.Name.Length;
               succeeded = true;
               return t;
            }
         length = 42; // total egal, da succeeded eh false ist
         succeeded = false;
         return null;
      }

      // Und noch einen Operator
      // Meine Einstellung zu Attributen habe ich ja schon kundgegeben
      // 110 = Operatorvorrang (bei einem einzigen Operator ziemlich egal
      // \a = Argument
      [InfixOperator(110, @"\a is \a")]
      public static bool Is(Type t1, Type t2)
      {
         return t2.IsAssignableFrom(t1);
      }
   }
}
Hmm. Wir haben sozusagen einen komplett neuen Parser geschrieben, und das mit genau 64 Zeilen, von denen die meisten aus Kommentaren bestehen. Nicht schlecht, würde ich mit wenigstens einem kleinem Bisschen Eigenlob sagen .

Zum Sourcecode: Da ich eigentlich nur OS-Projekte schreibe und die Assembly sowieso unter der GPL steht, ich gleichzeitig aber die erste verwendbare Version sofort ins Netz stellen wollte, ist der Sourcecode an manchen Stellen noch etwas - nun ja - "inoptimal" . Zur Lektüre würde ich also lieber auf eine der nächsten Versionen warten, morgen werde ich mal FxCop drüberlaufen lassen. Wie gesagt, er läuft, aber in den nächsten Versionen wird das Ganze noch einmal um Einiges generischer werden (-> Plugins). Es sei mir verziehen, wenn man Stellen durch C# oder das Framework eigentlich viel eleganter hätte schreiben können, ich sharpe (^^) (leider) erst seit einem halben Jahr. Achja, irgendwelche Form von Doku lässt auch noch bis zur nächsten Version auf sich warten .

TODO (nicht vollständig, einfach alles, was mir im Moment einfällt):

- Vektoren
- Komplexe Zahlen
- Ein UPN-Parser
- Ein Operator-Browser
- generische Variablen/Konstanten
- Ein Precompiler (konstante Teile des Ausdrucks)
- Optimierungen
- IL-Compiler (Reflection = schnarch)

(Wahrscheinlich wieder die Hälfte vergessen -.-)

GenPar.zip
Moderator in der EE
 
Benutzerbild von arbu man
arbu man

 
Delphi 7 Professional
 
#11
  Alt 12. Aug 2006, 16:46
Wirklich ein cooler Parser wenn ich das richtig verstanden habe kann der mit complexen zahlen rechnen oder ?

Gibt es eine möglich keit den Parser in Win32 zu nutzen ?
Björn
  Mit Zitat antworten Zitat
Benutzerbild von faux
faux

 
Turbo Delphi für Win32
 
#12
  Alt 12. Aug 2006, 17:01
Zitat von arbu man:
Gibt es eine möglich keit den Parser in Win32 zu nutzen ?
Ich tippe mal auf nein; außer du übersetzt ihn.
.NET ist normalerweise nicht Win32 portabel.

Grüße
Faux
Faux Manuel
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh
 
#13
  Alt 12. Aug 2006, 17:08
Zitat von arbu man:
Wirklich ein cooler Parser wenn ich das richtig verstanden habe kann der mit complexen zahlen rechnen oder ?
Selbst wenn er es nicht könnte, könntest du es ihm in 5 Minuten beibringen .

Zitat:
Gibt es eine möglich keit den Parser in Win32 zu nutzen ?
Gäbe es, aber mit der Generizität ist dann weitgehend Schluss. Du könntest beispielsweise (in einer .Net-Sprache) einen Wrapper zum Parsen von komplexen Zahlen schreiben und diesen dann als COM-Klasse registrieren.

[add=Roter, nichtexistenter Kasten]
Zitat von faux:
Ich tippe mal auf nein; außer du übersetzt ihn.
Selbst wenn man nur einen kleinen Teil der generischen Features übersetzen würde, wäre das Ergebnis wohl nicht sehr brauchbar, aber ziemlich hässlich .
[/add]
Sebastian
  Mit Zitat antworten Zitat
Benutzerbild von faux
faux

 
Turbo Delphi für Win32
 
#14
  Alt 12. Aug 2006, 17:20
Zitat von Khabarakh:
Selbst wenn man nur einen kleinen Teil der generischen Features übersetzen würde, wäre das Ergebnis wohl nicht sehr brauchbar, aber ziemlich hässlich .

Aber ich dachte, das ist für .NET 1.1 geschrieben.
Zitat von Khabarakh:
Version 1.1.2298.22751 ^^
Grüße
Faux
Faux Manuel
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh
 
#15
  Alt 12. Aug 2006, 21:27
Das ist doch nur die Assemblyversion. Wobei ein Umbau für 1.1 kein allzu großes Problem wäre, jedenfalls nichts im Vergleich zu 2.0 -> Win32 . Generics werden nur zur Erleichterung benutzt, noch nicht beim Parsen.

[add]Jetzt verstehe ich erst, wie du zu der Aussage
Zitat von faux:
Aber ich dachte, das ist für .NET 1.1 geschrieben.
kommst. Mit generischen Features meinte ich keine generischen Klassen, sondern eben das generische Konzept des Parsers. Und an diesem Punkt wird man schon wegen einer fehlenden Basisklasse aller Typen unter Win32 verzweifeln.
[/add]
Sebastian
  Mit Zitat antworten Zitat
Benutzerbild von faux
faux

 
Turbo Delphi für Win32
 
#16
  Alt 12. Aug 2006, 23:50
Zitat von Khabarakh:
Mit generischen Features meinte ich keine generischen Klassen, sondern eben das generische Konzept des Parsers.

Jetzt verstehe ich...

Grüße
Faux
Faux Manuel
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz