AGB  ·  Datenschutz  ·  Impressum  







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

erste Schritte zum Parser

Ein Thema von Antigo · begonnen am 3. Dez 2006 · letzter Beitrag vom 4. Dez 2006
Antwort Antwort
Antigo

Registriert seit: 14. Mär 2005
274 Beiträge
 
#1

erste Schritte zum Parser

  Alt 3. Dez 2006, 21:41
Hi,
bin heute auf einen Thread gestoßen wo jemand fragte wie man eine Rechnung in einem String berechnen kann. (Also '2+3/4' bspw). DIe Antwort war ein Mathe Parser und da ich etwas freizeit hatte hab ich mal angefangen einen zu entwickeln (ich weiss das es schon viele gibt, aber das hat denk ich mal noch keinen aufgehalten ).

Ich hab einfach mal angefangen simple Rechnungen zu lösen, erstmal ohne Klammern. Rausgekommen ist folgendes:

Delphi-Quellcode:
//Rechnungen ohne Klammern lösen
function TForm1.simplecalc(s:string):double;
var i:integer;
foo1,foo2:double;
temp:string;
ps:TPositionen;
begin
  temp:=s;

  //Punkt vor Strichrechnung
  calcpos(temp,ps); //Positionen der Operatoren festellen
  i:=0;
  while (i < length(ps)) and
  ((pos('*',temp)>0) or (pos('/',temp)>0)) do begin
    if (temp[ps[i]]='*') or (temp[ps[i]]='/') then begin
      //erster Faktor
      if i=0 then foo1:=strtofloat(copy(temp,1,ps[i]-1))
      else foo1:=strtofloat(copy(temp,ps[i-1]+1,ps[i]-ps[i-1]-1));
      //zweiter
      if i=length(ps)-1 then foo2:=strtofloat(copy(temp,ps[i]+1,length(temp)))
      else foo2:=strtofloat(copy(temp,ps[i]+1,ps[i+1]-ps[i]-1));

      //ergebnis
      if (temp[ps[i]]='*') then
      foo1:=foo1*foo2
      else foo1:=foo1/foo2;

      //an passender Stelle in den String einsetzen
      if i=0 then temp:=floattostr(foo1)+copy(temp,ps[i+1],length(temp))
      else if i=length(ps)-1 then temp:=copy(temp,1,ps[i-1])+floattostr(foo1)
      else temp:=copy(temp,1,ps[i-1])+floattostr(foo1)+copy(temp,ps[i+1],length(temp));

      showmessage(temp);
      
      calcpos(temp,ps);
     end;
     inc(i);
  end;

  //Additionen / Subtraktionen
  foo1:=strtofloat(copy(temp,1,ps[0]-1));
  for i:=0 to length(ps)-1 do begin
    if i=length(ps)-1 then
      foo2:=strtofloat(copy(temp,ps[i]+1,length(temp)))
        else foo2:=strtofloat(copy(temp,ps[i]+1,ps[i+1]-ps[i]-1));
    if temp[ps[i]]='+then foo1:=foo1+foo2
    else foo1:=foo1-foo2;
  end;

  //Ergebnis (foo1) ausgeben
  showmessage(floattostr(foo1));

