Hoa central
Pp.php
Go to the documentation of this file.
1 <?php
2 
37 namespace Hoa\Compiler\Bin;
38 
39 use Hoa\Compiler;
40 use Hoa\Console;
41 use Hoa\File;
42 
52 {
58  protected $options = [
59  ['visitor', Console\GetOption::REQUIRED_ARGUMENT, 'v'],
60  ['visitor-class', Console\GetOption::REQUIRED_ARGUMENT, 'c'],
61  ['token-sequence', Console\GetOption::NO_ARGUMENT, 's'],
62  ['trace', Console\GetOption::NO_ARGUMENT, 't'],
63  ['help', Console\GetOption::NO_ARGUMENT, 'h'],
64  ['help', Console\GetOption::NO_ARGUMENT, '?']
65  ];
66 
67 
68 
74  public function main()
75  {
76  $visitor = null;
77  $tokenSequence = false;
78  $trace = false;
79 
80  while (false !== $c = $this->getOption($v)) {
81  switch ($c) {
82  case 'v':
83  switch (strtolower($v)) {
84  case 'dump':
85  $visitor = 'Hoa\Compiler\Visitor\Dump';
86 
87  break;
88 
89  default:
90  return $this->usage();
91  }
92 
93  break;
94 
95  case 'c':
96  $visitor = str_replace('.', '\\', $v);
97 
98  break;
99 
100  case 's':
101  $tokenSequence = true;
102 
103  break;
104 
105  case 't':
106  $trace = true;
107 
108  break;
109 
110  case '__ambiguous':
111  $this->resolveOptionAmbiguity($v);
112 
113  break;
114 
115  case 'h':
116  case '?':
117  default:
118  return $this->usage();
119  }
120  }
121 
122  $this->parser->listInputs($grammar, $language);
123 
124  if (empty($grammar) || (empty($language) && '0' !== $language)) {
125  return $this->usage();
126  }
127 
128  $compiler = Compiler\Llk::load(new File\Read($grammar));
129  $data = new File\Read($language);
130 
131  try {
132  $ast = $compiler->parse($data->readAll());
133  } catch (Compiler\Exception $e) {
134  if (true === $tokenSequence) {
135  $this->printTokenSequence($compiler);
136  echo "\n\n";
137  }
138 
139  throw $e;
140 
141  return 1;
142  }
143 
144  if (true === $tokenSequence) {
145  $this->printTokenSequence($compiler);
146  echo "\n\n";
147  }
148 
149  if (true === $trace) {
150  $this->printTrace($compiler);
151  echo "\n\n";
152  }
153 
154  if (null !== $visitor) {
155  $visitor = dnew($visitor);
156  echo $visitor->visit($ast);
157  }
158 
159  return;
160  }
161 
168  protected function printTrace(Compiler\Llk\Parser $compiler)
169  {
170  $i = 0;
171 
172  foreach ($compiler->getTrace() as $element) {
173  if ($element instanceof Compiler\Llk\Rule\Entry) {
174  $ruleName = $element->getRule();
175  $rule = $compiler->getRule($ruleName);
176 
177  echo str_repeat('> ', ++$i), 'enter ', $ruleName;
178 
179  if (null !== $id = $rule->getNodeId()) {
180  echo ' (', $id, ')';
181  }
182 
183  echo "\n";
184  } elseif ($element instanceof Compiler\Llk\Rule\Token) {
185  echo
186  str_repeat(' ', $i + 1),
187  'token ', $element->getTokenName(),
188  ', consumed ', $element->getValue(), "\n";
189  } else {
190  echo
191  str_repeat('< ', $i--),
192  'ekzit ', $element->getRule(), "\n";
193  }
194  }
195 
196  return;
197  }
198 
205  protected function printTokenSequence(Compiler\Llk\Parser $compiler)
206  {
207  $sequence = $compiler->getTokenSequence();
208  $format = '%' . (strlen((string) count($sequence)) + 1) . 's ' .
209  '%-13s %-20s %s %6s' . "\n";
210 
211  $header = sprintf(
212  $format,
213  '#',
214  'namespace',
215  'token name',
216  'token value ',
217  'offset'
218  );
219 
220  echo $header, str_repeat('-', strlen($header)), "\n";
221 
222  foreach ($sequence as $i => $token) {
223  printf(
224  $format,
225  $i,
226  $token['namespace'],
227  $token['token'],
228  30 < $token['length']
229  ? mb_substr($token['value'], 0, 29) . '…'
230  : 'EOF' === $token['token']
231  ? str_repeat(' ', 30)
232  : $token['value'] .
233  str_repeat(' ', 30 - $token['length']),
234  $token['offset']
235  );
236  }
237 
238  return;
239  }
240 
246  public function usage()
247  {
248  echo
249  'Usage : compiler:pp <options> [grammar.pp] [language]', "\n",
250  'Options :', "\n",
251  $this->makeUsageOptionsList([
252  'v' => 'Visitor name (only “dump” is supported).',
253  'c' => 'Visitor classname (using . instead of \ works).',
254  's' => 'Print token sequence.',
255  't' => 'Print trace.',
256  'help' => 'This help.'
257  ]), "\n";
258 
259  return;
260  }
261 }
262 
263 __halt_compiler();
264 Compile and visit languages with grammars.
makeUsageOptionsList(Array $definitions=[])
Definition: Kit.php:149
printTrace(Compiler\Llk\Parser $compiler)
Definition: Pp.php:168
printTokenSequence(Compiler\Llk\Parser $compiler)
Definition: Pp.php:205
getOption(&$optionValue, $short=null)
Definition: Kit.php:104
resolveOptionAmbiguity(Array $solutions)
Definition: Kit.php:190