Version: current

      1 <?php
      2  /**
      3  * This file is part of phpMorphy library
      4  *
      5  * Copyright c 2007-2008 Kamaev Vladimir <heromantor@users.sourceforge.net>
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Lesser General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Lesser General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Lesser General Public
     18  * License along with this library; if not, write to the
     19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     20  * Boston, MA 02111-1307, USA.
     21  */
     22
     23 /**
     24  * This file is autogenerated at Wed, 14 Oct 2009 01:33:59 +0400, don`t change it!
     25  */
     26 class phpMorphy_Fsa_Sparse_Shm extends phpMorphy_Fsa {
     27     function walk($trans, $word, $readAnnot = true) {
     28         $__shm = $this->resource['shm_id']; $__offset = $this->resource['offset']; $fsa_start = $this->fsa_start;
     29
     30         for($i = 0, $c = $GLOBALS['__phpmorphy_strlen']($word); $i < $c; $i++) {
     31             $prev_trans = $trans;
     32             $char = ord($word[$i]);
     33
     34             /////////////////////////////////
     35             // find char in state begin
     36             // sparse version
     37             $result = true;
     38
     39             list(, $trans) = unpack('V', shmop_read($__shm, $__offset + ($fsa_start + (((($trans >> 10) & 0x3FFFFF) + $char + 1) << 2)), 4));
     40
     41             if(($trans & 0x0200) || ($trans & 0xFF) != $char) {
     42                 $result = false;
     43             }
     44             // find char in state end
     45             /////////////////////////////////
     46
     47             if(!$result) {
     48                 $trans = $prev_trans;
     49                 break;
     50             }
     51         }
     52
     53         $annot = null;
     54         $result = false;
     55         $prev_trans = $trans;
     56
     57         if($i >= $c) {
     58             // Read annotation when we walked all chars in word
     59             $result = true;
     60
     61             if($readAnnot) {
     62                 // read annot trans
     63
     64                 list(, $trans) = unpack('V', shmop_read($__shm, $__offset + ($fsa_start + ((($trans >> 10) & 0x3FFFFF) << 2)), 4));
     65
     66                 if(0 == ($trans & 0x0100)) {
     67                     $result = false;
     68                 } else {
     69                     $annot = $this->getAnnot($trans);
     70                 }
     71             }
     72         }
     73
     74         return array(
     75             'result' => $result,
     76             'last_trans' => $trans,
     77             'word_trans' => $prev_trans,
     78             'walked' => $i,
     79             'annot' => $annot
     80         );
     81     }
     82
     83     function collect($startNode, $callback, $readAnnot = true, $path = '') {
     84         $total = 0;
     85
     86         $stack = array();
     87         $stack_idx = array();
     88         $start_idx = 0;
     89         array_push($stack, null);
     90         array_push($stack_idx, null);
     91
     92         $state = $this->readState((($startNode) >> 10) & 0x3FFFFF);
     93
     94         do {
     95             for($i = $start_idx, $c = count($state); $i < $c; $i++) {
     96                 $trans = $state[$i];
     97
     98                 if(($trans & 0x0100)) {
     99                     $total++;
    100
    101                     if($readAnnot) {
    102                         $annot = $this->getAnnot($trans);
    103                     } else {
    104                         $annot = $trans;
    105                     }
    106
    107                     if(!call_user_func($callback, $path, $annot)) {
    108                         return $total;
    109                     }
    110                 } else {
    111                     $path .= chr(($trans & 0xFF));
    112                     array_push($stack, $state);
    113                     array_push($stack_idx, $i + 1);
    114                     $state = $this->readState((($trans) >> 10) & 0x3FFFFF);
    115                     $start_idx = 0;
    116
    117                     break;
    118                 }
    119             }
    120
    121             if($i >= $c) {
    122                 $state = array_pop($stack);
    123                 $start_idx = array_pop($stack_idx);
    124                 $path = $GLOBALS['__phpmorphy_substr']($path, 0, -1);
    125             }
    126         } while(!empty($stack));
    127
    128         return $total;
    129     }
    130
    131     function readState($index) {
    132         $__shm = $this->resource['shm_id']; $__offset = $this->resource['offset']; $fsa_start = $this->fsa_start;
    133
    134         $result = array();
    135
    136         $start_offset = $fsa_start + (($index) << 2);
    137
    138         // first try read annot transition
    139
    140         list(, $trans) = unpack('V', shmop_read($__shm, $__offset + ($start_offset), 4));
    141
    142         if(($trans & 0x0100)) {
    143             $result[] = $trans;
    144         }
    145
    146         // read rest
    147         $start_offset += 4;
    148         foreach($this->getAlphabetNum() as $char) {
    149
    150             list(, $trans) = unpack('V', shmop_read($__shm, $__offset + ($start_offset + (($char) << 2)), 4));
    151
    152 //            if(!($trans & 0x0200) && ($trans & 0xFF) == $char) {
    153 // TODO: check term and empty flags at once i.e. $trans & 0x0300
    154             if(!(($trans & 0x0200) || ($trans & 0x0100)) && ($trans & 0xFF) == $char) {
    155
    156                 $result[] = $trans;
    157             }
    158         }
    159
    160         return $result;
    161     }
    162
    163     function unpackTranses($rawTranses) {
    164         settype($rawTranses, 'array');
    165         $result = array();
    166
    167         foreach($rawTranses as $rawTrans) {
    168             $result[] = array(
    169                 'term'  => ($rawTrans & 0x0100) ? true : false,
    170                 'empty' => ($rawTrans & 0x0200) ? true : false,
    171                 'attr'  => ($rawTrans & 0xFF),
    172                 'dest'  => (($rawTrans) >> 10) & 0x3FFFFF,
    173             );
    174         }
    175
    176         return $result;
    177     }
    178
    179     protected function readRootTrans() {
    180         $__shm = $this->resource['shm_id']; $__offset = $this->resource['offset']; $fsa_start = $this->fsa_start;
    181
    182
    183         list(, $trans) = unpack('V', shmop_read($__shm, $__offset + ($fsa_start + 4), 4));
    184
    185         return $trans;
    186     }
    187
    188     protected function readAlphabet() {
    189         $__shm = $this->resource['shm_id']; $__offset = $this->resource['offset']; $fsa_start = $this->fsa_start;
    190
    191
    192         return shmop_read($__shm, $__offset + ($this->header['alphabet_offset']), $this->header['alphabet_size']);
    193     }
    194
    195     function getAnnot($trans) {
    196         if(!($trans & 0x0100)) {
    197             return null;
    198         }
    199
    200         $__shm = $this->resource['shm_id']; $__offset = $this->resource['offset']; $fsa_start = $this->fsa_start;
    201
    202         $offset =
    203             $this->header['annot_offset'] +
    204             ((($trans & 0xFF) << 22) | (($trans >> 10) & 0x3FFFFF));
    205
    206
    207         $len = ord(shmop_read($__shm, $__offset + ($offset), 1));
    208
    209         if($len) {
    210             $annot = shmop_read($__shm, $__offset + ($offset + 1), $len);
    211         } else {
    212             $annot = null;
    213         }
    214
    215         return $annot;
    216     }
    217
    218     function getAlphabetNum() {
    219         if(!isset($this->alphabet_num)) {
    220             $this->alphabet_num = array_map('ord', $this->getAlphabet());
    221         }
    222
    223         return $this->alphabet_num;
    224     }
    225     protected $alphabet_num;
    226 }
    227

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -