Inform - Support - Patches

About Patches  

Compiler  
Library  

DM4 Errata  

Issue L61127     [previous patch]

Improve multiexcept look-ahead
Submitted by: Jesse McGrew     Appeared in: Library 6/11 or before     Fixed in: -
Problem

When the parser processes a grammar line that uses multiexcept or multiinside, it jumps ahead to match the second noun in order to provide context for the first one. However, in doing so, it skips over all the prepositions in the input, without caring whether they match the prepositions in the grammar line. If the second noun is ambiguous, this means the player may be asked a disambiguation question for a grammar line that has no chance of succeeding, whereas the grammar line that eventually succeeds might not even need disambiguation (thanks to a different token type or ChooseObjects).

Solution

This patch modifies look-ahead to match the prepositions along the way to finding the second noun, instead of skipping over them. If the prepositions don't match, the parser moves on to the next line immediately.

(The patch also resolves L61120.)

*** parserm.h.orig	Thu Jan  4 16:33:14 2007
--- parserm.h	Thu Jan  4 16:34:19 2007
***************
*** 1841,1873 ****

                      pcount++;
                      if (line_ttype-->pcount == PREPOSITION_TT) {
!                         while (line_ttype-->pcount == PREPOSITION_TT) pcount++;

                          if ((line_ttype-->pcount == ELEMENTARY_TT) && (line_tdata-->pcount == NOUN_TOKEN)) {
!
!                             ! Advance past the last preposition
!
!                             while (wn < num_words) {
!                                 l=NextWord();
!                                 if ( l && (l->#dict_par1) &8 ) {   ! if preposition
!                                     if (l == ALL1__WD or ALL2__WD or ALL3__WD or
!                                         ALL4__WD or ALL5__WD) continue;
!                                     l = Descriptors();  ! skip past THE etc
!                                     if (l~=0) etype=l;  ! don't allow multiple objects
!                                     l = NounDomain(actors_location, actor, NOUN_TOKEN);
!                                     #Ifdef DEBUG;
!                                     if (parser_trace >= 2) {
!                                         print " [Advanced to ~noun~ token: ";
!                                         if (l == REPARSE_CODE) print "re-parse request]^";
!                                         if (l == 1) print "but multiple found]^";
!                                         if (l == 0) print "error ", etype, "]^";
!                                         if (l >= 2) print (the) l, "]^";
!                                     }
!                                     #Endif; ! DEBUG
!                                     if (l == REPARSE_CODE) jump ReParse;
!                                     if (l >= 2) advance_warning = l;
!                                 }
                              }
                          }
                      }
                      break;
--- 1841,1908 ----

                      pcount++;
                      if (line_ttype-->pcount == PREPOSITION_TT) {
!                         ! skip ahead to a preposition word in the input
!                         do {
!                             l = NextWord();
!                         } until ((wn > num_words) ||
!                                  (l && (l->#dict_par1) & 8 ~= 0));
!
!                         if (wn > num_words) {
!                             #Ifdef DEBUG;
!                             if (parser_trace >= 2)
!                                 print " [Look-ahead aborted: prepositions missing]^";
!                             #Endif;
!                             jump LineFailed;
!                         }
!
!                         do {
!                             if (PrepositionChain(l, pcount) ~= -1) {
!                                 ! advance past the chain
!                                 if ((line_token-->pcount)->0 & $20 ~= 0) {
!                                     pcount++;
!                                     while ((line_token-->pcount ~= ENDIT_TOKEN) &&
!                                            ((line_token-->pcount)->0 & $10 ~= 0))
!                                         pcount++;
!                                 } else {
!                                     pcount++;
!                                 }
!                             } else {
!                                 ! try to find another preposition word
!                                 do {
!                                     l = NextWord();
!                                 } until ((wn >= num_words) ||
!                                          (l && (l->#dict_par1) & 8 ~= 0));
!
!                                 if (l && (l->#dict_par1) & 8) continue;
!
!                                 ! lookahead failed
!                                 #Ifdef DEBUG;
!                                 if (parser_trace >= 2)
!                                     print " [Look-ahead aborted: prepositions don't match]^";
!                                 #endif;
!                                 jump LineFailed;
!                             }
!                             l = NextWord();
!                         } until (line_ttype-->pcount ~= PREPOSITION_TT);
!
!                         ! put back the non-preposition we just read
!                         wn--;

                          if ((line_ttype-->pcount == ELEMENTARY_TT) && (line_tdata-->pcount == NOUN_TOKEN)) {
!                             l = Descriptors();  ! skip past THE etc
!                             if (l~=0) etype=l;  ! don't allow multiple objects
!                             l = NounDomain(actors_location, actor, NOUN_TOKEN);
!                             #Ifdef DEBUG;
!                             if (parser_trace >= 2) {
!                                 print " [Advanced to ~noun~ token: ";
!                                 if (l == REPARSE_CODE) print "re-parse request]^";
!                                 if (l == 1) print "but multiple found]^";
!                                 if (l == 0) print "error ", etype, "]^";
!                                 if (l >= 2) print (the) l, "]^";
                              }
+                             #Endif; ! DEBUG
+                             if (l == REPARSE_CODE) jump ReParse;
+                             if (l >= 2) advance_warning = l;
                          }
                      }
                      break;
***************
*** 2098,2103 ****
--- 2133,2139 ----
              } ! end of if(token ~= ENDIT_TOKEN) else
          } ! end of for(pcount++)

+         .LineFailed;
          ! The line has failed to match.
          ! We continue the outer "for" loop, trying the next line in the grammar.


Last updated 2 May 2008. The librarian in charge of this page is Roger Firth. Please email any comments, suggestions or corrections to roger@firthworks.com.