end;
das ganze funktioniert zumindest schonmal. Was ganz klar noch nicht funktioniert ist:
- Klammersetzung, aber das hab ich bereits geschrieben
- Negative Zahlen eingeben (Nach dem Motto 1+-3, aber das kann man noch relativ leicht abfangen indem man -- zu +; +- und -+ zu - und ++ zu + macht.

Ich würde mal gern eure Meinung zu meinem Ansatz hören. Ich denke mal es ist nicht der eleganteste, aber was hätte ich wie besser machen können? Ich würd mich über Feedback sehr freuen

edit: noch kurz zum algorithmus: ich gehe so vor, das ich in der Rechnung erst alle Produkte löse, so dass ich nachher nur noch additionen und subtraktion haben.
Aus 1*2+3*4+5*6 wir so erstmal 2+3*4+5*6 , dann 2+12+5*6 und dann 2+12+30 was dann im zweiten schritt zu 44 wird

mfg
Antigo
Michael
"How should I know if it works? That's what beta testers are for. I only coded it."
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#2

Re: erste Schritte zum Parser

  Alt 3. Dez 2006, 21:49
Ich denke einfach mal laut, dass die allermeisten Parser einen (Binär-)Baum verwenden, und es dafür sicher einen Grund gibt

Was die Klammern angeht: Die könntest du vielleicht rekursiv lösen: Einfach zuerst alle eingeklammerten Terme suchen, und diese dann (rekursiv) auswerten
  Mit Zitat antworten Zitat
Antigo

Registriert seit: 14. Mär 2005
274 Beiträge
 
#3

Re: erste Schritte zum Parser

  Alt 3. Dez 2006, 21:56
ich hab leider keine ahnung wie ich so einen Binärbaum umsetzen soll. IM Prinzip wird da aber doch auch nciht viel anders gemacht als ich es tue.

Und das mit den Klammern wollte ich auch ungefähr so lösen. Also bis zur untersten "KLammerebene" gehen, wo also nur noch addition/subtraktion/multiplikation/division zu machen ist, und das ergebnis davon dann halt rückwikend einsetzen. Dafür würde sich eine rekusrive Prozedur natürlich anbieten. Wie ich das dann konkret umsetz muss ich noch schauen, ich finde es immer schwer rekursiv zu denken/zu programmieren, auch wenn das Ergebnis dann meist genial einfach ist...
Michael
"How should I know if it works? That's what beta testers are for. I only coded it."
  Mit Zitat antworten Zitat
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: erste Schritte zum Parser

  Alt 3. Dez 2006, 22:09
Wird dein Ansatz auch mit Klammern auskommen? Ich denke nicht.

So ein Parser richtig zu implementieren ist gar nicht mal so einfach. Schwer ist es allerdings auch nicht, wenn man weiss, wie man es richtig machen muss.

Dazu musst du wissen, das ein Parser eine 'Sprache' erkennt und syntaktisch analysiert. In Deinem Fall heißt die Sprache "Terme" oder "mathematische Ausdrücke".

Jede Sprache besteht aus Wörtern, oder Dingern, oder wie auch immer man das nennt. Auf Englisch heißen die Dinger "Token". Bei den mathematischen Ausdrücken sind die Token (oder eben Wörter): ( ) + - / * Zahl.

So, der Parser... was hab ich gesagt? ... genauer gesagt erkennt der Parser einen Satz einer Sprache. Und jeder Satz benötigt ein Satzende. Also definieren wir noch ein extra Wort "Ende des mathematischen Ausdruckes" oder einfach nur '$'.

Jetzt haben wir die Wörter, fehlt noch die Sprache. Damit man die einfach und formal korrekt definieren kann, haben sich Informatiker eine Notation ausgedacht, die BNF oder "Backus-Naur-Form".

Wenn Du eine Sprache in EBNF (steht im Wiki-Artikel) beschreiben kannst, dann bekommst Du vermutlich auch sehr einfach einen super funktionierenden Parser hin. Kurz erweitert hast du dann auch den Syntax-Baum.
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#5

Re: erste Schritte zum Parser

  Alt 3. Dez 2006, 22:16
Ein schöner Einstieg in die faszinierende Welt des Compilerbaus ist die Artikelreihe Let's Build a Compiler von Jack Crenshaw.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Antigo

Registriert seit: 14. Mär 2005
274 Beiträge
 
#6

Re: erste Schritte zum Parser

  Alt 3. Dez 2006, 22:17
hmm naja ich denke schon das mein Ansatz auch irgendwie mit Klammern auskommen wird, aber die Betonung liegt auf irgendwie. Besondern elegant würde das wohl nicht werden

Den Syntax Baum verstehe ich grundsätzlich, aber nicht wie ich damit arbeite. Im Prinzip ist das ja nur eine Darstellungsart von dem was ich machen will.

Naja ich werd dann wohl erstmal die letzten 2 Klausuren diese Woche hinter mich bringen und mir das ganze dann nochmal näher anschauen. Das Projekt Parser Bau scheint nichts für mal eben zwischendurch zu sein

danke auf jedenf all schonmal für die hinweise.

edit:
Let's Build a Compiler scheint interessant zu sein. Aber auch nix für mal eben grade ^^ Ich werd mir das aber wenn die Klausuren vorrüber sind mal zu gemüte führen. Vielen Dank für den Tipp
Michael
"How should I know if it works? That's what beta testers are for. I only coded it."
  Mit Zitat antworten Zitat
Antigo

Registriert seit: 14. Mär 2005
274 Beiträge
 
#7

Re: erste Schritte zum Parser

  Alt 4. Dez 2006, 14:54
ich muss leider sagen, dass ich mit dem Tutorial nicht so wirklich zurecht komme. Das es auf englisch ist, ist ja noch ok, aber das assembler zeug verwirrt mich irgendwie. Ausserdem muss man nach guter alter Pascal Manier beim lesen des Codes ständig hin und her springen, da die Prozeduren chronoligsch angeordnet sien müssen...

Kennt jemand eine andere gute EInführung? SOnst muss ich mir doch weiter selber den kopf zerbrechen...
Michael
"How should I know if it works? That's what beta testers are for. I only coded it."
  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 00:01 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