AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Automaten in Source Code

Ein Thema von Christian18 · begonnen am 20. Nov 2009 · letzter Beitrag vom 1. Dez 2009
Antwort Antwort
Seite 7 von 7   « Erste     567   
Benutzerbild von JasonDX
JasonDX
(CodeLib-Manager)

Registriert seit: 5. Aug 2004
Ort: München
1.062 Beiträge
 
#61

Re: Automaten in Source Code

  Alt 22. Nov 2009, 21:23
Zitat von SebE:
Ja, wie man es OO löst wurde hier noch nicht gelöst
Was ist an meinem Code noch ungelöst? Die Entscheidung, welcher Pfad im Graph gewählt wird, wird vom jeweiligen Zustand getroffen. Der Automat selbst kennt nur den aktuellen Zustand, und greift auf dessen Methoden zurück, um den Zielzustand der korrekten Kante zu ermitteln.
Die Festlegung der Übergänge für einen bestimmten Zustand kann dabei vom Automaten selbst, oder aber auch von außen gesteuert werden - je nach belieben. Notwendig dafür sind weder Tabellen, noch unübersichtliche case-Strukturen. Was will man mehr?

greetz
Mike
Mike
Passion is no replacement for reason
  Mit Zitat antworten Zitat
SebE

Registriert seit: 31. Jul 2004
Ort: Chemnitz
316 Beiträge
 
Delphi 7 Personal
 
#62

Re: Automaten in Source Code

  Alt 22. Nov 2009, 21:28
Nein, ich hatte das nicht so gemeint.

Du hast doch mitbekommen, dass es hier eine philosophische Diskussion über die OO-Lösung gab (und DIE ist nocht nicht gelöst).

In meinen Augen, ist deine Lösung äquivalent zu meiner (wenn ich davon ausgehe, deinen Code richtig verstanden zu haben) (also der "Zustandsbaum"-Lösung, die den Graph KOMPLETT aufbaut)
Sebastian
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#63

Re: Automaten in Source Code

  Alt 22. Nov 2009, 21:31
Zitat von SebE:
Ich find (wenn es eren Ideen entspricht) beide nicht elegant.
Na dann erzähl doch mal, was dir an der ersten nicht gefällt (das Destroy übernimmt natürlich die ausführende Schleife). Es dürfte doch unbestreitbar sein, dass das die minimale, von der Logik her direkteste Variante ist: Jeder Zustand sagt, mit welchem es weiter gehen soll, fertig. Das ist KISS.
Wenn dir dabei unnötig viele Instanzen erzeugt werden, kann ich dich sogar verstehen. Eine bereits genannte Lösung wäre Singletons. Gäbe dann allerdings bei verarbeitenden Automaten und Multi-Threading Probleme. Also führe ich wie JasonDX einen Owner ein:
Delphi-Quellcode:
function TZustand1.GetNextState(const aToken : Char): TState;
begin
  case aToken of
  ...
  '0'..'9': begin
    ...
    Result := Owner.GetOrCreate(TZustand2);
    end;
  end;
end;
Der große Unterschied? Mein Owner hat keine Ahnung, welche Klassen er enthält, er ist effektiv ein TDictionary<TStateClass, TState>, ein dummer Cache. Und hält so meine beiden Regeln ein.

So, das war jetzt die simpelste Lösung, die ich mir vorstellen kann. JasonDX' Code ist mir ehrlich gesagt zu komplex, da nehme ich doch lieber wieder Tabellen in prozeduralem Code .

Zitat von SebE:
@GC:
Ich halte es nicht gerade für ein gutes Pattern, ihn zu verwenden
Gut, das ist deine Meinung und die werde ich dir nicht aussprechen. Es muss dir nur klar sein, dass in etwa gleiche viele Leute sie mit dir teilen wie deinen Code-Style.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#64

Re: Automaten in Source Code

  Alt 29. Nov 2009, 21:16
Zitat von Daniel G:
Ich kann mir nicht vorstellen, wie ich den Zustandsgraphen (der mir ja durchaus bewusst ist) komplett in OOP und als Tabelle implementiere.
Nach ein wenig Überlegen sage ich mal, wie ich persönlich es machen würde: Sicherlich nicht mit OOP .

