Original Parser

version 1 by Ron Newcomb

  • Home page
  • Beginning
  • Previous
  • Next



  • Chapter - Match List

    [The match list is an array, |match_list-->|, which holds the current best
    guesses at what object(s) a portion of the command refers to. The global
    |number_matched| is set to the current length of the |match_list|.

    When the parser sees a possible match of object |obj| at quality level |q|,
    it calls |MakeMatch(obj, q)|. If this is the best quality match so far, then
    we wipe out all the previous matches and start a new list with this one.
    If it's only as good as the best so far, we add it to the list (provided
    we haven't run out of space, and provided it isn't in the list already).
    If it's worse, we ignore it altogether.

    I6 tokens in the form |noun=Filter| or |Attribute| are ``noun filter tokens'',
    and mean that the match list should be filtered to accept only nouns which
    are acceptable to the given routine, or have the given attribute. Such a
    token is in force if |token_filter| is used. (I7 makes no use of this in the
    attribute case, which is deprecated nowadays.)

    Quality is essentially the number of words in the command referring to
    the object: the idea is that "red panic button" is better than "red button"
    or "panic".]

    To add (obj - an object) to the match list assuming (quality - a number) qualifies it (this is MakeMatch):
        if trace 6, say " Match with quality [quality][line break]";
        if the noun filter is not currently blank and the noun filter disallows the obj:
            if trace 6, say " Match filtered out: token filter [noun filter][line break]";
            stop the action;
        if the quality < the number of words matched per object, stop the action;
        if the quality > the number of words matched per object:
            now the number of objects in the match list is 0; [ empty it out of all the lesser matches ]
            now the number of words matched per object is the quality;
        otherwise:
            if the number of objects in the match list >= the maximum number of things understood at once, stop the action;
            if the obj is listed in the match list of size the number of objects in the match list, stop the action;
        append the obj to the match list of size the number of objects in the match list;
        if trace 6, say " Match added to list[line break]".

    [ MakeMatch obj quality i;
    #Ifdef DEBUG;
    if (parser_trace >= 6) print " Match with quality ",quality,"^";
    #Endif; ! DEBUG
    if (token_filter ~= 0 && ConsultNounFilterToken(obj) == 0) {
    #Ifdef DEBUG;
    if (parser_trace >= 6) print " Match filtered out: token filter ", token_filter, "^";
    #Endif; ! DEBUG
    rtrue;
    }
    if (quality < match_length) rtrue;
    if (quality > match_length) { match_length = quality; number_matched = 0; }
    else {
    if (number_matched >= MATCH_LIST_WORDS) rtrue;
    for (i=0 : i<number_matched : i++)
    if (match_list-->i == obj) rtrue;
    }
    match_list-->number_matched++ = obj;
    #Ifdef DEBUG;
    if (parser_trace >= 6) print " Match added to list^";
    #Endif; ! DEBUG
    ]

    To decide if the noun filter disallows (obj - an object) (this is ConsultNounFilterToken):
        if the noun filter is currently a rule:
            now the noun is the obj;
            decide on whether or not the noun filter returns true;
        if the obj provides the property (noun filter as an adjective) directly, yes.

    [ ConsultNounFilterToken obj;
    if (token_filter ofclass Routine) {
         noun = obj;
    return indirect(token_filter);
    }
    if (obj has (token_filter-1)) rtrue;
    rfalse;
    ]