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