AGB  ·  Datenschutz  ·  Impressum  







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

JVRichEdit parsen - Hilfe?!

Ein Thema von Yheeky · begonnen am 3. Okt 2006 · letzter Beitrag vom 3. Okt 2006
Antwort Antwort
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#1

JVRichEdit parsen - Hilfe?!

  Alt 3. Okt 2006, 18:09
Hi,

ich möchte in meinem Programm die JVRichEdit Komponente verwenden, da ich gerne Bitmaps in mein RichEdit einbauen möchte. Ich habe mit dem "Messenger-Beispiel" von den JV-Beispielen gearbeitet und die Bitmapanzeige geht auch schon soweit. Die Eingabe des Textes erfolgt auch über ein JVRichEdit. Dies sieht z.B. wiefolgt aus:
Zitat:
Hallo! Das ist ein Test
Was nun noch per Hand gemacht werden muss, ist der Parser. Ich muss den oben dargestellten String durchgehen und schauen, ob ein Smiley bzw. ein eigenes Schlüsselwort enthalten ist...und hier liegt das Problem:

Das Messenger Beispiel hat wohl schon vorgefertigte Smileys, aber irgendwie blicke ich nicht so wirklich durch den Code. Ich weiss nicht wie ich eigene Definitionen einbauen kann.

Hier erstmal der komplette Code, unten drunter eine genauere Erklärung, was ich nicht verstehe:

Code:
procedure TfrmNachricht.ParseString(const S: string);
var
  P, Q: PChar;
  State: Integer;

  procedure AddImage(const SmileIndex, SmileLength: Integer);
  begin
    AddTextToRichEdit(Q, P - Q - SmileLength + 1, JVRichEdit2.Font);
    AddImageToRichEdit(SmileIndex);

    State := 0;
    Q := P + 1;
  end;
begin
  P := PChar(S);
  Q := P;

  State := 0;

  // State = 1.. then looking at ":-A" with A = @x)( etc.
  //         10..                 "LOL"
  //         20..                 "O :-)"
  //         30..                 "(blush)"
  //         40..                 ":'-("
  //         50..                 "8-)"
  //         60..                 ";-)"
  //         70..                 "readonly"
  //         80..                 "read-only on" or "read-only off"
  //
  // State = 1 -> ":" read
  // State = 2 -> ":-" read
  // State = 11 -> "LO" read
  // State = 22 -> "O :" read
  // State = 23 -> "O :-" read
  //
  // etc.

  while P^ <> #0 do
  begin
    case P^ of
      '$':
        if State in [2, 23] then
          AddImage(9, 3) // :-$
        else
          State := 0;
      '&':
        if State in [2, 23] then
          AddImage(4, 3) // :-&
        else
          State := 0;
      '(':
        case State of
          1, 22: AddImage(5, 2); // :(
          2, 23: AddImage(5, 3); // :-(
          40: AddImage(2, 3); // :,(
          41: AddImage(2, 4); // :'-(
        else
          State := 30;
        end;
      ')':
        case State of
          1, 22: AddImage(11, 2); // :)
          2: AddImage(11, 3); // :-)
          23: AddImage(6, 5); // O :-)
          35: AddImage(3, 7); // (blush)
          51: AddImage(1, 3); // 8-)
          61: AddImage(15, 3); // ;-)
        else
          State := 0;
        end;
      '*':
        if State = 1 then
          AddImage(7, 2) // :*
        else
          State := 0;
      ',':
        if State in [1, 22] then
          State := 40
        else
          State := 0;
      '-':
        case State of
          1, 22, 40, 50, 60: Inc(State);
          73: State := 80;
        else
          State := 0;
        end;
      '8': State := 50;
      '"': State := -1; // to prevent "read.." etc will be triggered by the program
      ':':
        if State = 21 then
          State := 22
        else
          State := 1;
      ';': State := 60;
      '@':
        case State of
          1, 22: AddImage(0, 2); // :@
          2, 23: AddImage(0, 3) // :-@
        else
          State := 0;
        end;
      'D':
        case State of
          1, 22: AddImage(8, 2); // :D = LOL
          2, 23: AddImage(8, 3) // :-D = LOL
        else
          State := 0;
        end;
      'L':
        if State = 11 then
          AddImage(8, 3) // LOL
        else
          State := 10;
      'O':
        if State = 10 then
          State := 11
        else
          State := 20;
      '\', '/':
        if State in [2, 23] then
          AddImage(14, 3) // :-\
        else
          State := 0;
      'a':
        if State = 71 then
          State := 72
        else
          State := 0;
      'b':
        if State = 30 then
          State := 31
        else
          State := 0;
      'd':
        if State = 72 then
          State := 73
        else
          State := 0;
      'e':
        if State = 70 then
          State := 71
        else
          State := 0;
      'h':
        if State = 34 then
          State := 35
        else
          State := 0;
      'l':
        if State in [31, 75, 82] then
          Inc(State)
        else
          State := 0;
      'o':
        case State of
          2, 23: AddImage(12, 3); // :-o
          73, 80, 85: Inc(State);
        else
          State := 0;
        end;
      'p':
        if State in [2, 23] then
          AddImage(13, 3) // :-p
        else
          State := 0;
      'r':
        if State <> -1 then
          State := 70
        else
          State := 0;
      's':
        if State = 33 then
          State := 34
        else
          State := 0;
      'u':
        if State = 32 then
          State := 33
        else
          State := 0;
      'x', 'X':
        if State in [2, 23] then
          AddImage(10, 3) // :-x
        else
          State := 0;
      ' ':
        case State of
          20, 84: Inc(State);
          11: State := 21;
        else
          State := 0;
        end;
    end;
    Inc(P);
  end;

  if Q < P then
    AddTextToRichEdit(Q, P - Q, JVRichEdit2.Font);
