home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Tool Box
/
SIMS_2.iso
/
bp_3_94
/
vbdos
/
abfrage.bas
next >
Wrap
BASIC Source File
|
1994-05-25
|
7KB
|
233 lines
DECLARE SUB Baum_New (Zeiger AS INTEGER)
DECLARE FUNCTION BedingungPasst (Daten AS ANY, Zeiger AS INTEGER) AS INTEGER
DECLARE SUB ErstelleBlatt (Wort AS STRING, Zeiger AS INTEGER)
DECLARE SUB Parse (Ausdruck AS STRING, Zeiger AS INTEGER)
DECLARE FUNCTION Passt (Daten AS ANY, Zeiger AS INTEGER) AS INTEGER
DECLARE SUB TeileWoerter (Zeile AS STRING, Wort() AS STRING)
CONST True = -1, False = 0
TYPE AdressenTyp
Name AS STRING * 40
Strasse AS STRING * 40
Ort AS STRING * 40
Bestellungen AS INTEGER
END TYPE
TYPE BaumTyp
Operator AS STRING * 40
LinkerNachf AS INTEGER
RechterNachf AS INTEGER
END TYPE
COMMON SHARED Baum() AS BaumTyp
REDIM Baum(0 TO 0) AS BaumTyp
' hier beginnt der Test-Teil
DIM A AS AdressenTyp, Such AS STRING
DIM BaumStart AS INTEGER
CLS : PRINT "---- Baum-Suche Testprogramm ----"
LINE INPUT "Suchausdruck: ", Such
Parse Such, BaumStart ' Baum erzeugen
DO
PRINT "-------------------"
INPUT "Dateneingabe Name: ", A.Name
INPUT " Straße: ", A.Strasse
INPUT " Ort: ", A.Ort
INPUT " Bestellungen: ", A.Bestellungen
IF Passt(A, BaumStart) THEN
PRINT "Datensatz paßt auf Suchausdruck"
ELSE
PRINT "Datensatz paßt nicht auf Suchausdruck"
END IF
LOOP
' Neues Element im Baum anlegen
SUB Baum_New (Zeiger AS INTEGER)
Zeiger = UBOUND(Baum) + 1
REDIM PRESERVE Baum(0 TO Zeiger) AS BaumTyp
END SUB
' Prüfen, ob eine Bedingung auf einen geg. Datentyp zutrifft
FUNCTION BedingungPasst (Daten AS AdressenTyp, Zeiger AS INTEGER) AS INTEGER
DIM Var AS STRING, Konst AS STRING, VarInhalt AS STRING
DIM Numerisch AS INTEGER
' Jeder Baumknoten, der an diese Funktion übergeben
' wird, zeigt mit LinkerNachf auf einen Variablennamen,
' mit RechterNachf auf eine Konstante, von der wir ggf. die
' Anführungszeichen abschneiden:
Konst = RTRIM$(Baum(Baum(Zeiger).RechterNachf).Operator)
IF LEFT$(Konst, 1) = CHR$(34) THEN
Konst = MID$(Konst, 2, LEN(Konst) - 2)
END IF
Var = UCASE$(RTRIM$(Baum(Baum(Zeiger).LinkerNachf).Operator))
' Jetzt wissen wir zwar, wie die Variable heißt, aber an den
' Inhalt müssen wir erst noch herankommen:
' Am Ende des Artikels wird eine Alternative hierzu be-
' schrieben!
SELECT CASE Var
CASE "NAME": VarInhalt = RTRIM$(Daten.Name)
CASE "STRASSE": VarInhalt = RTRIM$(Daten.Strasse)
CASE "ORT": VarInhalt = RTRIM$(Daten.Ort)
CASE "BESTELLUNGEN":
VarInhalt = LTRIM$(STR$(Daten.Bestellungen))
Numerisch = True
END SELECT
' Nun kann die Prüfung stattfinden
' Zur Erinnerung: Die Zeile "x = (behauptung)" führt
' dazu, dass x TRUE wird, wenn die "behauptung" stimmt
IF NOT Numerisch THEN
SELECT CASE RTRIM$(Baum(Zeiger).Operator)
CASE "ENTHAELT"
BedingungPasst = (INSTR(VarInhalt, Konst) > 0)
CASE "BEGINNTMIT"
BedingungPasst = (LEFT$(VarInhalt, LEN(Konst)) = Konst)
CASE "=" ' geht nur mit ISAM!
BedingungPasst = (TEXTCOMP(VarInhalt, Konst) = 0)
CASE "=="
BedingungPasst = (VarInhalt = Konst)
CASE ">"
BedingungPasst = (VarInhalt > Konst)
CASE "<"
BedingungPasst = (VarInhalt < Konst)
END SELECT
ELSE
SELECT CASE RTRIM$(Baum(Zeiger).Operator)
CASE "=", "=="
BedingungPasst = VAL(VarInhalt) = VAL(Konst)
CASE ">"
BedingungPasst = VAL(VarInhalt) > VAL(Konst)
CASE "<"
BedingungPasst = VAL(VarInhalt) < VAL(Konst)
END SELECT
END IF
END FUNCTION
' Neues Element erstellen und "Wort" als Operator eintragen
SUB ErstelleBlatt (Wort AS STRING, Zeiger AS INTEGER)
Baum_New Zeiger
Baum(Zeiger).Operator = Wort
Baum(Zeiger).LinkerNachf = 0
Baum(Zeiger).RechterNachf = 0
END SUB
' Baum aus einem Suchausdruck erstellen
SUB Parse (Ausdruck AS STRING, Zeiger AS INTEGER)
REDIM Wort(0 TO 0) AS STRING
' Erst die umschliessenden Klammern entfernen und in
' Wörter teilen:
TeileWoerter MID$(Ausdruck, 2, LEN(Ausdruck) - 2), Wort()
' Ein neues Baum-Element erstellen:
Baum_New Zeiger
SELECT CASE UBOUND(Wort)
CASE 2
' Zwei Wörter - dann ist das linke der Operator
' (bislang gibt es nur NICHT):
Baum(Zeiger).Operator = UCASE$(Wort(1))
SELECT CASE UCASE$(Wort(1))
CASE "NICHT"
Parse Wort(2), Baum(Zeiger).LinkerNachf
END SELECT
CASE 3
' Drei Wörter - dann ist das mittlere der Operator
Baum(Zeiger).Operator = UCASE$(Wort(2))
SELECT CASE UCASE$(Wort(2))
CASE "UND", "ODER" ' die logischen Operatoren
Parse Wort(1), Baum(Zeiger).LinkerNachf
Parse Wort(3), Baum(Zeiger).RechterNachf
CASE "ENTHAELT", "BEGINNTMIT", "=", "==", ">", "<"
ErstelleBlatt Wort(1), Baum(Zeiger).LinkerNachf
ErstelleBlatt Wort(3), Baum(Zeiger).RechterNachf
END SELECT
END SELECT
END SUB
' Prüfen, ob Datensatz auf Baum paßt
FUNCTION Passt (Daten AS AdressenTyp, Zeiger AS INTEGER) AS INTEGER
' Zunächst werden die logischen Operatoren geprüft
' und die Funktion rekursiv aufgerufen.
SELECT CASE RTRIM$(Baum(Zeiger).Operator)
CASE "UND"
Passt = False
IF Passt(Daten, Baum(Zeiger).LinkerNachf) THEN
Passt = Passt(Daten, Baum(Zeiger).RechterNachf)
END IF
CASE "ODER"
Passt = True
IF NOT Passt(Daten, Baum(Zeiger).LinkerNachf) THEN
Passt = Passt(Daten, Baum(Zeiger).RechterNachf)
END IF
CASE "NICHT"
Passt = NOT Passt(Daten, Baum(Zeiger).LinkerNachf)
' Um den Rest soll sich jemand anders kümmern
' (nur der Übersichtlichkeit halber!)
CASE ELSE
Passt = BedingungPasst(Daten, Zeiger)
END SELECT
END FUNCTION
SUB TeileWoerter (Zeile AS STRING, Wort() AS STRING)
' Eine Zeile wird in ihre Wörter unterteilt. Als "ein Wort" gilt
' dabei alles, was in Anführungszeichen oder Klammern steht.
REDIM Wort(0 TO 1) AS STRING
DIM Zaehler AS INTEGER, i AS INTEGER, AZModus AS INTEGER
DIM Zeichen AS STRING * 1, Klammer AS INTEGER
Zaehler = 1
FOR i = 1 TO LEN(Zeile)
Zeichen = MID$(Zeile, i, 1)
IF Zeichen = CHR$(34) THEN ' Anführungszeichen
AZModus = NOT AZModus
END IF
IF AZModus THEN
GOSUB Anhaengen ' Zeichen ungeprüft übernehmen
ELSE
IF Zeichen = " " AND Klammer = 0 THEN
IF LEN(Wort(Zaehler)) THEN
Zaehler = Zaehler + 1
REDIM PRESERVE Wort(0 TO Zaehler) AS STRING
END IF
ELSE
GOSUB Anhaengen
SELECT CASE Zeichen
CASE "(": Klammer = Klammer + 1
CASE ")": Klammer = Klammer - 1
END SELECT
END IF
END IF
NEXT
EXIT SUB
Anhaengen:
Wort(Zaehler) = Wort(Zaehler) + Zeichen
RETURN
END SUB