Zuallererst würde ich die Sprache auf jeden Fall in EBNF fassen - schon allein, um eine prägnante, von der Implementierung unabhängige Definition zu haben. Jetzt kommt es drauf an: Wenn die Grammatik nicht zu komplex und vor allem LL(1) ist, geht meine Stimme an einen Recursive Descent Parser. Viel Theorie und Fachwörter, aber imho eigentlich eine der simpelsten und zugleich übersichtlichsten Methoden. Entspricht auch ziemlich genau dem OOP-Ansatz (der ohne Gott-Klasse ), aber ohne diesen ganzen Syntax-Overhead *schauder* .

Erstmal brauchen wir eine halbwegs taugliche Repräsentation des Inputs:
Delphi-Quellcode:
type TTokenStream = class
  public
    property Current : Char read;
    property Eof : Boolean read;
    procedure MoveNext;
    procedure Expect(aToken : Char); // MoveNext, falls Current = aToken, sonst Exception
end;
Eine Grammatik für deine Dateien könnte etwa so aussehen:
Code:
lines = line, [ newline, lines ] ;

line = comment | constant | entry ;

comment = "//", { symbol } ;

constant = identifier, "=", { symbol - ";" }, ";" ;

...
Diese werden dann in rekursive Funktionen umgeformt:

Delphi-Quellcode:
function TFile Lines(aStream : TTokenStream);
begin
  Result := TFile.Create;
  repeat
    if not Comment(aStream) then
    begin
      var constant := Constant(aStream);
      if Assigned(constant) then
         Result.AddConstant(constant)
       else
      begin
        var entry := Entry(aStream);
        Assert(Assigned(entry));
        Result.AddEntry(entry);
      end;
     end;
   
    if not aStream.Eof then
      Assert(Newline(aStream));
  until aStream.Eof;
end;

function Boolean Comment(aStream : TTokenStream);
begin
  Result := aStream.Current = '/';
  if Result then
  begin
   aStream.Expect('/');
    while not Newline(aStream) do;
  end;
end;

function TConstant Constant(aStream : TTokenStream);
begin
  var name : String := Identifier(aStream);
  if not Assigned(identifier) then
    Exit(nil);
   
  var constant := TConstant.Create;
  constant.Name := name;
  
  aStream.Expect('=');
  
  constant.Value := '';
  
  while aStream.Current <> ';do
  begin
    constant.Value += aStream.Current;
   aStream.MoveNext;
  end;
  
  aStream.Expect(';');
end;

.
.
.
Keine Ahnung, ob das jetzt nachvollziehbar war, das Ergebnis finde ich aber äußerst übersichtlich. Wie gesagt entspricht es der OOP-Variante: Jede Funktion ist unabhängig und kennt nur ihre Teilfunktionen, ein Aufruf der Startfunktion bringt alles ins Rollen.
Wir haben uns damit zwar etwas von Automaten wegbewegt, was ich aber wirklich nicht schade finde: BNF kann einfach viele winzige Zustände in eine zusammenhängende Regel fassen, bei der Umsetzung in rekursive Funktionen können es sogar noch weniger werden. Man rückt von einzelnen Zeichen ab und denkt in größeren Blöcken.

Was aber, wenn die Sprache doch etwas zu komplex ist? Dann gibt es imo keine Ausrede mehr, nicht gleich zu einem Parser-Generator zu greifen:
Zitat von http://en.wikipedia.org/wiki/Recursive_descent_parser:
Although predictive parsers are widely used, programmers often prefer to create LR or LALR parsers via parser generators without transforming the grammar into LL(k) form.
Spätestens, wenn eine ordentliche Fehlerausgabe gefordert ist, wird jede handgestrickte Lösung, öhm... lustig .
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von Mithrandir
Mithrandir
(CodeLib-Manager)

Registriert seit: 27. Nov 2008
Ort: Delmenhorst
2.379 Beiträge
 
#65

Re: Automaten in Source Code

  Alt 1. Dez 2009, 10:55


Danke, ich werde mir das die Tage mal zu Gemüte führen und dann sehen, ob ich die Klasse nicht entsprechend anpassen kann.
米斯蘭迪爾
"In einer Zeit universellen Betruges wird das Aussprechen der Wahrheit zu einem revolutionären Akt." -- 1984, George Orwell
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 7 von 7   « Erste     567   


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 21:59 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