AGB  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Parser: Operatoren

Ein Thema von blablab · begonnen am 13. Apr 2012 · letzter Beitrag vom 16. Apr 2012
Antwort Antwort
Seite 2 von 2     12
Medium

Registriert seit: 23. Jan 2008
3.310 Beiträge
 
Delphi 2007 Enterprise
 
#11

AW: Parser: Operatoren

  Alt 14. Apr 2012, 00:20
Ja, er sucht mittels Pos(), also aktiv. Zudem gibt mir mein FindToken() den ersten Operator zurück, der nicht in Klammern steht, jap. Wird kein OP ausserhalb von Klammern gefunden, fällt meine If-Then-Wurst in einen Zweig if (s[1] = '(') and (s[High(s)] = ')') then result := Parse(copy(s, 2, Length(s)-2)); durch.

Ich hab mit der Technik jetzt ziemlich alle trivialen Dinge abgedeckt: "Normale" Operatoren (^,*,/,+,-), Funktionen mit 1-3 Parametern (sin(), cos(), ...), logische Operatoren (and, or, not, ...) sowie das Vorzeichenminus, Klammerung und Operatorenrang wie in der Mathematik üblich, wobei ich logischen Operatoren noch Vorrang vor diesen gewähre. (Dort ist sogar der ternäre Operator in Form eines IfThen() dabei.)
Unäre Operatoren wären leicht umzusetzen, wenn diese Zeichen dann von Variablen- und Konstantenbezeichnern als Bestandteil ausgeschlossen würden - fände man einen solchen, wird alles bis zum nächsten Operator als Argument aufgefasst, oder via Klammerung eindeutig gemacht. Ähnlich ließe sich mit unären Postfix-Operatoren verfahren, nur eben in die andere Richtung.

Dass dieses Vorgehen nicht unbedingt einem reinen sprachtheoretischen Lexer entspricht stimmt, jedoch ist es schlank, übersichtlich, recht intuitiv und wartbar (auch nach 6-7 Jahren noch, ich hab nämlich die Boolschen OPs erst letzte Woche nachgerüstst, auf einem Stand, den ich zuletzt 2006 gesehen habe glaube ich). Schmankerl sind registrierbare Konstanten und Variablen, letztere als Pointer auf eine Delphi-Variable, so dass sie zur Laufzeit geändert werden können, ohne den String neu parsen zu müssen. Zudem werden alle konstanten Teile des Baumes vorab gelöst und als Konstanten-Blatt eingefügt, so dass diese in dem Fall auch nicht immer wieder erneut aufgelöst werden müssen. Ergo: Das Teil ist sogar richtig flott, gerade bei wiederholter Ausführung der gleichen Formel mit unterschiedlichen Variableninhalten.

Für eine allgemeine, formale Grammatik mag das ggf. nicht taugen. Für logische und mathematische Terme war mir das bisher der angenehmste und universellste Ansatz, der zudem zu einer günstigen Datenstruktur führt.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#12

AW: Parser: Operatoren

  Alt 14. Apr 2012, 09:32
Bei Pascal z.B. betrifft dies den '.' (wie in 7.1) und '..' (wie in [1..2]).
Beim rekursiven parsen in einen Grammatikbaum (Term von aussen nach innen) weiss der Parser, dass er eine eckige Klammer betreten
Na ja. Widerspricht ja nicht dem, was ich geschrieben habe. Du kannst '..' als zwei Zeichen des Alphabets für die Programmiersprache Delphi ansehen, oder als ein Zeichen, entsprechend '(*', '*)' etc. Ich habe das immer als ein Zeichen interpretiert. Aber Scanner und Tokenizer arbeiten so. Z.B. bei C#:

a) int i=j++-++x; // geht
b) int i=j+++++x; // geht nicht

Bei A liefert der Tokenizer: id(int) id(i) symbol(assignment) id(j) symbol(plusplus) symbol(minus) symbol(plusplus) id(x)
Bei B liefert der Tokenizer: id(int) id(i) symbol(assignment) id(j) symbol(plusplus) symbol(plusplus) symbol(plus) id(x)

