网络游戏《天下》 管理员手册

MudOS v21c2

     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)