NfaCalc   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 59
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 35
dl 0
loc 59
rs 10
c 1
b 0
f 1
wmc 9

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getEpsilonClosure() 0 13 2
A getStateSymbolMoves() 0 13 3
A __construct() 0 3 1
A getSymbolMoves() 0 10 2
A getStateEpsilonMoves() 0 8 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\UniLex\RegExp\FSM;
6
7
class NfaCalc
8
{
9
    private $nfa;
10
11
    public function __construct(Nfa $nfa)
12
    {
13
        $this->nfa = $nfa;
14
    }
15
16
    public function getEpsilonClosure(int ...$stateList): array
17
    {
18
        $notProcessedStateList = $stateList;
19
        $processedStateList = [];
20
        while (!empty($notProcessedStateList)) {
21
            $nextState = array_pop($notProcessedStateList);
22
            $processedStateList[] = $nextState;
23
            $stateEpsilonMoves = $this->getStateEpsilonMoves($nextState);
24
            $newNotProcessedStateList = array_diff($stateEpsilonMoves, $processedStateList, $notProcessedStateList);
25
            $notProcessedStateList = array_merge($notProcessedStateList, $newNotProcessedStateList);
26
        }
27
        sort($processedStateList);
28
        return $processedStateList;
29
    }
30
31
    public function getSymbolMoves(int $symbolId, int ...$stateList): array
32
    {
33
        $result = [];
34
        foreach ($stateList as $stateId) {
35
            $moveList = $this->getStateSymbolMoves($symbolId, $stateId);
36
            $newMoveList = array_diff($moveList, $result);
37
            $result = array_merge($result, $newMoveList);
38
        }
39
        sort($result);
40
        return $result;
41
    }
42
43
    private function getStateSymbolMoves(int $symbolId, int $stateIn): array
44
    {
45
        $moveList = $this
46
            ->nfa
47
            ->getSymbolTransitionMap()
48
            ->getExitList($stateIn);
49
        $stateOutList = [];
50
        foreach ($moveList as $stateOut => $symbolList) {
51
            if (in_array($symbolId, $symbolList)) {
52
                $stateOutList[] = $stateOut;
53
            }
54
        }
55
        return $stateOutList;
56
    }
57
58
    private function getStateEpsilonMoves(int $stateIn): array
59
    {
60
        $moveList = $this
61
            ->nfa
62
            ->getEpsilonTransitionMap()
63
            ->getExitList($stateIn);
64
        $moveList[$stateIn] = true;
65
        return array_keys($moveList);
66
    }
67
}
68