IF-Forum

» IF-Forum - Autorencafé - Schreiben! - Deklinator V1.0
AntwortenNeues ThemaNeue Umfrage

Deklinator V1.0

Geschrieben um 08:18 am 31.07.2004 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

Hallo,

da es mir zu müssig war, bei praktisch jedem neuen Objekt die Deklinationstabelle zu studieren, habe ich ein kleines Tool erstellt, das mir (fast) die Arbeit abnimmt.

Vielen Dank an Martin, der mich mit Tests und Tips dabei unterstützt hat.

Es ist ein kompiliertes z5-File bei dem man einfach den Namen und Genus eingibt und dann über Steuerungstasten die einzelnen Deklinationen im Singular und Plural durchlaufen kann bis man die richtige gefunden hat (wenn man nicht mit dekl 0 arbeiten muss). Den Wert für die dekl-Property liest man dann einfach ab und trägt ihn in seinen Code ein.

Der Vorteil gegenüber dem Debugbefehl '>dekliniere baum' ist, dass ich nicht erst kompilieren und prüfen muss, ob dieser eine Wert richtig war, hier kann man sich per Tastendruck nacheinander alle Deklinationen anschauen.

Mir ist es eine Hilfe beim programmieren, und vielleicht kann es ja auch der eine oder andere gebrauchen.

Zur Zeit befindet es sich noch unter

http://www.ifarchive.org/indexes/if-archiveXunprocessed.html

Da es als .z5 und nicht als .zip hochgeladen wurde, muss man es (deklinator.z5) mit der rechten Maustaste anklicken und dann auf "Ziel speichern unter" gehen.

(Es wird aber auch noch ein .zip geben)

Grüße

Kris

Geschrieben um 22:10 am 05.08.2004 | Zitat | Editieren | Löschen
Mo
Mitglied
Dr Gumby
Beiträge: 290

Nachtrag. Herunterladen kann man es jetzt hier:.

www.ifarchive.org oder ftp.ifarchive.org oder ftp.funet.fi (gzip-komprimiert).

Geschrieben um 22:20 am 05.08.2004 | Zitat | Editieren | Löschen
Christoph
Mitglied
Student Gumby
Beiträge: 37

Hi Kris,

ich habe den Deklinator nur mal kurz ausprobiert, aber er sieht sehr gut aus! Ich bin es auch leid, bei jedem Objekt die Deklinationstabellen rauskramen zu müssen.

Ich wüsste nicht im entferntesten, wie ich sowas in Inform programmieren würde, sieht schwer nach Z-Machine-Bastelei aus. Hut ab!

Toni Arnolds hat auf seiner Homepage übrigens ein kleines CGI-Script, dass versucht, nach Eingabe des Objektnamens (Substantiv) selbständig die richtige dekl-Form zu finden.

Keine Ahnung, ob du dich mit CGI auskennst (ich tu's nicht), aber vielleicht könnte man das kombinieren und den Deklinator damit soweit bringen, von selbst die richtige Form zu finden und als erste Möglichkeit anzubieten? Nur so eine Idee...

Schöne Arbeit jedenfalls!

Geschrieben um 19:39 am 06.08.2004 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

Hallo!

Zitat:

Nachtrag. Herunterladen kann man es jetzt hier:.

www.ifarchive.org oder ftp.ifarchive.org oder ftp.funet.fi (gzip-komprimiert).

Danke, warst schneller als ich :-)

Zitat:

Toni Arnolds hat auf seiner Homepage übrigens ein kleines CGI-Script, dass versucht, nach Eingabe des Objektnamens (Substantiv) selbständig die richtige dekl-Form zu finden.

Habe ich auch schon gesehen, komme damit aber nicht ganz zurecht:

Ich hatte z.B. schon über dieses Script für Bus dekl 1 genannt bekommen, und das stimmt nicht (obwohl es in seinen Beispielen richtig dekliniert wird!?)

In Inform wird ein Bus mit dekl 1 im Plural Dativ zum Busen (und die anderen stimmen auch nicht ganz).

Zitat:

aber vielleicht könnte man das kombinieren und den Deklinator damit soweit bringen, von selbst die richtige Form zu finden und als erste Möglichkeit anzubieten? Nur so eine Idee...