end;
Nehmen wir mal den Anfang des Parsers - hier fängt das erste Problem an:

Code:
while P^ <> #0 do
  begin
    case P^ of
      '$':
        if State in [2, 23] then
          AddImage(9, 3) // :-$
        else
          State := 0;
while P^ <> #0 - ist wohl die Abfrage, ob der String leer ist oder nicht, richtig?
case P^ of normale Case-Bedingung, prüft auf die kommenden Zeichen
'$': Wenn das Zeichen $ im String vorkommt, dann...
if State in [2, 23] then Hier nun ein Problem: Warum State in [2, 23]? Was hat die 2 und die 23 damit zu tun?

Ich verstehe auch nicht die Kommentare in der Funktion oben. Gibt´s da keine extra Hilfe, in der die States erklärt werden? Außerdem wird doch der Integer-Wert State vor dem Aufruf des Zeigers 0 gesetzt...

Wie ihr seht: Fragen über Fragen...vielleicht versteht ja einer von euch den Code und könnte ihn mir etwas erklären?! Wäre super nett! Danke!
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: JVRichEdit parsen - Hilfe?!

  Alt 3. Okt 2006, 19:44
Hi Christian,

die Prozedur ParseString() implementiert einen Parser als Zustandsautomaten (Finite State Machine, FSM). Nach C-Manier wird der zu untersuchende String mit einem PChar-Zeiger (P) adressiert, der einfach per Zeigerarithmetik (Inc(P)) über den String geschoben werden kann. Da auf diese Weise immer nur ein Zeichen (P^) gesehen wird, die Grammatik aber die Zusammensetzung eines Smiley aus mehreren Zeichen erlaubt, muss sich der lexical analyser merken, welche Teil-Kombinationen er bisher erkannt hat (State). Auf diese Weise entfallen teure Stringvergleiche.

Hoffentlich habe ich mich einigermaßen verständlich ausdrücken können.

Grüße vom marabu
  Mit Zitat antworten Zitat
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#3

Re: JVRichEdit parsen - Hilfe?!

  Alt 3. Okt 2006, 20:03
Ja, bin inzwischen durchgestiegen...raffiniert diese Methode, aber richtig "sauber" ist sie doch nicht, oder?
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#4

Re: JVRichEdit parsen - Hilfe?!

  Alt 3. Okt 2006, 20:12
An der Methode ist nichts auszusetzen. Schwachstellen in der Umsetzung vermute ich, bin aber zu faul sie aufzuspüren.

Grüße, marabu
  Mit Zitat antworten Zitat
Yheeky

Registriert seit: 7. Jun 2002
1.339 Beiträge
 
#5

Re: JVRichEdit parsen - Hilfe?!

  Alt 3. Okt 2006, 20:38
Das bezog sich nicht auf die oben stehende Variante.
Trotzdem danke! Problem solved!
  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 03:50 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