



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). 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.)
About Patches
Issue L61127 [previous patch]
Improve multiexcept look-ahead
Submitted by: Jesse McGrew
Appeared in: Library 6/11 or before
Fixed in: -
Problem
Solution
*** 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.