parse_command(3) MudOS (5 Sep 1994) parse_command(3)
名称:
parse_command() - 尝试以给定样式(pattern)来配对一个字串
语法:
int parse_command( string command, object env|object *oblist,
string pattern, mixed arg, ... );
整数 parse_command( 字串 command, 物件 env|物件 *oblist,
字串 pattern, 混合 arg, ... );
用法:
parse_command() 是透过操作在字串上 sscanf(3) 的。它的运作类
似於有一个样式和一个目的参数之变数集合的 sscanf(3)。它以传递
其他变数的参照(refence)和阵列的方式,结合唯一的超越函式(efun)
sscanf(3)。因此,parse_command() 将传回值置於它的参数上。
若 'command' 配对成功,parse_command() 会传回 1。
参数 'env' 或是 'oblist' 不是一个物件就会是一个物件阵列。如
果它是单一物件的话,它将会以增加此物件的 deep_inventory 方式
来自动建立一个物件阵列,例如下面这二个函式是等效的:
parse_command(cmd, environment(), pattern, arg)
和
parse_command( cmd, ({ environment() }) +
deep_inventory(environment()), pattern, arg)
假设有一个字串是 " 'get' / 'take' %i "
语法:
'word' 必备的文字(text)
[word] 可省略的文字
/ 选择性的记号(marker)
%o 单一项目(item), 物件
%l 生物(living object)
%s 任何文字
%w 任何单字(word)
%p 串列(list) (介系词)
%i 任何项目
%d 数字 0- 或是 tx(0-99)
'arg' 串列可以是零个或是多个参数。这些是如同 sscanf 内的结果
变数。注意到每一个变数都需要一个 %。
不同 %_ 的传回型态是:
%o 传回一个物件
%s 传回单字的字串
%w 传回单一单字的字串
%p 可以是一个含有单字串列的阵列或是一个
空变数
传回:
如果是空变数:一个字串
如果是阵列:array[0] 就是配对的单字
%i 传回一个下列格式的特定阵列:
[0] = (int) +(wanted) -(order) 0(all)
[1..n] (object) 物件指标(objectpointers)
%l 传回一个下列格式的特定阵列:
[0] = (int) +(wanted) -(order) 0(all)
[1..n] (object) 物件指标
这些都是生物。
%d 传回一个数值
用到所有已载入资讯的 % 型态只有 %i 和 %l。事实上,除了 %l 在
尝试剖析(parse)前会从所有物件串列中过滤掉非生物外,这些都是
一样的。
%i 和 %l 的传回值也是最复杂的。他们传回一个由数字带头,接著
是所有可能配对之物件组成的阵列。一个典型由 %i、%l 配对的字串
看来像是 'three red roses',在这之中有数个构造可以被配对:
如果 numeral>0 则 tree, four, five 等会被配对;
如果 numeral<0 则 second, twentyfirst 等会被配对;
如果 numeral==0 则 'all' 或是一般的复数形式如 'apples'会
被配对。
注意!
这个超越函式(efun)不管给定数值的隐含语意。若给予
'all apples' 或是 'second apple',它都不会关心的。%i
将会传回所有阵列内可以配对的物件。它留给呼叫者来决定
'second' 在给定内容的意思。并且,当给定一个物件而非
一个外显的(explicit)物件阵列时,整个给定物件的递回内
容将会被搜寻。它也留给呼叫者来决定实际上可看到的物件
中,哪个是 'second' ,而不是传回之物件阵列中第二个物
件。
警告:
"%s %w %i" 这些型态的样式可能不如预期的有用。%w 将总会成功,
以至於相对於 %s 的参数将总会是空的。
问题:
'word' 和 [word] 这型态的样式中,'word' 不能包含空白。它必须
是单一单字。这是因为样式会以 " " (空白) 来剖析,所以一个样式
单元(element)不能含有空白。
以空白来剖析的另一个影响是,用来分隔一个样式的部份(piece)必须
是以空白隔开,例如不能是 " 'word'/%i " 而须是 " 'word' / %i"。
例子:
if (parse_command("spray car",environment(this_player()),
" 'spray' / 'paint' [paint] %i ",items))
{
/*
如果这个样式被配对的话,则 items 会传回在 'destargs'
之後如同上述 %i 的阵列。
*/
}
MUDLIB 之支援:
为了使这个超越函式有用,它必须有来自 mudlib 的支援,它需要一
组函式让它在判断机制(sensible manner)内进行剖析前呼叫,以取
得相关资讯。
在早期的版本中,它使用在 LPC 物件中一般的 id() lfun 以找到一
个特定字串所指定的物件。由於它在剖析非常长的指令时,会产生数
百甚至数千个呼叫,所以十分没有效率。
新的版本则依赖著提供这三个 'names' 串列的 LPC 物件。
1 - 一般单一的名字;
2 - 复数格式的名字;
3 - 公认的物件形容词。
以上可以由呼叫下列函式得到:
1 - string *parse_command_id_list();
2 - string *parse_command_plural_id_list();
3 - string *parse_command_adjectiv_id_list();
真正唯一需要的串列是第一个。如果第二个不存在的话,这个超越函
式将会试著由单一串列建立出来。因为文法上的因素,它并不是完美
到总是会成功。尤其当 'names' 不是单一单字而是片语时,更是如
此。
The third is very nice to have because it makes constructs
like
(译注:无法翻译此原文。)
除了这些函式应该存在於所有物件外,最好它们能置於基本的 mudlib
物件内,当中也有一些函式是母物件(master object) 所需要的。
这些虽不是绝对必须的,但它们真的给了这个超越函式额外的能力。
基本上,这些母物件的 lfuns 需要设定由每个物件得到之名称串列
的预设值。
这些串列上的名字可应用於任何所有的物件上。在这些物件里的前
三个对这些 lfuns 是一样的:
string *parse_command_id_list()
- 一般会传回: ({ "one", "thing" })
string *parse_command_plural_id_list()
- 一般会传回: ({ "ones", "things", "them" })
string *parse_command_adjectiv_id_list()
- 一般会传回: ({ "iffish" })
最後二个是介系词的内定串列,所以:
string *parse_command_prepos_list()
- 一般会传回: ({ "in", "on", "under" })
string parse_command_all_word()
- 一般会传回: "all"
翻译:
[email protected] 97.Jul.26 (printed 3/16/95)