Autor Beitrag
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 28.03.06 22:23 
Dann will ich mich auch mal an diesem wirklich netten Forum beteiligen :wink2: .


(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

ausblenden Quelltext
1:
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 :zwinker:
ausblenden Quelltext
1:
(!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:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
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 CSharpForum : 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("CSharpForum 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 :angel: .

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


Zuletzt bearbeitet von Kha am Mi 29.03.06 16:26, insgesamt 1-mal bearbeitet
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 28.03.06 22:56 
Hallo!

Ich kann das wohl erst morgen ausführlich testen, aber es sieht wirklich gut aus! :zustimm:

Für alle, die auch noch testen wollen: Mal einen Blick in den Ordner "Packages" werfen ;-)

Tschuldige, dass ich jetzt nicht mehr schreibe, aber wie gesagt: getestet wird morgen :-)

Grüße
Christian

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Kha Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 18.04.06 19:08 
@Christian: Lass dir Zeit ;) .

Version 1.1.2298.22751 ^^
  • Hab mal mit der Dokumentation angefangen, der Attributes-Ordner ist soweit fertig.
  • Alle Exceptions sind ab nun lokalisiert (deutsch + englisch).
  • MethodLiteral-Klasse: ziemlich ähnlich wie SimpleLiteralAttribute, aber weniger Reflection (in alle Standard-Packages eingebaut).
  • DefiningOperatorsAttribute-Klasse: Alle selbstdefinierten Operatoren ("operator XYZ") werden automatisch in den Parser übernommen.
  • Noch ein paar neue InfixOperatorAttribute-ctors
  • Komplexe Zahlen (Complex(Package)) und Vektoren (Vector2(Package), Vector3(Package))

Ein kleiner Bleistift zu den 3D-Vektoren:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
static void Main(string[] args)
{
  InfixParser parser = new InfixParser(new Vector3Package());
  parser.Parse("(1; 0; 0) x (0; 2; 0)");
  Console.WriteLine(parser.Root.Evaluate());
  Console.ReadLine();
}
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 18.04.06 19:12 
user profile iconKhabarakh hat folgendes geschrieben:
@Christian: Lass dir Zeit ;) .
:oops: Peinlich. Vielleicht denke ich heute abend dran ;-)

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Di 18.04.06 19:17 
Sieht genial aus :). Mich würde interessieren, wozu das hier gut is (was es macht is mir klar) ^^

ausblenden Delphi-Quelltext
1:
this.justReal = Math.Abs(imaginary) < epsilon;  //HACK?					


Außerdem: warum hast du dieses justReal-Feld überhaupt? Ginge das nicht einfacher über eine Methode - muss ja nicht gleich ein Attribut sein ;)? Und wieso hast du die Multiplikation und Division derart kompliziert gelöst? Das ginge viel einfacher/schneller mit Betrag und Phase. Falls du noch mehr Funktionen brauchst (e^, log, sinh etc.) meld dich einfach mal per PN ;)

AXMD


Zuletzt bearbeitet von AXMD am Di 18.04.06 19:23, insgesamt 1-mal bearbeitet
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Di 18.04.06 19:20 
Sieht für mich so aus, als würde einem das sagen, ob die Zahl rein reell ist. Also der Im.teil = 0 (im Rahmen der Genauigkeit Epsilon).

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: Di 18.04.06 19:27 
user profile iconChristian S. hat folgendes geschrieben:
Sieht für mich so aus, als würde einem das sagen, ob die Zahl rein reell ist. Also der Im.teil = 0 (im Rahmen der Genauigkeit Epsilon).


Ist klar, nur das würde doch viel besser in eine Methode passen - find ich zumindest ;). Aber gut, die Dikussion ist hier an der falschen Stelle ;)

AXMD
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 18.04.06 19:44 
Kann es sein, dass die Testseite nicht funktioniert?

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Kha Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 18.04.06 19:53 
user profile iconAXMD hat folgendes geschrieben:
Sieht genial aus :).

Danke :D .
user profile iconAXMD hat folgendes geschrieben:
Mich würde interessieren, wozu das hier gut is (was es macht is mir klar) ^^

ausblenden Delphi-Quelltext
1:
this.justReal = Math.Abs(imaginary) < epsilon;  //HACK?					

Epsilon habe ich eingefügt, damit wenigstens i^2 = -1 ist ;) . Und eine Methode wäre spätestens damit viel zu kostspielig gewesen.
user profile iconAXMD hat folgendes geschrieben:
Außerdem: warum hast du dieses justReal-Feld überhaupt? Ginge das nicht einfacher über eine Methode - muss ja nicht gleich ein Attribut sein ;)? Und wieso hast du die Multiplikation und Division derart kompliziert gelöst? Das ginge viel einfacher/schneller mit Betrag und Phase. Falls du noch mehr Funktionen brauchst (e^, log, sinh etc.) meld dich einfach mal per PN ;)
So hab ich es eben gelernt ;) . Schneller wäre es durch die Umrechnung zwischen den zwei Systemen wahrscheinlich nicht, aber ich könnte testweise mal eine Klasse, die mit den Polarkoordinaten rechnet, einbauen.
Robert_G
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 416


Delphi32 (D2005 PE); Chrome/C# (VS2003 E/A, VS2005)
BeitragVerfasst: Di 18.04.06 19:55 
user profile iconBenBE hat folgendes geschrieben:
Kann es sein, dass die Testseite nicht funktioniert?
Hast wahrscheinlich das gleiche Problem wie ich: englisches Windows. ;)
Wenn du im Browser die Sprache auf deutsch stellst gates...

ASPX verwendet die Localsettings des Browser um die UI-Culture des serverseitigen Threads festzulegen. Klaradings' Beispielformel enthält zum Bleistift , als Dezimaltrenner. Ein double.Parse dürfte dann wohl schiefgehen. ;)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 18.04.06 20:13 
Ne, englischen FF mit de als Preferred Setting ;-)

Jetzt ging's aber plötzlich ...

Aber Shakespeare mag der Parser trotzdem nicht:

Std + Int-Package
(2*b) or not (2*b)
Wird mit nem Lex-Fehler quittiert, nehm ich das Bool-Package rein, gibt's nen Parser-Fehler.
Mein Delphi sagt mir korrekt -1 (oder 2^32-1 bei Unsigned).

Verbessert werden sollt, dass er die genaue Stelle des Fehlers markiert.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Kha Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 18.04.06 21:18 
user profile iconBenBE hat folgendes geschrieben:
ausblenden Quelltext
1:
(2*b) or not (2*b)					
Bitweise Operatoren fand ich für einen in erster Linie mathematischen Parser unnötig. Aber ist natürlich kein Probelm, sie für die nächste Version einzufügen, damit er auch der Werke des Herrn Schüttelspeer mächtig ist ;) .


Die Lokalisierungsprobleme sind jetzt (hoffentlich) gelöst, der Beispielterm wird automatisch angepasst.
Zitat:
Verbessert werden sollt, dass er die genaue Stelle des Fehlers markiert.

Ist leider nicht annähernd so leicht wie bei einem statischen Parser :? . Wird aber auf jeden Fall noch kommen :) .