ParseToken__ (lines 1601-1999)
Back to List
Browsing parserm.h
1601 [ ParseToken__ given_ttype given_tdata token_n
1602 token l o i j k and_parity single_object desc_wn many_flag
1603 token_allows_multiple;
1604
1605 ! **** (A) ****
1606
1607 token_filter = 0;
1608
1609 switch(given_ttype)
1610 { ELEMENTARY_TT:
1611 switch(given_tdata)
1612 { SPECIAL_TOKEN:
1613 l=TryNumber(wn);
1614 special_word=NextWord();
1615 #ifdef DEBUG;
1616 if (l~=-1000)
1617 if (parser_trace>=3)
1618 print " [Read special as the number ", l, "]^";
1619 #endif;
1620 if (l==-1000)
1621 { #ifdef DEBUG;
1622 if (parser_trace>=3)
1623 print " [Read special word at word number ", wn, "]^";
1624 #endif;
1625 l = special_word;
1626 }
1627 parsed_number = l; return GPR_NUMBER;
1628
1629 NUMBER_TOKEN:
1630 l=TryNumber(wn++);
1631 if (l==-1000) { etype=NUMBER_PE; return GPR_FAIL; }
1632 #ifdef DEBUG;
1633 if (parser_trace>=3) print " [Read number as ", l, "]^";
1634 #endif;
1635 parsed_number = l; return GPR_NUMBER;
1636
1637 CREATURE_TOKEN:
1638 if (action_to_be==##Answer or ##Ask or ##AskFor or ##Tell)
1639 scope_reason = TALKING_REASON;
1640
1641 TOPIC_TOKEN:
1642 consult_from = wn;
1643 if ((line_ttype-->(token_n+1) ~= PREPOSITION_TT)
1644 && (line_token-->(token_n+1) ~= ENDIT_TOKEN))
1645 RunTimeError(13);
1646 do o=NextWordStopped();
1647 until (o==-1 || PrepositionChain(o, token_n+1) ~= -1);
1648 wn--;
1649 consult_words = wn-consult_from;
1650 if (consult_words==0) return GPR_FAIL;
1651 if (action_to_be==##Ask or ##Answer or ##Tell)
1652 { o=wn; wn=consult_from; parsed_number=NextWord();
1653 #IFDEF EnglishNaturalLanguage;
1654 if (parsed_number=='the' && consult_words>1)
1655 parsed_number=NextWord();
1656 #ENDIF;
1657 wn=o; return 1;
1658 }
1659 return GPR_PREPOSITION;
1660 }
1661
1662 PREPOSITION_TT:
1663 #Iffalse Grammar__Version==1;
1664 ! Is it an unnecessary alternative preposition, when a previous choice
1665 ! has already been matched?
1666 if ((token->0) & $10) return GPR_PREPOSITION;
1667 #Endif;
1668
1669 ! If we've run out of the player's input, but still have parameters to
1670 ! specify, we go into "infer" mode, remembering where we are and the
1671 ! preposition we are inferring...
1672
1673 if (wn > num_words)
1674 { if (inferfrom==0 && parameters<params_wanted)
1675 { inferfrom = pcount; inferword = token;
1676 pattern-->pcount = REPARSE_CODE + Dword__No(given_tdata);
1677 }
1678
1679 ! If we are not inferring, then the line is wrong...
1680
1681 if (inferfrom==0) return -1;
1682
1683 ! If not, then the line is right but we mark in the preposition...
1684
1685 pattern-->pcount = REPARSE_CODE + Dword__No(given_tdata);
1686 return GPR_PREPOSITION;
1687 }
1688
1689 o = NextWord();
1690
1691 pattern-->pcount = REPARSE_CODE + Dword__No(o);
1692
1693 ! Whereas, if the player has typed something here, see if it is the
1694 ! required preposition... if it's wrong, the line must be wrong,
1695 ! but if it's right, the token is passed (jump to finish this token).
1696
1697 if (o == given_tdata) return GPR_PREPOSITION;
1698 #Iffalse Grammar__Version==1;
1699 if (PrepositionChain(o, token_n) ~= -1)
1700 return GPR_PREPOSITION;
1701 #Endif;
1702 return -1;
1703
1704 GPR_TT:
1705 l=indirect(given_tdata);
1706 #ifdef DEBUG;
1707 if (parser_trace>=3)
1708 print " [Outside parsing routine returned ", l, "]^";
1709 #endif;
1710 return l;
1711
1712 SCOPE_TT:
1713 scope_token = given_tdata;
1714 scope_stage = 1;
1715 l = indirect(scope_token);
1716 #ifdef DEBUG;
1717 if (parser_trace>=3)
1718 print " [Scope routine returned multiple-flag of ", l, "]^";
1719 #endif;
1720 if (l==1) given_tdata = MULTI_TOKEN; else given_tdata = NOUN_TOKEN;
1721
1722 ATTR_FILTER_TT:
1723 token_filter = 1 + given_tdata;
1724 given_tdata = NOUN_TOKEN;
1725
1726 ROUTINE_FILTER_TT:
1727 token_filter = given_tdata;
1728 given_tdata = NOUN_TOKEN;
1729 }
1730
1731 token = given_tdata;
1732
1733 ! **** (B) ****
1734
1735 ! There are now three possible ways we can be here:
1736 ! parsing an elementary token other than "special" or "number";
1737 ! parsing a scope token;
1738 ! parsing a noun-filter token (either by routine or attribute).
1739 !
1740 ! In each case, token holds the type of elementary parse to
1741 ! perform in matching one or more objects, and
1742 ! token_filter is 0 (default), an attribute + 1 for an attribute filter
1743 ! or a routine address for a routine filter.
1744
1745 token_allows_multiple = false;
1746 if (token == MULTI_TOKEN or MULTIHELD_TOKEN or MULTIEXCEPT_TOKEN
1747 or MULTIINSIDE_TOKEN) token_allows_multiple = true;
1748
1749 many_flag = false; and_parity = true; dont_infer = false;
1750
1751 ! **** (C) ****
1752 ! We expect to find a list of objects next in what the player's typed.
1753
1754 .ObjectList;
1755
1756 #ifdef DEBUG;
1757 if (parser_trace>=3) print " [Object list from word ", wn, "]^";
1758 #endif;
1759
1760 ! Take an advance look at the next word: if it's "it" or "them", and these
1761 ! are unset, set the appropriate error number and give up on the line
1762 ! (if not, these are still parsed in the usual way - it is not assumed
1763 ! that they still refer to something in scope)
1764
1765 o=NextWord(); wn--;
1766
1767 pronoun_word = NULL; pronoun_obj = NULL;
1768 l = PronounValue(o);
1769 if (l ~= 0)
1770 { pronoun_word = o; pronoun_obj = l;
1771 if (l == NULL)
1772 { ! Don't assume this is a use of an unset pronoun until the
1773 ! descriptors have been checked, because it might be an
1774 ! article (or some such) instead
1775
1776 for (l=1:l<=LanguageDescriptors-->0:l=l+4)
1777 if (o == LanguageDescriptors-->l) jump AssumeDescriptor;
1778 pronoun__word=pronoun_word; pronoun__obj=pronoun_obj;
1779 etype=VAGUE_PE; return GPR_FAIL;
1780 }
1781 }
1782
1783 .AssumeDescriptor;
1784
1785 if (o==ME1__WD or ME2__WD or ME3__WD)
1786 { pronoun_word = o; pronoun_obj = player;
1787 }
1788
1789 allow_plurals = true; desc_wn = wn;
1790
1791 .TryAgain;
1792 ! First, we parse any descriptive words (like "the", "five" or "every"):
1793 l = Descriptors(token_allows_multiple);
1794 if (l~=0) { etype=l; return GPR_FAIL; }
1795
1796 .TryAgain2;
1797
1798 ! **** (D) ****
1799
1800 ! This is an actual specified object, and is therefore where a typing error
1801 ! is most likely to occur, so we set:
1802
1803 oops_from = wn;
1804
1805 ! So, two cases. Case 1: token not equal to "held" (so, no implicit takes)
1806 ! but we may well be dealing with multiple objects
1807
1808 ! In either case below we use NounDomain, giving it the token number as
1809 ! context, and two places to look: among the actor's possessions, and in the
1810 ! present location. (Note that the order depends on which is likeliest.)
1811
1812 if (token ~= HELD_TOKEN)
1813 { i=multiple_object-->0;
1814 #ifdef DEBUG;
1815 if (parser_trace>=3)
1816 print " [Calling NounDomain on location and actor]^";
1817 #endif;
1818 l=NounDomain(actors_location, actor, token);
1819 if (l==REPARSE_CODE) return l; ! Reparse after Q&A
1820 if (l==0) { if (indef_possambig)
1821 { ResetDescriptors(); wn = desc_wn; jump TryAgain2; }
1822 etype=CantSee(); jump FailToken; } ! Choose best error
1823
1824 #ifdef DEBUG;
1825 if (parser_trace>=3)
1826 { if (l>1)
1827 print " [ND returned ", (the) l, "]^";
1828 else
1829 { print " [ND appended to the multiple object list:^";
1830 k=multiple_object-->0;
1831 for (j=i+1:j<=k:j++)
1832 print " Entry ", j, ": ", (The) multiple_object-->j,
1833 " (", multiple_object-->j, ")^";
1834 print " List now has size ", k, "]^";
1835 }
1836 }
1837 #endif;
1838
1839 if (l==1)
1840 { if (~~many_flag)
1841 { many_flag = true;
1842 }
1843 else ! Merge with earlier ones
1844 { k=multiple_object-->0; ! (with either parity)
1845 multiple_object-->0 = i;
1846 for (j=i+1:j<=k:j++)
1847 { if (and_parity) MultiAdd(multiple_object-->j);
1848 else MultiSub(multiple_object-->j);
1849 }
1850 #ifdef DEBUG;
1851 if (parser_trace>=3)
1852 print " [Merging ", k-i, " new objects to the ",
1853 i, " old ones]^";
1854 #endif;
1855 }
1856 }
1857 else
1858 { ! A single object was indeed found
1859
1860 if (match_length == 0 && indef_possambig)
1861 { ! So the answer had to be inferred from no textual data,
1862 ! and we know that there was an ambiguity in the descriptor
1863 ! stage (such as a word which could be a pronoun being
1864 ! parsed as an article or possessive). It's worth having
1865 ! another go.
1866
1867 ResetDescriptors(); wn = desc_wn; jump TryAgain2;
1868 }
1869
1870 if (token==CREATURE_TOKEN && CreatureTest(l)==0)
1871 { etype=ANIMA_PE; jump FailToken; } ! Animation is required
1872
1873 if (~~many_flag)
1874 single_object = l;
1875 else
1876 { if (and_parity) MultiAdd(l); else MultiSub(l);
1877 #ifdef DEBUG;
1878 if (parser_trace>=3)
1879 print " [Combining ", (the) l, " with list]^";
1880 #endif;
1881 }
1882 }
1883 }
1884
1885 ! Case 2: token is "held" (which fortunately can't take multiple objects)
1886 ! and may generate an implicit take
1887
1888 else
1889
1890 { l=NounDomain(actor,actors_location,token); ! Same as above...
1891 if (l==REPARSE_CODE) return GPR_REPARSE;
1892 if (l==0)
1893 { if (indef_possambig)
1894 { ResetDescriptors(); wn = desc_wn; jump TryAgain2; }
1895 etype=CantSee(); return GPR_FAIL; ! Choose best error
1896 }
1897
1898 ! ...until it produces something not held by the actor. Then an implicit
1899 ! take must be tried. If this is already happening anyway, things are too
1900 ! confused and we have to give up (but saving the oops marker so as to get
1901 ! it on the right word afterwards).
1902 ! The point of this last rule is that a sequence like
1903 !
1904 ! > read newspaper
1905 ! (taking the newspaper first)
1906 ! The dwarf unexpectedly prevents you from taking the newspaper!
1907 !
1908 ! should not be allowed to go into an infinite repeat - read becomes
1909 ! take then read, but take has no effect, so read becomes take then read...
1910 ! Anyway for now all we do is record the number of the object to take.
1911
1912 o=parent(l);
1913 if (o~=actor)
1914 { if (notheld_mode==1)
1915 { saved_oops=oops_from; etype=NOTHELD_PE; jump FailToken;
1916 }
1917 not_holding = l;
1918 #ifdef DEBUG;
1919 if (parser_trace>=3)
1920 print " [Allowing object ", (the) l, " for now]^";
1921 #endif;
1922 }
1923 single_object = l;
1924 }
1925
1926 ! The following moves the word marker to just past the named object...
1927
1928 wn = oops_from + match_length;
1929
1930 ! **** (E) ****
1931
1932 ! Object(s) specified now: is that the end of the list, or have we reached
1933 ! "and", "but" and so on? If so, create a multiple-object list if we
1934 ! haven't already (and are allowed to).
1935
1936 .NextInList;
1937
1938 o=NextWord();
1939
1940 if (o==AND1__WD or AND2__WD or AND3__WD or BUT1__WD or BUT2__WD or BUT3__WD
1941 or comma_word)
1942 {
1943 #ifdef DEBUG;
1944 if (parser_trace>=3) print " [Read connective '", (address) o, "']^";
1945 #endif;
1946
1947 if (~~token_allows_multiple)
1948 { etype=MULTI_PE; jump FailToken;
1949 }
1950
1951 if (o==BUT1__WD or BUT2__WD or BUT3__WD) and_parity = 1-and_parity;
1952
1953 if (~~many_flag)
1954 { multiple_object-->0 = 1;
1955 multiple_object-->1 = single_object;
1956 many_flag = true;
1957 #ifdef DEBUG;
1958 if (parser_trace>=3)
1959 print " [Making new list from ", (the) single_object, "]^";
1960 #endif;
1961 }
1962 dont_infer = true; inferfrom=0; ! Don't print (inferences)
1963 jump ObjectList; ! And back around
1964 }
1965
1966 wn--; ! Word marker back to first not-understood word
1967
1968 ! **** (F) ****
1969
1970 ! Happy or unhappy endings:
1971
1972 .PassToken;
1973
1974 if (many_flag)
1975 { single_object = GPR_MULTIPLE;
1976 multi_context = token;
1977 }
1978 else
1979 { if (indef_mode==1 && indef_type & PLURAL_BIT ~= 0)
1980 { if (indef_wanted<100 && indef_wanted>1)
1981 { multi_had=1; multi_wanted=indef_wanted;
1982 etype=TOOFEW_PE;
1983 jump FailToken;
1984 }
1985 }
1986 }
1987 return single_object;
1988
1989 .FailToken;
1990
1991 ! If we were only guessing about it being a plural, try again but only
1992 ! allowing singulars (so that words like "six" are not swallowed up as
1993 ! Descriptors)
1994
1995 if (allow_plurals && indef_guess_p==1)
1996 { allow_plurals=false; wn=desc_wn; jump TryAgain;
1997 }
1998 return -1;
1999 ];
Last updated 27 February 2004.
This site is no longer supported; information may be out of date.
Maintained as a historical archive by the Interactive Fiction Technology Foundation.
Copyright 1993-2018 IFTF, CC-BY-SA unless otherwise noted.
This page was originally managed by Graham Nelson (graham@gnelson.demon.co.uk) assisted by C Knight.