Original Parser

version 1 by Ron Newcomb

  • Home page
  • Beginning
  • Previous
  • Next



  • Chapter - TryGivenObject

    [|TryGivenObject| tries to match as many words as possible in what has been
    typed to the given object, |obj|. If it manages any words matched at all,
    it calls |MakeMatch| to say so, then returns the number of words (or 1
    if it was a match because of inadequate input).]

    To decide what number is how many words (obj - an object) can match, hypothetically (this is TryGivenObject):
        if trace 5, say " Trying [the obj] ([the obj as a debugging number]) at word [parser's current word position][line break]";
        if the obj is nothing and hypothetically, Decide on 0;
        exclude all possibilities from the word's usages;
        if the parser's current word position > the number of words in the command:
            if hypothetically, decide on 0 [words matched];
            if the indefinite article mode is true, now the word's usages is the unused usages;
            ADD the obj TO THE MATCH LIST assuming zero qualifies it;
            if trace 5, say " Matched (0)[line break]";
            Decide on 1 [word matched];
        let the count of matched words be 0;
        if the hidden parse name rule of the obj is not currently blank:
            now what the parser's doing is parsing normally;
            let the saved position be the parser's current word position;
            now the count of matched words is the parse name rule of the obj considered directly;
            if the count of matched words is at least 1:
                now the parser's current word position is the saved position + the count of matched words;
                Decide on the count of matched words after noting descriptors and plurality of the obj;
            otherwise if the count of matched words is 0:
                if the indefinite article mode is false, Decide on 0 [words matched];
                now what the parser's doing is parsing normally;
                Decide on 0 after noting descriptors and plurality of the obj;
        now what the parser's doing is parsing normally;
        let the appropriate word be the possibility that it's a noun;
        if the appropriate word is ME The Player and the obj is the player:
            Decide on 1 after noting descriptors and plurality of the obj;
        if the obj is the antecedent for the appropriate word:
            Decide on 1 after noting descriptors and plurality of the obj;
        unless the word at the parser's current word position - 1 can refer to the obj:
            if the indefinite article mode is false, Decide on 0 [words matched];
            now what the parser's doing is parsing normally;
            Decide on 0 after noting descriptors and plurality of the obj;
        now the count of matched words is 1;
        now the word's usages is the usage of the appropriate word excluding (being plural + the unused usages);
        now the appropriate word is the next word;
        while the word at the parser's current word position - 1 can refer to the obj:
            increment the count of matched words;
            if the appropriate word is not a word unknown by the game:
                include the usage of the appropriate word excluding (being plural + the unused usages) in the word's usages;
            now the appropriate word is the next word;
        Decide on the count of matched words after noting descriptors and plurality of the obj.


    To decide which number is (how many matched - a number) after (done this hypothetically - a truth state) and plurality of (obj - an object):
        if identifying plurals is what the parser's doing:
            include being plural in the word's usages;
        if the word's usages include being plural:
            if we cannot allow numeric words as descriptors:
                now how many matched is 0;
            otherwise:
                if the indefinite article mode is false:
                    now the indefinite article mode is true;
                    exclude all possibilities from the type of descriptor word used;
                    now the number of items wanted is 0;
                include a plural descriptor in the type of descriptor word used;
                if the number of items wanted is 0:
                    now the number of items wanted is all items are wanted;
        if trace 5, say " Matched ([how many matched]) words[line break]";
        if we haven't done this hypothetically:
            ADD the obj TO THE MATCH LIST assuming how many matched qualifies it;
        Decide on how many matched.

    Noting descriptors is a truth state that varies. [ This is a hackish way to get code that reads well. ]
    Noting descriptors variable translates into I6 as "phrase_options".

    [ TryGivenObject obj nomatch threshold k w j;
    #Ifdef DEBUG;
    if (parser_trace >= 5) print " Trying ", (the) obj, " (", obj, ") at word ", wn, "^";
    #Endif; ! DEBUG

        if (nomatch && obj == 0) return 0;

    ! if (nomatch) print "*** TryGivenObject *** on ", (the) obj, " at wn = ", wn, "^";

    dict_flags_of_noun = 0;

    ! If input has run out then always match, with only quality 0 (this saves
    ! time).

    if (wn > num_words) {
    if (nomatch) return 0;
    if (indef_mode ~= 0)
    dict_flags_of_noun = $$01110000; ! Reject "plural" bit
    MakeMatch(obj,0);
    #Ifdef DEBUG;
    if (parser_trace >= 5) print " Matched (0)^";
    #Endif; ! DEBUG
    return 1;
    }

    ! Ask the object to parse itself if necessary, sitting up and taking notice
    ! if it says the plural was used:

    if (obj.parse_name~=0)
    {
    parser_action = NULL; j=wn;
    k = RunRoutines(obj,parse_name);
    if (k > 0)
    {
    wn=j+k;

    .MMbyPN;

    if (parser_action == ##PluralFound)
    dict_flags_of_noun = dict_flags_of_noun | 4;

    if (dict_flags_of_noun & 4)
    {
    if (~~allow_plurals)
    k = 0;
    else
    {
    if (indef_mode == 0)
    {
    indef_mode = 1; indef_type = 0; indef_wanted = 0;
    }
    indef_type = indef_type | PLURAL_BIT;
    if (indef_wanted == 0)
    indef_wanted = INDEF_ALL_WANTED;
    }
    }

    #Ifdef DEBUG;
    if (parser_trace >= 5) print " Matched (", k, ")^";
    #Endif; ! DEBUG
    if (nomatch == false)
    MakeMatch(obj,k);
    return k;
    }
    if (k == 0)
    jump NoWordsMatch;
    }

    ! The default algorithm is simply to count up how many words pass the
    ! Refers test:

    parser_action = NULL;

    w = NounWord();
    if (w == 1 && player == obj) { k=1; jump MMbyPN; }
    if (w >= 2 && w < 128 && (LanguagePronouns-->w == obj)) { k = 1; jump MMbyPN; }

    if (Refers(obj, wn-1) == 0)
    {
    .NoWordsMatch;
    if (indef_mode ~= 0)
        {
            k = 0;
            parser_action = NULL;
            jump MMbyPN;
        }
    rfalse;
    }

    threshold = 1;
    dict_flags_of_noun = (w->#dict_par1) & $$01110100;
    w = NextWord();
    while (Refers(obj, wn-1))
    {
    threshold++;
    if (w)
    dict_flags_of_noun = dict_flags_of_noun | ((w->#dict_par1) & $$01110100);
    w = NextWord();
    }
    k = threshold;

    jump MMbyPN;
    ]