Original Parser

version 1 by Ron Newcomb

  • Home page
  • Beginning
  • Previous
  • Next



  • Chapter - SearchScope

    [Level 1. The method is:
    (a) If the context is a |scope=...| token, then the search is delegated
    to ``stage 2'' of the scope routine. This was the old I6 way to override
    the searching behaviour: while users probably won't be using it any more,
    the template does, in order to give testing commands universal scope which
    is exempt from the activity below; and the NI compiler creates |scope=...|
    tokens to handle Understand grammar such as ``[any room]''. So the feature
    remains very much still in use.
    (b) The ``deciding the scope of'' activity is given the chance to intervene.
    This is the I7 way to override the searching behaviour, and is the one taken
    by users.
    (c) And otherwise:
    (-1) The I6 |multiinside| token, used as the first noun of its grammar line,
    has as its scope all of the objects which are inside or on top of the
    {\it second} noun of the grammar line. This provides a neat scope for the
    ALL in a command like GET ALL FROM CUPBOARD, where the player clearly
    does not intend ALL to refer to the cupboard itself, for instance. The
    difficulty is that we don't yet know what the second object is, if we are
    parsing left to right. But the parser code above has taken care of all of
    that, and the |advance_warning| global is set to the object number of the
    second noun, or to $-1$ if that is not yet known. Note that we check that
    the contents are visible before adding them to scope, because otherwise
    an unscrupulous player could use such a command to detect the contents of
    an opaque locked box. If this rule applies, we skip (c.2), (c.3) and (c.4).
    (-2) For all other tokens except |creature|, searching scope for the room
    holding the current actor always catches the compass directions unless a
    definite article has already been typed. (Thus OPEN THE EAST would match
    an object called ``east door'', but not the compass direction ``east''.)
    (-3) The contents of |domain1| which are not contents of |domain2| are
    placed in scope, and so are any component parts of |domain1|. If |domain1|
    is a container or supporter, it is placed in scope itself.
    (-4) The contents and component parts of |domain2| are placed in scope.
    If |domain2| is a container or supporter, it is placed in scope itself.
    (-5) In darkness, the actor and his component parts are in scope. If the
    actor is inside or on top of something, then that thing is also in scope.
    (This avoids a situation where the player gets into an opaque box, then
    pulls it closed from the inside, plunging himself into darkness, then types
    OPEN BOX only to be told that he can't see any such thing.)]

    To search the scope of (first domain - an object) and (second domain - an object) under (context - a grammar token) (this is SearchScope):
        if the first domain is nothing, stop;
        [ Rule (a) - If the current scope limit is set by an understand token like Understand "[any room]" as... or one of those described in 25.22 of _Writing with Inform_ then invoke that phrase/function/routine. ]
        if the scope decider is not currently blank:
            now the scope stage is please add eligible objects to scope;
            if TRACE 3, say " [bracket]Scope routine called at stage 2[close bracket][line break]";
            if the scope decider returns true, stop the action;
        [ Rule (b) - The "deciding the scope" activity allows the I7 author their preferences now.]
        begin the deciding the scope activity with the person asked;
        if handling the deciding the scope activity with the person asked:
            [ Rule (c) - if the author has no special preferences, then the default is these five rules: ]
            [ Rule (c.1) - for GET ALL FROM CUPBOARD we place the contents of the second noun into scope, assuming we can see the contents (i.e. the second noun is a supporter, open container, transparent anything, etc.). ]
            if the reason for deciding scope is because we're parsing the predicate nouns and the context is 'things inside' and we suspect what the second noun will be:
                if the likely second noun is see-through:
                    place the contents of the likely second noun into scope excluding nothing under the context;
            otherwise:
                [ Rule (c.2) - For non-creatures, searching scope for the room containing the actor always catches the compass directions unless a definite article has already been typed. (Thus OPEN THE EAST would match "east door" but not the compass direction "east".)]
                if the reason for deciding scope is because we're parsing the predicate nouns and the context is not 'someone' and the indefinite article mode is false and the first domain is the actor's scopewise location:
                    place the contents of the compass in scope;
                [ Rule (c.3) - The contents of |domain1| which are not contents of |domain2| are placed in scope, and so are any component parts of |domain1|. If |domain1| is a container or supporter, itself is placed in scope.]
                if the first domain is a supporter or container:
                    do scope action on the first domain;
                place the contents of the first domain in scope excluding the second domain under the context;
                [ Rule (c.4) - The contents and component parts of |domain2| are placed in scope. If |domain2| is a container or supporter, it is placed in scope itself.]
                unless the second domain is nothing:
                    if the second domain is a supporter or container:
                        do scope action on the second domain;
                    place the contents of the second domain in scope excluding nothing under the context;
            [ Rule (c.5) - avoid the situation where the player gets into an opaque box, then pulls it closed from the inside, plunging himself into darkness, then types OPEN BOX only to be told that he can't see any such thing.]
            if the first domain is the ur-darkness or the second domain is the ur-darkness:
                recursively do scope action on the person asked excluding the person asked under the context;
                if the parent of the person asked is a supporter or container:
                    recursively do scope action on the parent of the person asked excluding the parent of the person asked under the context;
        end the deciding the scope activity with the person asked.

    [ SearchScope domain1 domain2 context i;
        if (domain1 == 0) return;
        ! (a)
    if (scope_token) {
    scope_stage = 2;
    #Ifdef DEBUG;
    if (parser_trace >= 3) print " [Scope routine called at stage 2]^";
    #Endif;
    if (indirect(scope_token) ~= 0) rtrue;
    }
        ! (b)
    BeginActivity(DECIDING_SCOPE_ACT, actor);
    if (ForActivity(DECIDING_SCOPE_ACT, actor) == false) {
            ! (c.1)
            if ((scope_reason == PARSING_REASON) && (context == MULTIINSIDE_TOKEN) &&
                (advance_warning ~= -1)) {
                if (IsSeeThrough(advance_warning) == 1)
                 ScopeWithin(advance_warning, 0, context);
            } else {
                ! (c.2)
                if ((scope_reason == PARSING_REASON) && (context ~= CREATURE_TOKEN) &&
                    (indef_mode == 0) && (domain1 == actors_location))
                        ScopeWithin(compass);
                ! (c.3)
                if (domain1 has supporter or container) DoScopeAction(domain1);
                ScopeWithin(domain1, domain2, context);
                ! (c.4)
                if (domain2) {
                    if (domain2 has supporter or container) DoScopeAction(domain2);
                    ScopeWithin(domain2, 0, context);
                }
            }
            ! (c.5)
            if (thedark == domain1 or domain2) {
                DoScopeActionAndRecurse(actor, actor, context);
                if (parent(actor) has supporter or container)
                    DoScopeActionAndRecurse(parent(actor), parent(actor), context);
            }
    }
    EndActivity(DECIDING_SCOPE_ACT, actor);
    ]