IF-Forum

» IF-Forum - Autorencafé - Schreiben! - Doppeldeutige Nouns herausfinden
AntwortenNeues ThemaNeue Umfrage

Doppeldeutige Nouns herausfinden

Geschrieben um 15:40 am 24.09.2013 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Gibt es einen Compiler-Switch, ein Debug-Verb oder ein extra Tool mit dem ich mein Spiel (entweder den resultierenden Z-Code oder den Source Code) nach doppeldeutigen Nouns[1] überprüfen kann?

Schön wäre als Ausgabe eine Liste der doppeldeutigen Namen und den dazugehörigen Objekten, die ich dann einerseits auf Richtigkeit überprüfen kann und andererseits als Todo-Liste hernehmen kann, um die Disambiguisierung zu implementieren.


[1]: Also Nouns, die bei mehr als einem Objekt in der name property vorkommen.

Geschrieben um 01:33 am 25.09.2013 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

Mischa:

Gibt es einen Compiler-Switch, ein Debug-Verb oder ein extra Tool mit dem ich mein Spiel (entweder den resultierenden Z-Code oder den Source Code) nach doppeldeutigen Nouns[1] überprüfen kann?

Nicht, dass ich wüsste. Aber die Abfrage ist auch nicht so super-aufwendig; allerdings muss man etwas die Treppe runter in Richtung Wörterbuch-Keller, wo es unbequem zugehen kann.

Ich habe mal auf die Schnelle eine Check-Routine geschrieben, die in etwa das macht, was Dir vorschwebt ... allerdings nur oberflächlich getestet. Wenn Du das Beispiel komplett in Deinen Code kopierst, kannst Du mit dem Befehl #SYNCHECK die Prüfung starten. Allerdings klappt das nur mit Vokabeln, die in der name-Property der Objekte stehen. (Wenn über parse_name geparst wird, klappt das Ermitteln des Vokabel-Objekt-Kontextes nicht so einfach, was auch schon der Libcheck in GerX auf abenteuerliche Weise zu umgehen versucht.)



Verb '#syncheck' * -> Syncheck;

Array results -> 48;

[ SyncheckSub     dict_start dict_entry_size dict_end

                  dict_entries match

                  a i j o;

    dict_start = HDR_DICTIONARY-->0;

    dict_entry_size = dict_start->(dict_start->0 + 1);

    dict_start = dict_start + dict_start->0 + 4;

    dict_end = dict_start + ((dict_start - 2)-->0) * dict_entry_size;

    dict_entries = (dict_start - dict_end)/dict_entry_size;

    if (dict_entries < 0) dict_entries = -dict_entries;

    for (a = 0 : a < dict_entries : a++ ) {

        ! Adresse berechnen

        i = dict_start + a*dict_entry_size;

        j = i->#dict_par1;

       

        match = 0;

        if (j & $$10000000) { ! ist die Vokabel ein Objekt-Synonym?

            ! Wenn ja, dann Schleife über alle Objekte und prüfen,

            ! ob das Synonym in der name-Property enthalten ist. Bei

            ! einem Treffer, wird das Objekt mit Nummer angezeigt.

            ! Objektsynonyme, die über parse_name geparst werden,

            ! können leider nicht so einfach geprüft werden.

            objectloop (o provides name) {

                if (WordInProperty(i, o, name)) {

                    results->match = o;

                    match++;

                }

            }

            if (match > 1) {

                print "---------";

                print " Vokabel '", (address) i, "':^";

                for (i = 0 : i < match : i++) {

                    print (name) results->i, " (", results->i, ")^";

                }

                print "---------^^";

            }

        }

    }

];

#endif;```

Das geht bestimmt noch schöner, aber die wichtigsten Sachen zum Durchackern des Wörterbuchs stehen schon mal drin.
Geschrieben um 07:08 am 25.09.2013 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Danke, das sieht sehr vielversprechend aus! :-)

Geschrieben um 13:20 am 25.09.2013 | Zitat | Editieren | Löschen
ChristianB
Mitglied
Retired Gumby
Beiträge: 1062

In der Zeile

if (j & $$10000000) { ...

stand bis eben noch i anstatt j, das habe ich im Beispiel oben jetzt korrigiert. Es soll natürlich nicht die Vokabel selbst (hier i), sondern die Dictionary-Parameter-Bits (hier j) geprüft werden, genauer Bit Nr. 7.

Geschrieben um 21:19 am 07.10.2013 | Zitat | Editieren | Löschen
Mischa
Mitglied
Master Gumby
Beiträge: 107

Endlich hab' ich mal die Zeit gefunden, deinen syncheck auszuprobieren!

Funktioniert einwandfrei.

Das Einzige, was ihn noch besser machen würde, wäre das Ausgeben der Objektvariablen (zusätzlich zur Nummer), aber ich fürchte, das bekommt man aus dem kompilierten Z-Code nicht mehr raus, oder?

Geschrieben um 23:30 am 07.10.2013 | Zitat | Editieren | Löschen
Martin
Avatar
Mitglied
Prof Gumby
Beiträge: 634

Mischa:

Das Einzige, was ihn noch besser machen würde, wäre das Ausgeben der Objektvariablen (zusätzlich zur Nummer), aber ich fürchte, das bekommt man aus dem kompilierten Z-Code nicht mehr raus, oder?

Wenn man Infix mit -X aktiviert, kommt man an alle internen Symbole von Inform ran. Das bläht aber natürlich auch den Code auf. (Ich habe Infix nie nützlich gefunden.)

Also, hier eine printing rule für Objektsymbole:


    i lo hi is_obj j;

   

    #ifdef INFIX;

    lo = #lowest_constant_number;

    hi = #highest_constant_number;

   

    for (i = lo : i <= hi : i++) {

        j = Symb__Tab(INFIXTT_CONSTANT, i);

        is_obj = (temp__global3 % 32 == 2);

        if (is_obj && j == o) {

            InfixPrintConstant(i);

            return;

        }

    }

    #ifnot;

    i = lo = hi = is_obj = j; ! Maul halten, I6

    #endif;

    print "#unnamed_object_", o;

];

Wenn man aus den Zahlen auf Objekte schließen möchte, kann man I6 auch mit der Option -j laufen lassen. Dann werden einem alle Objekte mit numerischer Id aufgelistet, allerdings wird dabei nicht das interne Symbol ausgegeben, sondern der short name, der im Objektkopf steht. Die Objekte stehen aber in derselben Reihenfolge, in der sie im Quelltext auftauchen.

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