Hmm, Martin meinte beim Testen auch schon so etwas, ich habe mich aber erstmal aus Zeitgründen davor gedrückt. Mein Spiel kam nicht voran weil ich mich dort ausgeklingt und nur noch an dem Deklinator gebastelt hatte. Aber ich werde mich mal damit beschäftigen, es macht ja schon Sinn.

Toll wäre es, wenn die suffixes-Property auch Arrays zugewiesen bekommen könnte, dann würde ich nämlich weitere häufige Deklinationen in einer Extension in Arrays schreiben. Diese würden dann ebenfalls im Deklinator angezeigt werden und man könnte dann der Objektproperty suffixes den genannten Array zuweisen. (hmm, ziehmlich viele "könnte" und "würde" ;-)

Leider habe ich dass aber nicht zum Laufen gebracht (habe aber auch nur 20 Minuten probiert)

Ich schätze hier kann mir bestimmt jemand sagen, ob dieser Property überhaupt einen Array zugewiesen bekommen kann (ich glaube aber nicht dass es geht).

Grüße

Kris

Geschrieben um 11:28 am 16.08.2004 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

Hi,

ich weiss zwar nicht, ob noch jemand gerne mit Arrays für die suffixes-Property arbeiten möchte, aber ich bin nun schlauer als noch in meinem letzten Post und gebe mal die Info weiter:

In der ta_PrintNounSuffix-Routine aus tgerman.h steht folgendes:



... if (metaclass(obj.suffixes) == Routine)

      obj.suffixes(case);

   

...   ```

D.h. sollte suffixes eine Routine beherbergen wird diese ausgeführt und der Wert case (also die Eintrag-Nummer) übergeben.

Wenn man mit einem Array arbeiten möchte kann man das so lösen:

```...

SFX_Array --> "n"  "n" "n" "n";

...

Object Orange

  with ...blabla...

           dekl 0,

           suffixes [case; print (string) SFX_array --> case;],

   has pluralname female;

...```

Also, wer's braucht...

Grüße

Kris
Geschrieben um 10:38 am 18.08.2004 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Kris:

Ich schätze hier kann mir bestimmt jemand sagen, ob dieser Property überhaupt einen Array zugewiesen bekommen kann (ich glaube aber nicht dass es geht).

Wenn ich das PDF-Dokument zur deutschen Inform-Lib richtig gelesen habe, kann suffixes ein Array oder eine Routine haben, wobei ein Array wohl die gängigere Variante ist.

Kris:

In der ta_PrintNounSuffix-Routine aus tgerman.h steht folgendes:

Das komplette Zitat lautet:


   ... if (obj provides suffixes) {

       n = case + ta_ArticlesNumberOffset(obj);

       if (metaclass(obj.suffixes) == Routine)

           obj.suffixes(case);

       else

           print (string) (obj.&suffixes-->case);

   }

Und das macht ja ziemlich genau das, was deine Routine macht, nur dass hier suffixes bereits ein Array ist.

Die Vorgehensweise der Lib, wie sie auch dokumentiert und implementiert ist: Schreibe den short_name, dann hänge folgendes an:

  • Wenn dekl nicht null ist: Eine Endung, je nach Fall, Anzahl und Deklinationsform

  • Wenn dekl null ist und suffixes ein Feld enthält, dann schreibe den für den Fall passenden Eintrag (0=Nominativ, 1=Akkusativ, 2=Dativ, 3=Genitiv) des Feldes, der ein String in Gänsefüßchen sein muss

  • Wenn dekl null ist und suffixes eine Routine ist, das, was diese Routine ausgibt, der Fall wird als Argument übergeben

  • ansonsten nichts

Im Fall einer Routine würde man wohl eher den unüblichen Fall mit einem if abfangen, anstatt sich auf ein Hilfsfeld zu beziehen, im (oben erwähnten) einfachsten Fall also:


Object Orange

  with ...

       dekl 0,

       suffixes [c; print "n"; ],

   has pluralname female;

Oder natürlich:


Object Orange

  with dekl 0,

       short_name "Orangen",

       ...;

(Ich habe nie verstanden, warum man in Inform die Plurale so angeben muss, als ob sie im Singular stehen, zumal das ganze - im Gegensatz zu Floyd etwa - nicht ganz zu Ende gedacht ist. Man muss zum Beispiel Umlautbildungen ("Äpfel") schon angeben, Plural-Suffixe aber nicht.)

Geschrieben um 14:52 am 18.08.2004 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

Hallo,

Zitat:

Wenn dekl null ist und suffixes ein Feld enthält, dann schreibe den für den Fall passenden Eintrag (0=Nominativ, 1=Akkusativ, 2=Dativ, 3=Genitiv) des Feldes, der ein String in Gänsefüßchen sein muss

Ich habe einen Array und ein Object folgendermassen deklariert:



Array SFX_array --> "n" "n" "n" "n";

...

Object Orange "Orange" Startraum

  with   name 'orange',

     description "Einfach eine Orange.",

     dekl 0,

     suffixes SFX_array,

  has   female pluralname;

...```

