Hm, also das scheint mir doch relativ komplex zu sein. Aber um vielleicht nochmal zur Praxis zurückzukommen... Wie könnte ich es denn Codetechnisch angehen?
Ich habe sicher nicht alles von dem verstanden, was Du geschrieben hast, habe auch diverse Google-Pages durchgelesen, aber auch hier im Forum kein wirkliches Codebeispiel finden können. Mir ist schon klar, dass ich nichts für mir sofort brauchbares finden kann, da es hier sicher noch keinen Scanner für CSS, so ich das denn richtig verstanden habe, gibt, aber wie wäre es denn mit einem kleinen Beispiel für Scanner, Grammatikfestlegung und Parser...?
So wie ich es verstanden habe, findet der Scanenr nur die Worte. Das wären, um bei meinem Beispiel zu bleiben folgende:
body, font-family,verdana,font,size,12px
/* Dann ein Kommentar zum üben */
.class, #id ,color, green, border, 1px, solid, gray,
Das wäre doch im Prinzip alles ausser , ; : (Komma, Semikolon und Doppelpunkt) Wie würde aber das mit der lexikalischen Analyse funktionieren oder wie wäre das mit den regulären Ausdrücken. Das sind alles so unklare Formulierungen. Ich bin da immer der Freund des praktischen Beispieles, weil da wohl meine Vorstellungskraft nicht ausreicht.
Im Prinzip habe ich es bisher wie folgt gemacht.
Delphi-Quellcode:
procedure ReadElemente;
var
Stringliste:TStringList;
Pos_A,Pos_E:integer;
Element,Inhalt:
String;
begin
ParserError:=False;
//erstmal alles leeren
myClass.Clear;
myHTML.Clear;
myIndi.Clear;
//der inahlt dieser stringlisten wir in einen Treeview geschrieben,
//wo man dann zugeordnet sehen kann, welche klassen, id´s oder html-elemende man hat
myTClass.Clear;
myTHTML.Clear;
myTIndi.Clear;
Stringliste:=TStringList.Create;
Stringliste.AddStrings(MainForm.SynEdit1.Lines);
//holt inhalt vom synedit
if MainForm.SynEdit1.Lines.Count > 0
then
Inhalt:=ClearCommentarTStrings(Stringliste);
//löscht die kommentare
while length(Inhalt) > 0
do //zerkaut den inhalt bis keiner mehr da ist
begin
{und hier das abarbeiten des Codes}
Pos_A:= pos('
{',Inhalt);
//begin des formatierten elementes gefunden
if Pos_A = 0
then
begin
Inhalt := '
';
Stringliste.Free;
ParserError:=True;
exit;
end;
Pos_E:= pos('
}',Inhalt);
//ende des formatierten elementes gefunden
if Pos_E > 0
then
begin
//ermittelt den elementnamen
Element:=Trim(midstr(Inhalt,0,Pos_A-1));
//ShowMessage(Element);
//ermittelt den elementtyp
//hier klasse
if (leftstr(Element,1) = '
.')
or (pos('
.',Element) > 1)
then
begin
myClass.Add(Element);
end
//hier ID
else if (leftstr(Element,1) = '
#')
or (pos('
#',Element) > 1)
then
begin
myIndi.Add(Element);
end
else
begin
//ansonsten HTML-Element
myHTML.Add(Element);
end;
//löscht das element mit allen angaben aus der liste
Delete(Inhalt,1,Pos_E);
Stringliste.Text:=Inhalt;
end
else
begin
ParserError:=True;
//setzt globalen bool
exit;
end;
end;
Stringliste.Free;
end;
Leider ist diese Routine nicht so perfekt, hier fehlt auch noch diverses Zeugs, was zeigt, wie es weitergeht mit dem Code. Eines meiner Hauptprobleme ist, dass parsen während der Codeeingabe. Da geht mir immer wieder der Fokus von der SynEdit verloren, so dass man mitten im Schreiben einfach nicht weiter arbeiten kann.