AGB  ·  Datenschutz  ·  Impressum  







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

[Tipps gesucht] Parser erstellen

Ein Thema von Dragon27 · begonnen am 7. Feb 2007 · letzter Beitrag vom 7. Feb 2007
Antwort Antwort
Dragon27

Registriert seit: 20. Nov 2003
Ort: Aßling
543 Beiträge
 
Delphi XE6 Enterprise
 
#1

[Tipps gesucht] Parser erstellen

  Alt 7. Feb 2007, 17:13
Hallo,

ich würde gerne einen Parser selbst bauen. Das ganze soll Befehle verstehen und interpretieren. Auch eine Variablenverwaltung soll das Ding haben.
Nun hänge ich an mehreren Stellen, da ich das ganze von Anfang an gut aufziehen will.

Folgende Fragen:

- Wie würdet Ihr das mit einer Variablendeklaration machen und mit dem Auslesen? Mein Code:
Delphi-Quellcode:
unit varverwaltung;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Menus;


  type TVariablen=record
  Name:string;
  Inhalt:Variant;
  Script:String;

  end;



  //dek
  procedure Reset_Var();
  Function Get_Free_Var():integer;
  Procedure Set_Var(Name,Inhalt,Script:String);
  procedure Set_Systemvar();
  procedure Var_out_by_name(VName:String);


  var
  Variablen: array[0..999999] of TVariablen;

implementation

uses unit2, Fehler;




procedure Var_out_by_name(VName:String);
var i:integer;
ok:Boolean;
begin
ok:=false;
for i:=0 to 999999 do begin
if Variablen[i].name=Vname then begin
mainf.addL('Wert von '+Vname+' = '+Variablen[i].Inhalt+ ' > '+Variablen[i].Script);
ok:=true
end;
end;

if ok=false then mainf.addL('Keine Variable vorhanden');

end;

procedure Set_Systemvar();
begin
Set_Var('$uptime',datetimetostr(now),'system');
mainf.addl('Systemvariablen intialisiert..');
end;

procedure Reset_Var();
var i:integer;
begin
for i:=0 to 999999 do begin
Variablen[i].Name:='';
Variablen[i].Inhalt:='';
Variablen[i].Script:='';
end;
mainf.addl('Variablenspeicher geleert..');
end;

Function Get_Free_Var():integer;
var i:integer;
ok:Boolean;
begin
ok:=false;
for i:=0 to 999999 do begin
if (Variablen[i].Name='') and (Variablen[i].inhalt='') and (Variablen[i].script='')then begin
result:=i;
ok:=true;
break;
end;
end;
if ok=false then Messagedlg('Der Variablenspeicher ist voll!',mterror,[mbok],0);
end;

Procedure Set_Var(Name,Inhalt,Script:String);
var v:integer;
i:integer;
vorhanden:Boolean;
begin
vorhanden:=false;
for i:=0 to 999999 do begin
if variablen[i].name=Name then begin
Variablen[i].name:=name;
Variablen[i].Inhalt:=inhalt;
Variablen[i].Script:=script;
vorhanden:=true;
end;
end;
if vorhanden=false then begin
v:=Get_Free_Var();
Variablen[v].name:=name;
Variablen[v].Inhalt:=inhalt;
Variablen[v].Script:=script;
end;
end;

Procedure Del_Var(Name:string);
var i:integer;
begin
for i:=0 to 999999 do begin
if (Variablen[i].name=name) then begin
Variablen[i].Name:='';
Variablen[i].Inhalt:='';
Variablen[i].Script:='';
end;
end;
end;


end.
- Mit einer Befehlsverwaltung habe ich mich noch gar nicht beschäftigt aber vielleicht weiß hier auch jemand was?
- Weitere Gedanken und Tipps würden mich sehr freuen!!


Gruß

Dragon27
Delphi is ......... DELPHI!!
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: [Tipps gesucht] Parser erstellen

  Alt 7. Feb 2007, 17:58
Hi,
ehrlich gesagt wäre bei dem was Du vorhast mein erster Tipp an Dich, das Programmieren noch weiter nach hinten zu schieben. Deinem Code fehlt schon jegliche Einrückung (such mal nach dem Begriff Codestil). Das wird sich bei einem Vorhaben der Größe "Parser-bauen" doch deutlich bemerkbar machen (nicht positiv).

Genauso wichtig ist es sich gut mit der Planung auseinander zu setzen. Jeder Fehler, den Du in der Planungsphase machst, wirkt sich irgendwann aus. Je später das der Fall ist, desto mehr Dinge sind von einer Änderung betroffen (das kann viel Zeit und Nerven kosten).

An sich solltest Du Dir vielleicht erstmal anschauen, wie ein Compiler normalerweise aufgebaut ist (geht ein wenig weiter als ein reiner Parser, aber mehr Wissen schadet hier schon nicht). An sich arbeitet man immer in mehreren Stufen, mit mehreren Komponenten.
An erster Stelle kommt hier i.d.R. die Zerlegung in Token. Aus diesen setzt Du dann einen Syntaxbaum zusammen, der es Dir dann auch schon mal ermöglicht, dass Du Syntaktische Fehler entdeckst.
Danach kannst Du Dich dann auf die Suche nach semantischen Fehlern machen. Eventuell würdest hier vorher noch einen Desuggarer einsetzen, der alle verwendeten Elemente erst in eine einfachere Normalform bringt.

Erst danach solltest Du mit dem echten Parsen anfangen. Was die Variablen angeht, so solltest Du Dir eine schönere Zuordnung überlegen. Vorallem aber ist eine statische Struktur hier völlig ungeeignet. Du reservierst eine Menge Speicher 1.000.000 * sizeOf(TVariablen), wobei ein guter Teil davon wohl ungenutzt bleiben dürfte. Ganz schlecht ist es dann auch jedes mal über 1.000.000 Werte zu iterieren, um eine Variable zu finden. Sehr viel geeigneter sind hier dyn. Strukturen (Listen/Bäume). Diese sind in ihrer Größe nicht beschränkt. TList wäre z.B. eine Möglichkeit, hier werden Zeiger in einem verwalteten Array abgespeichert. Dass sich hinter einer TList ein Array verbirgt ist für dich transparent, Delphi passt die Größe dyn. an den Bedarf an.
Noch geeigneter dürfte aber TStringList sein. Eine TStringlist ist in erster Linie eine einfache Liste von Strings. Man kann allerdings jedem String eine Objekt-Referenz assoziativ zuweisen. Diese Referenz steht immer an der gleichen Stelle, wie der String, dem sie zugeordnet wurde. Zu jedem String lässt sich dann die Position in der Liste und damit auch die Referenz ermitteln. Damit kannst Du also sehr einfach über den Namen direkt auf eine assozierte Variable zugreifen.
Etwas schneller geht das ganze dann mit der THashedStringList oder einem Dictionary (alzaimar hat mal eins gepostet), die beide mit einem Hash arbeiten und die Position eines Strings darüber schneller ermitteln können.

Ansonsten lohnt es sich für Dich vielleicht auch gleich dir den Aufbau und die Verwaltung eines Heaps anzuschauen.

Wie man es an sich so richtig richtig macht siehst Du allerdings am Besten, wenn Du hier fertige funktionierende Parser anschaust. Da gibt es ja auch im OpenSource bereich einige, allerdings dürfte deren Komplexität teilweise schon recht hoch sein. Nach Erklärungen zu suchen lohnt sich aber immer!

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Antwort Antwort


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 17:36 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