Wenn ich nun die Orange dekliniere, kommt folgende Fehlermeldung:

>dekl orange

die Orange

[** Programming error: tried to print (string) on something not a string **]

die Orange

[** Programming error: tried to print (string) on something not a string **]

den Orange

[** Programming error: tried to print (string) on something not a string **]

der Orange

[** Programming error: tried to print (string) on something not a string **]

Wenn ich den Array aber über die Routine wie oben beschrieben einsetze, gibt es keine Probleme.

Nachdem ich die ta_PrintNounSuffix "studiert" hatte war ich ja auch der Meinung, dass es eigentlich mit einem Array gehen muss. Nachdem es aber nicht lief,  dachte ich mir dass aus irgendwelchen Gründen der Array nicht gelesen wird sondern ein String dort stehen muss.

Weiß jemand warum?

Grüße

Kris
Geschrieben um 15:37 am 18.08.2004 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Oje! Du bist über die kruden Datenstrukturen des z-Codes gestolpert. Felder (die beliebig groß sein können) und Properties, die mehrere Einträge (maximal jedoch 32) enthalten, sind nicht dasselbe.


    with suffixes "n" "n" "n" "n", ...

Hier hat die property suffixes vier Word-Einträge, die mit Orange.&suffixes-->case gelesen werden können. Das entspricht der oben angegebenen Syntax und diese Version ist die von der Library vorgesehene.


    with suffixes SFX_array, ...

Das ist eine Property, die einen Word-Eintrag enthält. Dieser Eintrag bezieht sich auf ein Feld. Es gilt:


    Orange.suffixes == SFX_array

    Orange.&suffixes-->0 == SFX_array

    Orange.&suffixes-->1 == undefinded!

    (Orange.suffixes)-->1 == "n"

Inform kennt keine dynamischen Listenstrukturen, und so merkt es nicht, dass sich SFX_array auf ein Feld bezieht. Es gibt auch keine metaclass Array, so dass man herausfinden könnte, ob sich der Eintrag der Property auf ein Array bezieht.

Folgendes geht allerdings:


[ SFX_routine c; print "n"; ];

Object Orange "Orange"

  with name 'orange',

       dekl 0,

       suffixes SFX_routine,

   has female pluralmane;
Geschrieben um 18:38 am 18.08.2004 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

Zitat:

Oje! Du bist über die kruden Datenstrukturen des z-Codes gestolpert.

Prima, aber es ist ja nicht das erste mal :-)

Zitat:

Inform kennt keine dynamischen Listenstrukturen, und so merkt es nicht, dass sich SFX_array auf ein Feld bezieht. Es gibt auch keine metaclass Array, so dass man herausfinden könnte, ob sich der Eintrag der Property auf ein Array bezieht.

Habe ich dich richtig verstanden:

obj.&suffixes --> x

bezieht sich auf den x-ten String-Eintrag in suffixes.

Sollte suffixes ein Array zugewiesen haben, sucht z-Code den x-ten String und kann ihn nicht finden weil der nicht auf den x-ten String des Arrays (weiter-)verwiesen wird? Stimmt das so?

Grüße

Kris

Geschrieben um 08:50 am 19.08.2004 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Kris:

obj.&suffixes --> xbezieht sich auf den x-ten String-Eintrag in suffixes.

