xref: /plugin/combo/vendor/antlr/antlr4-php-runtime/src/Dfa/DFASerializer.php (revision 37748cd8654635afbeca80942126742f0f4cc346)
1*37748cd8SNickeau<?php
2*37748cd8SNickeau
3*37748cd8SNickeaudeclare(strict_types=1);
4*37748cd8SNickeau
5*37748cd8SNickeaunamespace Antlr\Antlr4\Runtime\Dfa;
6*37748cd8SNickeau
7*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Atn\ATNSimulator;
8*37748cd8SNickeauuse Antlr\Antlr4\Runtime\Vocabulary;
9*37748cd8SNickeau
10*37748cd8SNickeau/**
11*37748cd8SNickeau * A DFA walker that knows how to dump them to serialized strings.
12*37748cd8SNickeau */
13*37748cd8SNickeauclass DFASerializer
14*37748cd8SNickeau{
15*37748cd8SNickeau    /** @var DFA */
16*37748cd8SNickeau    private $dfa;
17*37748cd8SNickeau
18*37748cd8SNickeau    /** @var Vocabulary */
19*37748cd8SNickeau    private $vocabulary;
20*37748cd8SNickeau
21*37748cd8SNickeau    public function __construct(DFA $dfa, Vocabulary $vocabulary)
22*37748cd8SNickeau    {
23*37748cd8SNickeau        $this->dfa = $dfa;
24*37748cd8SNickeau        $this->vocabulary = $vocabulary;
25*37748cd8SNickeau    }
26*37748cd8SNickeau
27*37748cd8SNickeau    public function toString() : string
28*37748cd8SNickeau    {
29*37748cd8SNickeau        if ($this->dfa->s0 === null) {
30*37748cd8SNickeau            return '';
31*37748cd8SNickeau        }
32*37748cd8SNickeau
33*37748cd8SNickeau        $string = '';
34*37748cd8SNickeau
35*37748cd8SNickeau        /** @var DFAState $state */
36*37748cd8SNickeau        foreach ($this->dfa->getStates() as $state) {
37*37748cd8SNickeau            $count = $state->edges === null ? 0 : $state->edges->count();
38*37748cd8SNickeau
39*37748cd8SNickeau            for ($i = 0; $i < $count; $i++) {
40*37748cd8SNickeau                /** @var DFAState $t */
41*37748cd8SNickeau                $t = $state->edges[$i];
42*37748cd8SNickeau
43*37748cd8SNickeau                if ($t !== null && $t->stateNumber !== 0x7FFFFFFF) {
44*37748cd8SNickeau                    $string .= $this->getStateString($state);
45*37748cd8SNickeau
46*37748cd8SNickeau                    $label = $this->getEdgeLabel($i);
47*37748cd8SNickeau
48*37748cd8SNickeau                    $string .= \sprintf("-%s->%s\n", $label, $this->getStateString($t));
49*37748cd8SNickeau                }
50*37748cd8SNickeau            }
51*37748cd8SNickeau        }
52*37748cd8SNickeau
53*37748cd8SNickeau        return $string;
54*37748cd8SNickeau    }
55*37748cd8SNickeau
56*37748cd8SNickeau    protected function getEdgeLabel(int $i) : string
57*37748cd8SNickeau    {
58*37748cd8SNickeau        return $this->vocabulary->getDisplayName($i - 1);
59*37748cd8SNickeau    }
60*37748cd8SNickeau
61*37748cd8SNickeau    protected function getStateString(DFAState $state) : string
62*37748cd8SNickeau    {
63*37748cd8SNickeau        if ($state->equals(ATNSimulator::error())) {
64*37748cd8SNickeau            return 'ERROR';
65*37748cd8SNickeau        }
66*37748cd8SNickeau
67*37748cd8SNickeau        $baseStateStr = \sprintf(
68*37748cd8SNickeau            '%ss%d%s',
69*37748cd8SNickeau            $state->isAcceptState ? ':' : '',
70*37748cd8SNickeau            $state->stateNumber,
71*37748cd8SNickeau            $state->requiresFullContext ? '^' : ''
72*37748cd8SNickeau        );
73*37748cd8SNickeau
74*37748cd8SNickeau        if ($state->isAcceptState) {
75*37748cd8SNickeau            if ($state->predicates !== null) {
76*37748cd8SNickeau                return $baseStateStr . '=>[' . \implode(', ', $state->predicates) . ']';
77*37748cd8SNickeau            }
78*37748cd8SNickeau
79*37748cd8SNickeau            return $baseStateStr . '=>' . $state->prediction;
80*37748cd8SNickeau        }
81*37748cd8SNickeau
82*37748cd8SNickeau        return $baseStateStr;
83*37748cd8SNickeau    }
84*37748cd8SNickeau
85*37748cd8SNickeau    public function __toString() : string
86*37748cd8SNickeau    {
87*37748cd8SNickeau        return $this->toString();
88*37748cd8SNickeau    }
89*37748cd8SNickeau}
90