Würde der Parser das erkennen, wären beide Zeilen kompilierbar. Aber nur die erste Zeile funzt, eben weil der Scanner so blöd ist, und im Fall B die ersten zwei Plus-Paare erkennt. Probier's mal aus.

Hmm, aber dein Parser sucht ...
Ein Parser sicht nicht, ein Parser erkennt nur. Algorithmisch gesehen liefert ein Parser die Antwort auf die Frage: 'Ist diese Zeichenkette ein Satz aus der Grammatik G?'. Den Vorgang des Erkennens kann man nutzen, um einen Syntaxbaum aufzuspannen, über den dann das Compilat erzeugt wird. Algorithmisch gesehen wird jedoch nur ein Satz der Sprache 'A' (Delphi) in einen Satz der Sprache 'B' (Assembler) überführt. Das der Maschinencode semantisch äquivalent zum Quellcode ist, ist Glücksache.
Zitat:
Aber im Falle des Minus ist der Fall doch eigentlich klar:
...
Zumindest sind diese Regeln bei Parsern so üblich...
Diese 'Regeln' ergeben sich implizit über die Grammatik. Für deine letzte Regel ist aber der Tokenizer zuständig;
Zitat:
in der Mathematik ist es ja normalerweise nicht erlaubt, dass Operatoren oder mehrere Vorzeichen aufeinander folgen...
Nein, was ist denn daran nicht erlaubt? "a = 1+-+-+-+-+-2;
Zitat:
Bei Fakultät und Subfakultät müsste es so ähnlich sein.
Das ergibt sich aus deiner Grammatik.
  Mit Zitat antworten Zitat
idefix2

Registriert seit: 17. Mär 2010
Ort: Wien
961 Beiträge
 
RAD-Studio 2009 Pro
 
#13

AW: Parser: Operatoren

  Alt 14. Apr 2012, 10:17
Zitat:
Nein, was ist denn daran nicht erlaubt? "a = 1+-+-+-+-+-2;
Was ist bitte daran erlaubt?


Zitat:
Das der Maschinencode semantisch äquivalent zum Quellcode ist, ist Glücksache.
Programmieren ist doch generell Glückssache