Genau. Aber vergiss mal das mit den Strings: Generell bezieht sich dieser Ausdruck auf den x-ten Wert dieser Property, wobei, wie üblich bei Null zu zählen angefagen wird. Wenn diese Property aber weniger als x Einträge hat, gibt es bei aktiviertem Strict Mode eine Fehlermeldung zur Laufzeit. (Bei deaktiviertem Strict Mode wird entweder Murks gelesen oder der Interpreter steigt mit einem Fehler aus.)

Ein Property, das auf ein Feld verweist, hat nur einen Eintrag - die Referenz auf das Feld eben. Die Lib geht aber, ohne es zu überprüfen, davon aus, dass der Autor vier Strings in suffixes definiert hat.

Vorschlag eines "Strict Mode" für die Lib:


       if (metaclass(obj.suffixes) == Routine)

           obj.suffixes(case);

       else {

           if (obj.#suffixes/WORDSIZE != 4)

               print "^[*** Inform.de: suffixes von ",

               (object) obj, " muss eine Routine oder vier

               Strings enthalten! ***]^";

           else if (metaclass(obj.&suffixes) != String)

               print "^[*** Inform.de: suffixes-->", case,

               " von ", (object) obj, " ist kein String! ***]^";

           else print (string) (obj.&suffixes-->case);

       }   

(Hier könnte der Interpreter allerdings bei (object) aussteigen - wenn obj kein gültiges Objekt ist.)

Geschrieben um 11:39 am 19.08.2004 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

Zitat:

Ein Property, das auf ein Feld verweist, hat nur einen Eintrag - die Referenz auf das Feld eben. Die Lib geht aber, ohne es zu überprüfen, davon aus, dass der Autor vier Strings in suffixes definiert hat.

Ok, gehen wir davon aus dass bei suffixes entweder vier Strings

eingetragen sind, eine Routine oder ein Array. Alles andere würde (erstmal) keinen Sinn machen.

Ich kann über metaclass prüfen ob es eine Routine oder Strings enthält. Wenn beides nicht zutrifft bleibt (sofern man sich daran hält nur diese drei Möglichkeiten zu nutzen) nur noch der Array übrig.

Da ich aber überhaupt keine Möglichkeit habe (jedenfalls habe ich das gestern Abend nicht geschafft) auf einen Eintrag in einem Array zuzugreifen der einer Property zugewiesen ist (also über obj.suffixes angesprochen werden muß) scheint die einzige (nicht mal aufwendige) Lösung dann wieder diese:


Object

...

suffixes [case; print (string) SFX_array --> case;],

...

Oder?

Kris

Geschrieben um 13:50 am 19.08.2004 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Kris:

Oder?

Weiß nicht. Ich habe das Gefühl, dass du eine einfache Sache ohne rechten Grund verkomplizierst. Wieso willst du auf ein externes Array zurückgreifen? Weil es 50 Objekte mit der Orangen-Deklination gibt? Dann schreib halt eine Klasse. So, wie es ist, ist es doch einfach: Wenn ich meine eigenen Endungen haben möchte - was ja nur in Ausnahmefällen vorkommt, schließlich gibt es ja immer noch die Deklinationstabellen - lege ich diese, vier Stück, für jeden Fall eine, in suffixes ab. Oder ich schreibe eine Routine, die sie mir ausgibt. Fertig.

Zitat:

Da ich aber überhaupt keine Möglichkeit habe ... auf einen Eintrag in einem Array zuzugreifen der einer Property zugewiesen ist ...

Wieso das nicht?


    print (string) (obj.suffixes)-->x;

Zitat:

Ich kann über metaclass prüfen ob es eine Routine oder Strings enthält. Wenn beides nicht zutrifft bleibt (sofern man sich daran hält nur diese drei Möglichkeiten zu nutzen) nur noch der Array übrig.

Leider ein Denkfehler - es kann sein, dass ein Array-Eintrag bereits als String oder Routine ausgewertet wird.

