



ParseToken__ (lines 2244-2687)
Back to List
Browsing parserm.h
2244 [ ParseToken__ given_ttype given_tdata token_n
2245 token l o i j k and_parity single_object desc_wn many_flag
2246 token_allows_multiple prev_indef_wanted;
2247
2248 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2249 !
2250 ! A: Analyse token; handle all not involving object lists, break down others
2251 !
2252 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2253
2254 token_filter = 0;
2255
2256 switch (given_ttype) {
2257 ELEMENTARY_TT:
2258 switch (given_tdata) {
2259 SPECIAL_TOKEN:
2260 l = TryNumber(wn);
2261 special_word = NextWord();
2262 #Ifdef DEBUG;
2263 if (l ~= -1000)
2264 if (parser_trace >= 3) print " [Read special as the number ", l, "]^";
2265 #Endif; ! DEBUG
2266 if (l == -1000) {
2267 #Ifdef DEBUG;
2268 if (parser_trace >= 3) print " [Read special word at word number ", wn, "]^";
2269 #Endif; ! DEBUG
2270 l = special_word;
2271 }
2272 parsed_number = l; return GPR_NUMBER;
2273
2274 NUMBER_TOKEN:
2275 l=TryNumber(wn++);
2276 if (l == -1000) { etype = NUMBER_PE; return GPR_FAIL; }
2277 #Ifdef DEBUG;
2278 if (parser_trace>=3) print " [Read number as ", l, "]^";
2279 #Endif; ! DEBUG
2280 parsed_number = l; return GPR_NUMBER;
2281
2282 CREATURE_TOKEN:
2283 if (action_to_be == ##Answer or ##Ask or ##AskFor or ##Tell)
2284 scope_reason = TALKING_REASON;
2285
2286 TOPIC_TOKEN:
2287 consult_from = wn;
2288 if ((line_ttype-->(token_n+1) ~= PREPOSITION_TT) &&
2289 (line_token-->(token_n+1) ~= ENDIT_TOKEN))
2290 RunTimeError(13);
2291 do o = NextWordStopped();
2292 until (o == -1 || PrepositionChain(o, token_n+1) ~= -1);
2293 wn--;
2294 consult_words = wn-consult_from;
2295 if (consult_words == 0) return GPR_FAIL;
2296 if (action_to_be == ##Ask or ##Answer or ##Tell) {
2297 o = wn; wn = consult_from; parsed_number = NextWord();
2298 #Ifdef EnglishNaturalLanguage;
2299 if (parsed_number == 'the' && consult_words > 1) parsed_number=NextWord();
2300 #Endif; ! EnglishNaturalLanguage
2301 wn = o; return 1;
2302 }
2303 if (o==-1 && (line_ttype-->(token_n+1) == PREPOSITION_TT))
2304 return GPR_FAIL; ! don't infer if required preposition is absent
2305 return GPR_PREPOSITION;
2306 }
2307
2308 PREPOSITION_TT:
2309 #Iffalse (Grammar__Version == 1);
2310 ! Is it an unnecessary alternative preposition, when a previous choice
2311 ! has already been matched?
2312 if ((token->0) & $10) return GPR_PREPOSITION;
2313 #Endif; ! Grammar__Version
2314
2315 ! If we've run out of the player's input, but still have parameters to
2316 ! specify, we go into "infer" mode, remembering where we are and the
2317 ! preposition we are inferring...
2318
2319 if (wn > num_words) {
2320 if (inferfrom==0 && parameters<params_wanted) {
2321 inferfrom = pcount; inferword = token;
2322 pattern-->pcount = REPARSE_CODE + Dword__No(given_tdata);
2323 }
2324
2325 ! If we are not inferring, then the line is wrong...
2326
2327 if (inferfrom == 0) return -1;
2328
2329 ! If not, then the line is right but we mark in the preposition...
2330
2331 pattern-->pcount = REPARSE_CODE + Dword__No(given_tdata);
2332 return GPR_PREPOSITION;
2333 }
2334
2335 o = NextWord();
2336
2337 pattern-->pcount = REPARSE_CODE + Dword__No(o);
2338
2339 ! Whereas, if the player has typed something here, see if it is the
2340 ! required preposition... if it's wrong, the line must be wrong,
2341 ! but if it's right, the token is passed (jump to finish this token).
2342
2343 if (o == given_tdata) return GPR_PREPOSITION;
2344 #Iffalse (Grammar__Version == 1);
2345 if (PrepositionChain(o, token_n) ~= -1) return GPR_PREPOSITION;
2346 #Endif; ! Grammar__Version
2347 return -1;
2348
2349 GPR_TT:
2350 l = indirect(given_tdata);
2351 #Ifdef DEBUG;
2352 if (parser_trace >= 3) print " [Outside parsing routine returned ", l, "]^";
2353 #Endif; ! DEBUG
2354 return l;
2355
2356 SCOPE_TT:
2357 scope_token = given_tdata;
2358 scope_stage = 1;
2359 l = indirect(scope_token);
2360 #Ifdef DEBUG;
2361 if (parser_trace >= 3) print " [Scope routine returned multiple-flag of ", l, "]^";
2362 #Endif; ! DEBUG
2363 if (l == 1) given_tdata = MULTI_TOKEN; else given_tdata = NOUN_TOKEN;
2364
2365 ATTR_FILTER_TT:
2366 token_filter = 1 + given_tdata;
2367 given_tdata = NOUN_TOKEN;
2368
2369 ROUTINE_FILTER_TT:
2370 token_filter = given_tdata;
2371 given_tdata = NOUN_TOKEN;
2372
2373 } ! end of switch(given_ttype)
2374
2375 token = given_tdata;
2376
2377 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2378 !
2379 ! B: Begin parsing an object list
2380 !
2381 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2382
2383 ! There are now three possible ways we can be here:
2384 ! parsing an elementary token other than "special" or "number";
2385 ! parsing a scope token;
2386 ! parsing a noun-filter token (either by routine or attribute).
2387 !
2388 ! In each case, token holds the type of elementary parse to
2389 ! perform in matching one or more objects, and
2390 ! token_filter is 0 (default), an attribute + 1 for an attribute filter
2391 ! or a routine address for a routine filter.
2392
2393 token_allows_multiple = false;
2394 if (token == MULTI_TOKEN or MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN or MULTIINSIDE_TOKEN)
2395 token_allows_multiple = true;
2396
2397 many_flag = false; and_parity = true; dont_infer = false;
2398
2399 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2400 !
2401 ! C: Parse descriptors (articles, pronouns, etc.) in the list
2402 !
2403 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2404
2405 ! We expect to find a list of objects next in what the player's typed.
2406
2407 .ObjectList;
2408
2409 #Ifdef DEBUG;
2410 if (parser_trace >= 3) print " [Object list from word ", wn, "]^";
2411 #Endif; ! DEBUG
2412
2413 ! Take an advance look at the next word: if it's "it" or "them", and these
2414 ! are unset, set the appropriate error number and give up on the line
2415 ! (if not, these are still parsed in the usual way - it is not assumed
2416 ! that they still refer to something in scope)
2417
2418 o = NextWord(); wn--;
2419
2420 pronoun_word = NULL; pronoun_obj = NULL;
2421 l = PronounValue(o);
2422 if (l ~= 0) {
2423 pronoun_word = o; pronoun_obj = l;
2424 if (l == NULL) {
2425 ! Don't assume this is a use of an unset pronoun until the
2426 ! descriptors have been checked, because it might be an
2427 ! article (or some such) instead
2428
2429 for (l=1 : l<=LanguageDescriptors-->0 : l=l+4)
2430 if (o == LanguageDescriptors-->l) jump AssumeDescriptor;
2431 pronoun__word = pronoun_word; pronoun__obj = pronoun_obj;
2432 etype = VAGUE_PE; return GPR_FAIL;
2433 }
2434 }
2435
2436 .AssumeDescriptor;
2437
2438 if (o == ME1__WD or ME2__WD or ME3__WD) { pronoun_word = o; pronoun_obj = player; }
2439
2440 allow_plurals = true; desc_wn = wn;
2441
2442 .TryAgain;
2443
2444 ! First, we parse any descriptive words (like "the", "five" or "every"):
2445 l = Descriptors();
2446 if (l ~= 0) { etype = l; return GPR_FAIL; }
2447
2448 .TryAgain2;
2449
2450 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2451 !
2452 ! D: Parse an object name
2453 !
2454 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2455
2456 ! This is an actual specified object, and is therefore where a typing error
2457 ! is most likely to occur, so we set:
2458
2459 oops_from = wn;
2460
2461 ! So, two cases. Case 1: token not equal to "held" (so, no implicit takes)
2462 ! but we may well be dealing with multiple objects
2463
2464 ! In either case below we use NounDomain, giving it the token number as
2465 ! context, and two places to look: among the actor's possessions, and in the
2466 ! present location. (Note that the order depends on which is likeliest.)
2467
2468 if (token ~= HELD_TOKEN) {
2469 i = multiple_object-->0;
2470 #Ifdef DEBUG;
2471 if (parser_trace >= 3) print " [Calling NounDomain on location and actor]^";
2472 #Endif; ! DEBUG
2473 l = NounDomain(actors_location, actor, token);
2474 if (l == REPARSE_CODE) return l; ! Reparse after Q&A
2475 if (indef_wanted == 100 && l == 0 && number_matched == 0)
2476 l = 1; ! ReviseMulti if TAKE ALL FROM empty container
2477
2478 if (token_allows_multiple && ~~multiflag) {
2479 if (best_etype==MULTI_PE) best_etype=STUCK_PE;
2480 multiflag = true;
2481 }
2482 if (l == 0) {
2483 if (indef_possambig) {
2484 ResetDescriptors();
2485 wn = desc_wn;
2486 jump TryAgain2;
2487 }
2488 if (etype == MULTI_PE or TOOFEW_PE && multiflag) etype = STUCK_PE;
2489 etype=CantSee();
2490 jump FailToken;
2491 } ! Choose best error
2492
2493 #Ifdef DEBUG;
2494 if (parser_trace >= 3) {
2495 if (l > 1) print " [ND returned ", (the) l, "]^";
2496 else {
2497 print " [ND appended to the multiple object list:^";
2498 k = multiple_object-->0;
2499 for (j=i+1 : j<=k : j++)
2500 print " Entry ", j, ": ", (The) multiple_object-->j,
2501 " (", multiple_object-->j, ")^";
2502 print " List now has size ", k, "]^";
2503 }
2504 }
2505 #Endif; ! DEBUG
2506
2507 if (l == 1) {
2508 if (~~many_flag) many_flag = true;
2509 else { ! Merge with earlier ones
2510 k = multiple_object-->0; ! (with either parity)
2511 multiple_object-->0 = i;
2512 for (j=i+1 : j<=k : j++) {
2513 if (and_parity) MultiAdd(multiple_object-->j);
2514 else MultiSub(multiple_object-->j);
2515 }
2516 #Ifdef DEBUG;
2517 if (parser_trace >= 3) print " [Merging ", k-i, " new objects to the ", i, " old ones]^";
2518 #Endif; ! DEBUG
2519 }
2520 }
2521 else {
2522 ! A single object was indeed found
2523
2524 if (match_length == 0 && indef_possambig) {
2525 ! So the answer had to be inferred from no textual data,
2526 ! and we know that there was an ambiguity in the descriptor
2527 ! stage (such as a word which could be a pronoun being
2528 ! parsed as an article or possessive). It's worth having
2529 ! another go.
2530
2531 ResetDescriptors();
2532 wn = desc_wn;
2533 jump TryAgain2;
2534 }
2535
2536 if (token == CREATURE_TOKEN && CreatureTest(l) == 0) {
2537 etype = ANIMA_PE;
2538 jump FailToken;
2539 } ! Animation is required
2540
2541 if (~~many_flag) single_object = l;
2542 else {
2543 if (and_parity) MultiAdd(l); else MultiSub(l);
2544 #Ifdef DEBUG;
2545 if (parser_trace >= 3) print " [Combining ", (the) l, " with list]^";
2546 #Endif; ! DEBUG
2547 }
2548 }
2549 }
2550
2551 else {
2552
2553 ! Case 2: token is "held" (which fortunately can't take multiple objects)
2554 ! and may generate an implicit take
2555
2556 l = NounDomain(actor,actors_location,token); ! Same as above...
2557 if (l == REPARSE_CODE) return GPR_REPARSE;
2558 if (l == 0) {
2559 if (indef_possambig) {
2560 ResetDescriptors();
2561 wn = desc_wn;
2562 jump TryAgain2;
2563 }
2564 etype = CantSee(); jump FailToken; ! Choose best error
2565 }
2566
2567 ! ...until it produces something not held by the actor. Then an implicit
2568 ! take must be tried. If this is already happening anyway, things are too
2569 ! confused and we have to give up (but saving the oops marker so as to get
2570 ! it on the right word afterwards).
2571 ! The point of this last rule is that a sequence like
2572 !
2573 ! > read newspaper
2574 ! (taking the newspaper first)
2575 ! The dwarf unexpectedly prevents you from taking the newspaper!
2576 !
2577 ! should not be allowed to go into an infinite repeat - read becomes
2578 ! take then read, but take has no effect, so read becomes take then read...
2579 ! Anyway for now all we do is record the number of the object to take.
2580
2581 o = parent(l);
2582 if (o ~= actor) {
2583 if (notheld_mode == 1) {
2584 saved_oops = oops_from;
2585 etype = NOTHELD_PE;
2586 jump FailToken;
2587 }
2588 not_holding = l;
2589 #Ifdef DEBUG;
2590 if (parser_trace >= 3) print " [Allowing object ", (the) l, " for now]^";
2591 #Endif; ! DEBUG
2592 }
2593 single_object = l;
2594 } ! end of if (token ~= HELD_TOKEN) else
2595
2596 ! The following moves the word marker to just past the named object...
2597
2598 wn = oops_from + match_length;
2599
2600 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2601 !
2602 ! E: Parse connectives ("and", "but", etc.) and go back to (C)
2603 !
2604 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2605
2606 ! Object(s) specified now: is that the end of the list, or have we reached
2607 ! "and", "but" and so on? If so, create a multiple-object list if we
2608 ! haven't already (and are allowed to).
2609
2610 .NextInList;
2611
2612 o = NextWord();
2613
2614 if (o == AND1__WD or AND2__WD or AND3__WD or BUT1__WD or BUT2__WD or BUT3__WD or comma_word) {
2615
2616 #Ifdef DEBUG;
2617 if (parser_trace >= 3) print " [Read connective '", (address) o, "']^";
2618 #Endif; ! DEBUG
2619
2620 if (~~token_allows_multiple) {
2621 if (multiflag) jump PassToken; ! give UPTO_PE error
2622 etype=MULTI_PE;
2623 jump FailToken;
2624 }
2625
2626 if (o == BUT1__WD or BUT2__WD or BUT3__WD) and_parity = 1-and_parity;
2627
2628 if (~~many_flag) {
2629 multiple_object-->0 = 1;
2630 multiple_object-->1 = single_object;
2631 many_flag = true;
2632 #Ifdef DEBUG;
2633 if (parser_trace >= 3) print " [Making new list from ", (the) single_object, "]^";
2634 #Endif; ! DEBUG
2635 }
2636 dont_infer = true; inferfrom=0; ! Don't print (inferences)
2637 jump ObjectList; ! And back around
2638 }
2639
2640 wn--; ! Word marker back to first not-understood word
2641
2642 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2643 !
2644 ! F: Return the conclusion of parsing an object list
2645 !
2646 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2647
2648 ! Happy or unhappy endings:
2649
2650 .PassToken;
2651
2652 if (many_flag) {
2653 single_object = GPR_MULTIPLE;
2654 multi_context = token;
2655 }
2656 else {
2657 if (indef_mode == 1 && indef_type & PLURAL_BIT ~= 0) {
2658 if (indef_wanted < 100 && indef_wanted > 1) {
2659 multi_had = 1; multi_wanted = indef_wanted;
2660 etype = TOOFEW_PE;
2661 jump FailToken;
2662 }
2663 }
2664 }
2665 return single_object;
2666
2667 .FailToken;
2668
2669 ! If we were only guessing about it being a plural, try again but only
2670 ! allowing singulars (so that words like "six" are not swallowed up as
2671 ! Descriptors)
2672
2673 if (allow_plurals && indef_guess_p == 1) {
2674 #Ifdef DEBUG;
2675 if (parser_trace >= 4) print " [Retrying singulars after failure ", etype, "]^";
2676 #Endif;
2677 prev_indef_wanted = indef_wanted;
2678 allow_plurals = false;
2679 wn = desc_wn;
2680 jump TryAgain;
2681 }
2682
2683 if ((indef_wanted > 0 || prev_indef_wanted > 0) && (~~multiflag)) etype = MULTI_PE;
2684
2685 return GPR_FAIL;
2686
2687 ]; ! end of ParseToken__
Last updated 27 February 2004. The librarian in charge of this page is Graham Nelson (graham@gnelson.demon.co.uk) assisted by C Knight. Please email any comments, suggestions or corrections to cedenqs@inform-fiction.org.