‪TYPO3CMS  ‪main
LossyTokenizer.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
40 
57 {
59 
62 
63  private array ‪$lines;
64  private int ‪$currentLineNumber;
65  private string ‪$currentLineString;
66 
67  public function ‪tokenize(string $source): ‪LineStream
68  {
69  $this->lineStream = new ‪LineStream();
70  $this->currentLineNumber = -1;
71  $this->lines = [];
72  $this->‪splitLines($source);
73 
74  while (true) {
75  $this->currentLineNumber++;
76  if (!array_key_exists($this->currentLineNumber, $this->lines)) {
77  break;
78  }
79  $this->currentLineString = trim($this->lines[$this->currentLineNumber]['line']);
80  $nextChar = substr($this->currentLineString, 0, 1);
81  if ($nextChar === '') {
82  continue;
83  }
84  $nextTwoChars = substr($this->currentLineString, 0, 2);
85  if ($nextChar === '#' || $nextTwoChars === '//') {
86  continue;
87  }
88  if ($nextTwoChars === '/*') {
89  // @todo: This is one of multiple places where multiline "/*" comments are parsed in this tokenizer. Other
90  // places are cluttered in detail methods. It might be more straight to have an early scanning
91  // phase through all lines to remove comments up front, to not wire especially the multiline comment
92  // parsing to single places, and throw away commented lines early. This isn't trivial though, since
93  // for instance "foo = bar /* not a comment */" then needs to be sorted out, too. Having an early
94  // "kick comments" loop however might be quicker in the end and would make the main parsing
95  // methods more concise and probably more bullet proof.
96  // Also note there are currently not-unit-tested edge cases, that will currently not parse as
97  // (maybe) expected. In the example below, "foo2 = bar2" is ignored. This is an issue with the
98  // LosslessTokenizer as well, probably, and we may rather want to declare this as invalid syntax?!
99  // foo = bar /* comment start
100  // comment end */ foo2 = bar2
102  continue;
103  }
104  if ($nextChar === '[') {
105  $this->‪createConditionLine();
106  } elseif ($nextChar === '}') {
107  $this->lineStream->append((new ‪BlockCloseLine()));
108  } elseif (str_starts_with($this->currentLineString, '@import')) {
109  $this->‪parseImportLine();
110  } elseif (str_starts_with($this->currentLineString, '<INCLUDE_TYPOSCRIPT:')) {
111  $this->‪parseImportOld();
112  } else {
113  $this->‪parseIdentifier();
114  }
115  }
116 
117  return ‪$this->lineStream;
118  }
119 
120  private function ‪splitLines($source): void
121  {
122  $vanillaLines = explode(chr(10), $source);
123  $this->lines = array_map(
124  fn(int $lineNumber, string $vanillaLine): array => [
125  'line' => rtrim($vanillaLine, "\r"),
126  ],
127  array_keys($vanillaLines),
128  $vanillaLines
129  );
130  }
131 
132  private function ‪ignoreUntilEndOfMultilineComment(): void
133  {
134  while (true) {
135  if (str_contains($this->currentLineString, '*/')) {
136  return;
137  }
138  if (!array_key_exists($this->currentLineNumber + 1, $this->lines)) {
139  return;
140  }
141  $this->currentLineNumber++;
142  $this->currentLineString = trim($this->lines[$this->currentLineNumber]['line']);
143  }
144  }
145 
149  private function ‪createConditionLine(): void
150  {
151  $upperCaseLine = strtoupper($this->currentLineString);
152  if (str_starts_with($upperCaseLine, '[ELSE]')) {
153  $this->lineStream->append((new ‪ConditionElseLine()));
154  $this->currentLineString = trim(substr($this->currentLineString, 6));
155  if (str_starts_with($this->currentLineString, '/*')) {
157  }
158  return;
159  }
160  if (str_starts_with($upperCaseLine, '[END]')) {
161  $this->lineStream->append((new ‪ConditionStopLine()));
162  $this->currentLineString = trim(substr($this->currentLineString, 5));
163  if (str_starts_with($this->currentLineString, '/*')) {
165  }
166  return;
167  }
168  if (str_starts_with($upperCaseLine, '[GLOBAL]')) {
169  $this->lineStream->append((new ‪ConditionStopLine()));
170  $this->currentLineString = trim(substr($this->currentLineString, 8));
171  if (str_starts_with($this->currentLineString, '/*')) {
173  }
174  return;
175  }
176  $conditionBody = '';
177  $conditionBodyCharCount = 0;
178  $conditionBodyChars = mb_str_split(substr($this->currentLineString, 1), 1, 'UTF-8');
179  $bracketCount = 1;
180  while (true) {
181  $nextChar = $conditionBodyChars[$conditionBodyCharCount] ?? null;
182  if ($nextChar === null) {
183  // end of chars
184  return;
185  }
186  if ($nextChar === '[') {
187  $bracketCount++;
188  $conditionBody .= $nextChar;
189  $conditionBodyCharCount++;
190  continue;
191  }
192  if ($nextChar === ']') {
193  $bracketCount--;
194  if ($bracketCount === 0) {
195  if ($conditionBodyCharCount) {
196  $conditionBodyToken = new ‪Token(TokenType::T_VALUE, $conditionBody);
197  $this->lineStream->append((new ‪ConditionLine())->setValueToken($conditionBodyToken));
198  $conditionBodyCharCount++;
199  break;
200  }
201  $conditionBodyCharCount++;
202  break;
203  }
204  $conditionBody .= $nextChar;
205  $conditionBodyCharCount++;
206  continue;
207  }
208  $conditionBody .= $nextChar;
209  $conditionBodyCharCount++;
210  }
211  $this->currentLineString = trim(mb_substr($this->currentLineString, $conditionBodyCharCount + 1));
212  if (str_starts_with($this->currentLineString, '/*')) {
214  }
215  }
216 
217  private function ‪parseBlockStart(): void
218  {
219  $this->currentLineString = trim(substr($this->currentLineString, 1));
220  if (str_starts_with($this->currentLineString, '}')) {
221  // Edge case: foo = { } in one line. Note content within {} is not parsed, everything behind { ends up as comment.
222  $this->lineStream->append((new ‪IdentifierBlockOpenLine())->setIdentifierTokenStream($this->identifierStream));
223  $this->lineStream->append((new ‪BlockCloseLine()));
224  return;
225  }
226  $this->lineStream->append((new ‪IdentifierBlockOpenLine())->setIdentifierTokenStream($this->identifierStream));
227  }
228 
229  private function ‪parseImportLine(): void
230  {
231  $this->currentLineString = trim(substr($this->currentLineString, 7));
232 
233  // Next char should be the opening tick or doubletick, otherwise we create a comment until end of line
234  $nextChar = substr($this->currentLineString, 0, 1);
235  if ($nextChar !== '\'' && $nextChar !== '"') {
236  return;
237  }
238 
239  $importBody = '';
240  $importBodyCharCount = 0;
241  $importBodyChars = mb_str_split(substr($this->currentLineString, 1), 1, 'UTF-8');
242  while (true) {
243  $nextChar = $importBodyChars[$importBodyCharCount] ?? null;
244  if ($nextChar === null) {
245  // end of chars
246  if ($importBodyCharCount) {
247  $importBodyToken = (new ‪Token(TokenType::T_VALUE, $importBody));
248  $this->lineStream->append((new ‪ImportLine())->setValueToken($importBodyToken));
249  return;
250  }
251  return;
252  }
253  if ($nextChar === '\'' || $nextChar === '"') {
254  if ($importBodyCharCount) {
255  $importBodyToken = new ‪Token(TokenType::T_VALUE, $importBody);
256  $this->lineStream->append((new ‪ImportLine())->setValueToken($importBodyToken));
257  break;
258  }
259  break;
260  }
261  $importBody .= $nextChar;
262  $importBodyCharCount++;
263  }
264  $this->currentLineString = trim(mb_substr($this->currentLineString, $importBodyCharCount + 2));
265  if (str_starts_with($this->currentLineString, '/*')) {
267  }
268  }
269 
274  private function ‪parseImportOld(): void
275  {
276  $this->currentLineString = substr($this->currentLineString, 20);
277  $importBody = '';
278  $importBodyCharCount = 0;
279  $importBodyChars = mb_str_split($this->currentLineString, 1, 'UTF-8');
280  while (true) {
281  $nextChar = $importBodyChars[$importBodyCharCount] ?? null;
282  if ($nextChar === null) {
283  // end of chars
284  if ($importBodyCharCount) {
285  $importBodyToken = (new ‪Token(TokenType::T_VALUE, $importBody));
286  $this->lineStream->append((new ‪ImportOldLine())->setValueToken($importBodyToken));
287  return;
288  }
289  return;
290  }
291  if ($nextChar === '>') {
292  if ($importBodyCharCount) {
293  $importBodyToken = new ‪Token(TokenType::T_VALUE, $importBody);
294  $this->lineStream->append((new ‪ImportOldLine())->setValueToken($importBodyToken));
295  break;
296  }
297  break;
298  }
299  $importBody .= $nextChar;
300  $importBodyCharCount++;
301  }
302  $this->currentLineString = trim(mb_substr($this->currentLineString, $importBodyCharCount + 2));
303  if (str_starts_with($this->currentLineString, '/*')) {
305  }
306  }
307 
308  private function ‪parseIdentifier(): void
309  {
310  $splitLine = mb_str_split($this->currentLineString, 1, 'UTF-8');
311  $currentPosition = $this->‪parseIdentifierUntilStopChar($splitLine);
312  if (!$currentPosition) {
313  return;
314  }
315  $this->currentLineString = trim(substr($this->currentLineString, $currentPosition));
316  $nextChar = substr($this->currentLineString, 0, 1);
317  $nextTwoChars = $nextChar . substr($this->currentLineString, 1, 1);
318  if ($nextTwoChars === '=<') {
319  $this->‪parseOperatorReference();
320  return;
321  }
322  if ($nextChar === '=') {
324  return;
325  }
326  if ($nextChar === '{') {
327  $this->‪parseBlockStart();
328  return;
329  }
330  if ($nextChar === '>') {
331  $this->‪parseOperatorUnset();
332  return;
333  }
334  if ($nextChar === '<') {
335  $this->‪parseOperatorCopy();
336  return;
337  }
338  if ($nextChar === '(') {
340  return;
341  }
342  if ($nextTwoChars === ':=') {
343  $this->‪parseOperatorFunction();
344  }
345  if ($nextTwoChars === '/*') {
347  }
348  }
349 
350  private function ‪parseOperatorUnset(): void
351  {
352  $this->lineStream->append((new ‪IdentifierUnsetLine())->setIdentifierTokenStream($this->identifierStream));
353  $this->currentLineString = trim(trim(trim($this->currentLineString), '>'));
354  if (str_starts_with($this->currentLineString, '/*')) {
356  }
357  }
358 
359  private function ‪parseOperatorAssignment(): void
360  {
361  $this->currentLineString = trim(substr($this->currentLineString, 1));
362  $this->valueStream = new ‪TokenStream();
363  $this->‪parseValueForConstants();
364  $this->lineStream->append((new ‪IdentifierAssignmentLine())->setIdentifierTokenStream($this->identifierStream)->setValueTokenStream($this->valueStream));
365  }
366 
367  private function ‪parseOperatorMultilineAssignment(): void
368  {
369  $this->valueStream = new ‪TokenStream();
370  $this->currentLineString = substr($this->currentLineString, 1);
371  // True if we're currently in the line with the opening '('
372  $isFirstLine = true;
373  // True if the first line has a first value token: "foo ( thisIsTheFirstValueToken"
374  $valueOnFirstLine = false;
375  // True if the line after '(' is parsed
376  $isSecondLine = false;
377  while (true) {
378  if (str_starts_with(ltrim($this->currentLineString), ')')) {
379  $this->currentLineString = trim(substr($this->currentLineString, 1));
380  if (!$this->valueStream->isEmpty()) {
381  $this->lineStream->append((new ‪IdentifierAssignmentLine())->setIdentifierTokenStream($this->identifierStream)->setValueTokenStream($this->valueStream));
382  }
383  if (str_starts_with($this->currentLineString, '/*')) {
385  }
386  return;
387  }
388  if ($isFirstLine && str_ends_with($this->currentLineString, ')')) {
389  $this->currentLineString = substr($this->currentLineString, 0, -1);
390  if (strlen($this->currentLineString) > 1) {
391  $this->‪parseValueForConstants();
392  $this->lineStream->append((new ‪IdentifierAssignmentLine())->setIdentifierTokenStream($this->identifierStream)->setValueTokenStream($this->valueStream));
393  return;
394  }
395  return;
396  }
397  if ($isFirstLine && strlen($this->currentLineString)) {
398  $this->‪parseValueForConstants();
399  $valueOnFirstLine = true;
400  }
401  if (($isFirstLine && $valueOnFirstLine)
402  || (!$isFirstLine && !$isSecondLine)
403  ) {
404  $this->valueStream->append(new ‪Token(TokenType::T_NEWLINE, "\n"));
405  }
406  if (!$isFirstLine && strlen($this->currentLineString)) {
407  $this->‪parseValueForConstants();
408  }
409  if (!array_key_exists($this->currentLineNumber + 1, $this->lines)) {
410  return;
411  }
412  if ($isFirstLine) {
413  $isSecondLine = true;
414  } else {
415  $isSecondLine = false;
416  }
417  $isFirstLine = false;
418  $valueOnFirstLine = false;
419  $this->currentLineNumber++;
420  $this->currentLineString = $this->lines[‪$this->currentLineNumber]['line'];
421  }
422  }
423 
424  private function ‪parseOperatorCopy(): void
425  {
426  $this->currentLineString = trim(substr($this->currentLineString, 1));
428  $charsHandled = $this->‪parseIdentifierAtEndOfLine();
429  $referenceStream = ‪$this->identifierStream;
430  if ($referenceStream->isEmpty()) {
431  return;
432  }
433  $this->lineStream->‪append(
434  (new ‪IdentifierCopyLine())
435  ->setIdentifierTokenStream(‪$identifierStream)
436  ->setValueTokenStream($referenceStream)
437  );
438  $this->currentLineString = trim(mb_substr($this->currentLineString, $charsHandled));
439  if (str_starts_with($this->currentLineString, '/*')) {
441  }
442  }
443 
444  private function ‪parseOperatorReference(): void
445  {
446  $this->currentLineString = trim(substr($this->currentLineString, 2));
448  $charsHandled = $this->‪parseIdentifierAtEndOfLine();
449  $referenceStream = ‪$this->identifierStream;
450  if ($referenceStream->isEmpty()) {
451  return;
452  }
453  $this->lineStream->‪append(
455  ->setIdentifierTokenStream(‪$identifierStream)
456  ->setValueTokenStream($referenceStream)
457  );
458  $this->currentLineString = trim(mb_substr($this->currentLineString, $charsHandled));
459  if (str_starts_with($this->currentLineString, '/*')) {
461  }
462  }
463 
464  private function ‪parseIdentifierAtEndOfLine(): int
465  {
466  $this->identifierStream = new ‪IdentifierTokenStream();
467  $isRelative = false;
468  $splitLine = mb_str_split($this->currentLineString, 1, 'UTF-8');
469  $char = $splitLine[0] ?? null;
470  if ($char === null) {
471  return 0;
472  }
473  $nextTwoChars = $char . ($splitLine[1] ?? '');
474  if ($char === '.') {
475  // A relative right side: foo.bar < .foo (note the dot!). we identifierStream->setRelative() and
476  // get rid of the dot for the rest of the processing.
477  $isRelative = true;
478  array_shift($splitLine);
479  $this->currentLineString = substr($this->currentLineString, 1);
480  }
481  if ($char === '#') {
482  return 1;
483  }
484  if ($nextTwoChars === '//') {
485  return 2;
486  }
487  if ($nextTwoChars === '/*') {
489  return 0;
490  }
491  $charsHandled = $this->‪parseIdentifierUntilStopChar($splitLine, $isRelative);
492  return $charsHandled;
493  }
494 
495  private function ‪parseIdentifierUntilStopChar(array $splitLine, bool $isRelative = false): int
496  {
497  $this->identifierStream = new ‪IdentifierTokenStream();
498  if ($isRelative) {
499  $this->identifierStream->setRelative();
500  }
501  $currentPosition = 0;
502  $currentIdentifierBody = '';
503  $currentIdentifierCharCount = 0;
504  while (true) {
505  $nextChar = $splitLine[$currentPosition] ?? null;
506  if ($nextChar === null) {
507  if ($currentIdentifierCharCount) {
508  $identifierToken = new ‪IdentifierToken(TokenType::T_IDENTIFIER, $currentIdentifierBody);
509  $this->identifierStream->append($identifierToken);
510  }
511  return $currentPosition;
512  }
513  $nextTwoChars = $nextChar . ($splitLine[$currentPosition + 1] ?? null);
514  if ($currentPosition > 0
515  && ($nextChar === ' ' || $nextChar === "\t" || $nextChar === '=' || $nextChar === '<' || $nextChar === '>' || $nextChar === '{' || $nextTwoChars === ':=' || $nextChar === '(')
516  ) {
517  if ($currentIdentifierCharCount) {
518  $identifierToken = new ‪IdentifierToken(TokenType::T_IDENTIFIER, $currentIdentifierBody);
519  $this->identifierStream->append($identifierToken);
520  }
521  break;
522  }
523  if ($nextTwoChars === '\\.') {
524  // A quoted dot is part of *this* identifier
525  $currentIdentifierBody .= '.';
526  $currentPosition += 2;
527  $currentIdentifierCharCount++;
528  } elseif ($nextChar === '.') {
529  if ($currentIdentifierCharCount) {
530  $identifierToken = new ‪IdentifierToken(TokenType::T_IDENTIFIER, $currentIdentifierBody);
531  $this->identifierStream->append($identifierToken);
532  $currentIdentifierCharCount = 0;
533  $currentIdentifierBody = '';
534  }
535  $currentPosition++;
536  } else {
537  $currentIdentifierBody .= $nextChar;
538  $currentIdentifierCharCount++;
539  $currentPosition++;
540  }
541  }
542  return $currentPosition;
543  }
544 
545  private function ‪parseOperatorFunction(): void
546  {
547  $this->currentLineString = trim(substr($this->currentLineString, 2));
548  if ($this->currentLineString === '') {
549  return;
550  }
551  $functionName = '';
552  $functionNameCharCount = 0;
553  $functionChars = mb_str_split($this->currentLineString, 1, 'UTF-8');
554  while (true) {
555  $nextChar = $functionChars[$functionNameCharCount] ?? null;
556  if ($nextChar === null) {
557  // end of chars
558  return;
559  }
560  if ($nextChar === '(') {
561  if ($functionNameCharCount) {
562  $functionNameToken = new ‪Token(TokenType::T_FUNCTION_NAME, $functionName);
563  $functionNameCharCount++;
564  break;
565  }
566  return;
567  }
568  $functionName .= $nextChar;
569  $functionNameCharCount++;
570  }
571  $functionBodyStartPosition = $functionNameCharCount;
572  $functionBody = '';
573  $functionBodyCharCount = 0;
574  $functionValueToken = false;
575  while (true) {
576  $nextChar = $functionChars[$functionBodyStartPosition + $functionBodyCharCount] ?? null;
577  if ($nextChar === null) {
578  return;
579  }
580  if ($nextChar === ')') {
581  if ($functionBodyCharCount) {
582  $functionValueToken = new ‪Token(TokenType::T_VALUE, $functionBody);
583  $functionBodyCharCount++;
584  }
585  break;
586  }
587  $functionBody .= $nextChar;
588  $functionBodyCharCount++;
589  }
590  $line = (new ‪IdentifierFunctionLine())
591  ->setIdentifierTokenStream($this->identifierStream)
592  ->setFunctionNameToken($functionNameToken);
593  if ($functionValueToken) {
594  $line->setFunctionValueToken($functionValueToken);
595  }
596  $this->lineStream->append($line);
597  // Check for multiline comment
598  $this->currentLineString = implode('', array_slice($functionChars, $functionBodyStartPosition + $functionBodyCharCount + 1));
599  if (mb_strlen($this->currentLineString) >= 1 && str_starts_with($this->currentLineString, '/*')) {
601  }
602  }
603 
604  private function ‪parseValueForConstants(): void
605  {
606  if (!str_contains($this->currentLineString, '{$')) {
607  $valueToken = new ‪Token(TokenType::T_VALUE, $this->currentLineString);
608  $this->valueStream->append($valueToken);
609  return;
610  }
611  $splitLine = mb_str_split($this->currentLineString, 1, 'UTF-8');
612  $isInConstant = false;
613  $currentPosition = 0;
614  $currentString = '';
615  $currentStringLength = 0;
616  while (true) {
617  $char = $splitLine[$currentPosition] ?? null;
618  if ($char === null) {
619  if ($currentStringLength) {
620  $valueToken = new ‪Token(TokenType::T_VALUE, $currentString);
621  $this->valueStream->append($valueToken);
622  }
623  break;
624  }
625  $nextTwoChars = $char . ($splitLine[$currentPosition + 1] ?? '');
626  if ($nextTwoChars === '{$') {
627  $isInConstant = true;
628  if ($currentStringLength) {
629  $valueToken = new ‪Token(TokenType::T_VALUE, $currentString);
630  $this->valueStream->append($valueToken);
631  }
632  $currentString = '{$';
633  $currentPosition += 2;
634  continue;
635  }
636  if ($isInConstant && $char === '}') {
637  $valueToken = new ‪Token(TokenType::T_CONSTANT, $currentString . '}');
638  if (!$this->valueStream instanceof ‪ConstantAwareTokenStream) {
639  $this->valueStream = (new ‪ConstantAwareTokenStream())->setAll($this->valueStream->getAll());
640  }
641  $this->valueStream->append($valueToken);
642  $currentPosition++;
643  $currentString = '';
644  $currentStringLength = 0;
645  $isInConstant = false;
646  continue;
647  }
648  $currentPosition++;
649  $currentStringLength++;
650  $currentString .= $char;
651  }
652  }
653 }
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\ConditionElseLine
Definition: ConditionElseLine.php:25
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseOperatorMultilineAssignment
‪parseOperatorMultilineAssignment()
Definition: LossyTokenizer.php:367
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\IdentifierUnsetLine
Definition: IdentifierUnsetLine.php:31
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseOperatorReference
‪parseOperatorReference()
Definition: LossyTokenizer.php:444
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\Token
Definition: Token.php:29
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\IdentifierAssignmentLine
Definition: IdentifierAssignmentLine.php:37
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\IdentifierCopyLine
Definition: IdentifierCopyLine.php:37
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseValueForConstants
‪parseValueForConstants()
Definition: LossyTokenizer.php:604
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseOperatorFunction
‪parseOperatorFunction()
Definition: LossyTokenizer.php:545
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\$identifierStream
‪IdentifierTokenStream $identifierStream
Definition: LossyTokenizer.php:60
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\TokenType
‪TokenType
Definition: TokenType.php:26
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseBlockStart
‪parseBlockStart()
Definition: LossyTokenizer.php:217
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\IdentifierTokenStream
Definition: IdentifierTokenStream.php:44
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\BlockCloseLine
Definition: BlockCloseLine.php:25
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\ImportLine
Definition: ImportLine.php:33
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\ImportOldLine
Definition: ImportOldLine.php:32
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\ConditionStopLine
Definition: ConditionStopLine.php:26
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\$lines
‪array $lines
Definition: LossyTokenizer.php:63
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseIdentifierUntilStopChar
‪parseIdentifierUntilStopChar(array $splitLine, bool $isRelative=false)
Definition: LossyTokenizer.php:495
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\$lineStream
‪LineStream $lineStream
Definition: LossyTokenizer.php:58
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\IdentifierReferenceLine
Definition: IdentifierReferenceLine.php:35
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\TokenStreamInterface
Definition: TokenStreamInterface.php:30
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\IdentifierFunctionLine
Definition: IdentifierFunctionLine.php:34
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\$currentLineString
‪string $currentLineString
Definition: LossyTokenizer.php:65
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\IdentifierBlockOpenLine
Definition: IdentifierBlockOpenLine.php:31
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\TokenStream
Definition: TokenStream.php:26
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseIdentifier
‪parseIdentifier()
Definition: LossyTokenizer.php:308
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\ConstantAwareTokenStream
Definition: ConstantAwareTokenStream.php:29
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\ignoreUntilEndOfMultilineComment
‪ignoreUntilEndOfMultilineComment()
Definition: LossyTokenizer.php:132
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\tokenize
‪tokenize(string $source)
Definition: LossyTokenizer.php:67
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\IdentifierTokenStream\append
‪append(TokenInterface $token)
Definition: IdentifierTokenStream.php:78
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseImportOld
‪parseImportOld()
Definition: LossyTokenizer.php:274
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\ConditionLine
Definition: ConditionLine.php:29
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseImportLine
‪parseImportLine()
Definition: LossyTokenizer.php:229
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\createConditionLine
‪createConditionLine()
Definition: LossyTokenizer.php:149
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Token\IdentifierToken
Definition: IdentifierToken.php:34
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\$valueStream
‪TokenStreamInterface $valueStream
Definition: LossyTokenizer.php:61
‪TYPO3\CMS\Core\TypoScript\Tokenizer\TokenizerInterface
Definition: TokenizerInterface.php:40
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseIdentifierAtEndOfLine
‪parseIdentifierAtEndOfLine()
Definition: LossyTokenizer.php:464
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\$currentLineNumber
‪int $currentLineNumber
Definition: LossyTokenizer.php:64
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseOperatorAssignment
‪parseOperatorAssignment()
Definition: LossyTokenizer.php:359
‪TYPO3\CMS\Core\TypoScript\Tokenizer\Line\LineStream
Definition: LineStream.php:29
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\splitLines
‪splitLines($source)
Definition: LossyTokenizer.php:120
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer
Definition: LossyTokenizer.php:57
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseOperatorUnset
‪parseOperatorUnset()
Definition: LossyTokenizer.php:350
‪TYPO3\CMS\Core\TypoScript\Tokenizer
‪TYPO3\CMS\Core\TypoScript\Tokenizer\LossyTokenizer\parseOperatorCopy
‪parseOperatorCopy()
Definition: LossyTokenizer.php:424