Warum? Die Routine metaclass überprüft nicht den tatsächlichen Wert der Variable, sondern nur, ob diese Variable in einem Bereic liegt, der eine Routine, ein Objekt oder ein String sein könnte. Dummerweise verwendet der z-Code gepackte Adressen. das war damals ein toller Trick, um mit 16-Bit-Adressen Speicher jenseits der 64k-Marke anzusprechen. Dort dürfen sich im z-Code nur Routinen und Strings befinden, und wenn x ein String ist, wird der String an der Adresse 4x ausgegeben. Alle anderen Datenstrukturen verwenden aber einfache Adressen, und so kann es sein, dass an x ein Feld liegt, und an 4x ein String. Oder x ein Wörterbucheintrag und an 4*x eine Routine.

Natürlich ist es unwahrscheinlich, dass das passiert, aber es passiert. Kompilier einmal mit -z, dann bekommst du angezeigt, in welchem Speicherbereich welche Daten liegen. Und schau mal, mit was sich "static text" und "z-code" überschneiden, wenn man sie durch 4 (oder 8 bei .z8) teilt.

In Glulx, das seine "Objekte" - Routinen, Strings, Wörterbucheinträge, Objekte im Inform-Sinn (daher die Anführungszeichen) usw., jedoch keine Arrays - typisiert und auch keine gepackten Adressen verwendet, mag das funktionieren, im z-Code nicht.

Wenn du tatsächlich in der Lib herumpfuschen willst und ein externes Array zulassen willst, solltest du eine andere Syntax festlegen, etwa


    Constant USE_ARRAY = -1;

   

    ...

    Object ->

      with suffixes USE_ARRAY SFX_array, ...;

Und dann checkst du, ob der erste Eintrag die Konstante USE_ARRAY ist, und wenn ja nimmst du dein zweiten Eintrag als Feld her. Kompliziert. Und ich wage zu behaupten: Keine Sau braucht's.

Deshalb mein Ratschlag: Statt dich in Details der Lib zu verfransen, lass alles, wie es ist. Die gesparte Energie kannst du dann auf das Spiel selbst verwenden...

Geschrieben um 17:00 am 19.08.2004 | Zitat | Editieren | Löschen
Kris
Mitglied
Dr Gumby
Beiträge: 181

Martin:

Ich habe das Gefühl, dass du eine einfache Sache ohne rechten Grund verkomplizierst. Wieso willst du auf ein externes Array zurückgreifen?

Ganz unrecht hast Du nicht, mir geht es gar nicht mehr nur unbedingt um diesen Array, sondern ich habe mich da festgebissen und versuche zu kapieren, wie Z-Code dort tickt.

Martin:

Wieso das nicht?


    print (string) (obj.suffixes)-->x;

Auch hier bin ich noch am beissen, aus dem Object direkt heraus bekomme ich es zum laufen:

...print (string) self.suffixes --> x;...

Aber nicht wenn das Objekt aus einer Routine angesprochen wird.

Martin:

Deshalb mein Ratschlag: Statt dich in Details der Lib zu verfransen, lass alles, wie es ist. Die gesparte Energie kannst du dann auf das Spiel selbst verwenden...

Da hast du vollkommen recht, ich muss aber leider zugeben dass ich bis jetzt am meisten über die Grundlagen gelernt habe, wenn es irgendwo hakte, und nicht weil ich freiwillig immer wieder Chapert I im DM4 gelesen habe ;-)

Martin:

Warum? Die Routine metaclass überprüft nicht den tatsächlichen Wert der Variable, sondern nur, ob diese Variable in einem Bereic liegt, der eine Routine, ein Objekt oder ein String sein könnte. Dummerweise verwendet der z-Code gepackte Adressen. das war damals ein toller Trick, um mit 16-Bit-Adressen Speicher jenseits der 64k-Marke anzusprechen. Dort dürfen sich im z-Code nur Routinen und Strings befinden, und wenn x ein String ist, wird der String an der Adresse 4x ausgegeben. Alle anderen Datenstrukturen verwenden aber einfache Adressen, und so kann es sein, dass an x ein Feld liegt, und an 4x ein String. Oder x ein Wörterbucheintrag und an 4*x eine Routine.

Dein Wissen erstaunt mich immer wieder...

Dank und Gruß

Kris

AntwortenNeues ThemaNeue Umfrage
Powered by Spam Board SVN © 2007 - 2021
Impressum / Datenschutz