Geändert von idefix2 (14. Apr 2012 um 12:22 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
728 Beiträge
 
#14

AW: Parser: Operatoren

  Alt 16. Apr 2012, 11:30
In meinem Compiler habe ich rekursives parsen eingebaut. Undzwar wie folgt:

(von oberer zu unterer schicht, niedrigstes level bindet am stärksten):

releation := expression (relop Expression)
expression := Term (+- Term)*
term := factor (*/ Factor)*
factor := Var|Constant|Function call| '(' relation ')'

wenn ich bei Factor vor meinem wert ein '-' finde, weiß ich es ist ein vorzeichen. Die funktionen liefern übrigens bei mir einen Datentyp zurück. So kann ich ich typensicherheit verfolgen


edit @idefix: ich glaib dieses operator gewurschtel ist von delphi erlaubt, finde ich perönlich nicht so schön
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
31.638 Beiträge
 
Delphi XE3 Professional
 
#15

AW: Parser: Operatoren

  Alt 16. Apr 2012, 11:54
edit @idefix: ich glaib dieses operator gewurschtel ist von delphi erlaubt, finde ich perönlich nicht so schön
Meinst du das 1+-+-+-+-+-2 ?

Wenn man klammern setzt, dann läßt sich erkennen, daß es damit eigentlich keine Probleme geben sollte.
1+(-(+(-(+(-(+(-(+(-2)))))))))



Man könnte aber auch einfach die Plus/Minus zählen und entsprechend handeln.
So mach ich das in meinem Billigparser.

Das erste Plus Der erste Operator ist die Rechenoperator
und die +/- danach sind das Vorzeichen.
* alle Plus (Vorzeichen) werden stur ignoriert (da eh ohne Wirkung)
* die Minus werden gezählt ... bei einer ungeraden Anzahl ist es ein "-" und bei einer geraden Anzahl ein ignorierbares "+".

1+(-+-+-+-+-2) ergibt dann ein 1+(-- -- -2) , also 1+(-2)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014

Geändert von himitsu (16. Apr 2012 um 12:03 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
728 Beiträge
 
#16

AW: Parser: Operatoren

  Alt 16. Apr 2012, 12:27
1+(-+-+-+-+-2) ergibt dann ein 1+(-- -- -2) , also 1+(-2)
Also ein  1-2
Ja die operatoren schlange macht vielleicht 'sinn' aber sie ist extrem hässlich und zum glück vernab jeglicher praktischer verwendung.
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden
  Mit Zitat antworten Zitat
Iwo Asnet

Registriert seit: 11. Jun 2011
313 Beiträge
 
#17

AW: Parser: Operatoren

  Alt 16. Apr 2012, 12:55
Zitat:
Nein, was ist denn daran nicht erlaubt? "a = 1+-+-+-+-+-2;
Was ist bitte daran erlaubt?
Der Ausdruck. Versuche es selbst. In der Mathematik ist es problemlos möglich, und ich sehe keinen Grund (außer vielleicht einem ästhetischen), dies nicht zuzulassen. Bei ersetzenden Skriptsprachen (z.B. TeX) ist es sogar existentiell, das ein solcher Ausdruck keine Probleme bereitet. Ich kann mir auch vorstellen, das Codegeneratoren viel komplexer sein müssten, wären redundante Vorzeichen nicht erlaubt.

releation := expression (relop Expression)
expression := Term (+- Term)*
term := factor (*/ Factor)*
factor := Var|Constant|Function call| '(' relation ')'
wenn ich bei Factor vor meinem wert ein '-' finde, weiß ich es ist ein vorzeichen
Ich sehe das Vorzeichen in deiner Grammatik nicht. Dann muss dein Parser auch nichts 'wissen'. Parser sind -wie Du sicherlich schon herausgefunden hast- strutzdämlich, wissen gar nichts und machen doch alles richtig.
  Mit Zitat antworten Zitat
Namenloser
Online

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.639 Beiträge
 
FreePascal / Lazarus
 
#18

AW: Parser: Operatoren

  Alt 16. Apr 2012, 13:35
edit @idefix: ich glaib dieses operator gewurschtel ist von delphi erlaubt, finde ich perönlich nicht so schön
Meinst du das 1+-+-+-+-+-2 ?

Wenn man klammern setzt, dann läßt sich erkennen, daß es damit eigentlich keine Probleme geben sollte.
1+(-(+(-(+(-(+(-(+(-2)))))))))
Das Problem ist aber, dass die Klammern nicht da sind. In der Mathematik ist nur die Schreibweise mit Klammern erlaubt, nicht ohne. Genau so ist z.B. 5*-2 auch nicht erlaubt, sondern es muss 5*(-2) heißen. Ich habe es mir auch nicht ausgedacht, aber es ist nun mal so festgelegt. Wenn du das in der Schule so schreibst, wird dir das als Fehler angestrichen.

Bei Computern ist das in der Regel anders, aber das liegt daran, dass Informatiker halt manchmal ihre eigenen Regeln und Konventionen aufstellen und sich nicht an die aus der Mathematik halten. Z.B. ist ja auch der Ursprung des Koordinatensystems beim Computer meist links oben, während er sich in der Mathematik normalerweise links unten befindet.

Ich kann mir auch vorstellen, das Codegeneratoren viel komplexer sein müssten, wären redundante Vorzeichen nicht erlaubt.
Genau das wird wohl der Grund sein. Es hätte einfach keinen Vorteil, eine Aneinanderreihung von Vorzeichen zu verbieten, sondern würde nur den Code komplizierter machen. Aber deshalb ist es in der Mathematik noch lange nicht erlaubt...

Geändert von Namenloser (16. Apr 2012 um 13:38 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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:

Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2016, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2016 by Daniel R. Wolf