Skip to content

Commit dd1625d

Browse files
committed
TASK: Reform all parsers to use new Lexer
1 parent 4f5b603 commit dd1625d

File tree

61 files changed

+2056
-2331
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+2056
-2331
lines changed

src/Language/AST/Node/BinaryOperation/BinaryOperator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
enum BinaryOperator: string
2626
{
27+
case NULLISH_COALESCE = 'NULLISH_COALESCE';
28+
2729
case AND = 'AND';
2830
case OR = 'OR';
2931

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/**
4+
* PackageFactory.ComponentEngine - Universal View Components for PHP
5+
* Copyright (C) 2023 Contributors of PackageFactory.ComponentEngine
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
declare(strict_types=1);
22+
23+
namespace PackageFactory\ComponentEngine\Language\AST\Node\TemplateLiteral;
24+
25+
final class TemplateLiteralLine
26+
{
27+
public function __construct(
28+
public readonly int $indentation,
29+
public readonly TemplateLiteralSegments $segments
30+
) {
31+
}
32+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/**
4+
* PackageFactory.ComponentEngine - Universal View Components for PHP
5+
* Copyright (C) 2023 Contributors of PackageFactory.ComponentEngine
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
declare(strict_types=1);
22+
23+
namespace PackageFactory\ComponentEngine\Language\AST\Node\TemplateLiteral;
24+
25+
final class TemplateLiteralLines
26+
{
27+
/**
28+
* @var TemplateLiteralLine[]
29+
*/
30+
public readonly array $items;
31+
32+
public function __construct(TemplateLiteralLine ...$items)
33+
{
34+
$this->items = $items;
35+
}
36+
}

src/Language/AST/Node/TemplateLiteral/TemplateLiteralNode.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ final class TemplateLiteralNode extends Node
2929
{
3030
public function __construct(
3131
public readonly Range $rangeInSource,
32-
public readonly TemplateLiteralSegments $segments
32+
public readonly int $indentation,
33+
public readonly TemplateLiteralLines $lines
3334
) {
3435
}
3536
}

src/Language/Parser/BooleanLiteral/BooleanLiteralParser.php

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,33 @@
2424

2525
use PackageFactory\ComponentEngine\Framework\PHP\Singleton\Singleton;
2626
use PackageFactory\ComponentEngine\Language\AST\Node\BooleanLiteral\BooleanLiteralNode;
27-
use PackageFactory\ComponentEngine\Parser\Tokenizer\Scanner;
28-
use PackageFactory\ComponentEngine\Parser\Tokenizer\Token;
29-
use PackageFactory\ComponentEngine\Parser\Tokenizer\TokenType;
27+
use PackageFactory\ComponentEngine\Language\Lexer\Lexer;
28+
use PackageFactory\ComponentEngine\Language\Lexer\Token\TokenType;
29+
use PackageFactory\ComponentEngine\Language\Lexer\Token\TokenTypes;
3030

3131
final class BooleanLiteralParser
3232
{
3333
use Singleton;
3434

35-
/**
36-
* @param \Iterator<mixed,Token> $tokens
37-
* @return BooleanLiteralNode
38-
*/
39-
public function parse(\Iterator &$tokens): BooleanLiteralNode
35+
private static TokenTypes $TOKEN_TYPES_BOOLEAN_KEYWORDS;
36+
37+
private function __construct()
38+
{
39+
self::$TOKEN_TYPES_BOOLEAN_KEYWORDS ??= TokenTypes::from(
40+
TokenType::KEYWORD_TRUE,
41+
TokenType::KEYWORD_FALSE
42+
);
43+
}
44+
45+
public function parse(Lexer $lexer): BooleanLiteralNode
4046
{
41-
Scanner::assertType($tokens, TokenType::KEYWORD_TRUE, TokenType::KEYWORD_FALSE);
47+
$lexer->readOneOf(self::$TOKEN_TYPES_BOOLEAN_KEYWORDS);
4248

43-
$token = $tokens->current();
49+
$token = $lexer->getTokenUnderCursor();
4450
$value = $token->type === TokenType::KEYWORD_TRUE;
4551

46-
Scanner::skipOne($tokens);
47-
4852
return new BooleanLiteralNode(
49-
rangeInSource: $token->boundaries,
53+
rangeInSource: $token->rangeInSource,
5054
value: $value
5155
);
5256
}

src/Language/Parser/ComponentDeclaration/ComponentDeclarationParser.php

Lines changed: 41 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -28,150 +28,89 @@
2828
use PackageFactory\ComponentEngine\Language\AST\Node\ComponentDeclaration\ComponentNameNode;
2929
use PackageFactory\ComponentEngine\Language\AST\Node\Expression\ExpressionNode;
3030
use PackageFactory\ComponentEngine\Language\AST\Node\PropertyDeclaration\PropertyDeclarationNodes;
31+
use PackageFactory\ComponentEngine\Language\Lexer\Lexer;
32+
use PackageFactory\ComponentEngine\Language\Lexer\Token\TokenType;
33+
use PackageFactory\ComponentEngine\Language\Lexer\Token\TokenTypes;
3134
use PackageFactory\ComponentEngine\Language\Parser\Expression\ExpressionParser;
3235
use PackageFactory\ComponentEngine\Language\Parser\PropertyDeclaration\PropertyDeclarationParser;
3336
use PackageFactory\ComponentEngine\Parser\Source\Range;
34-
use PackageFactory\ComponentEngine\Parser\Tokenizer\Scanner;
35-
use PackageFactory\ComponentEngine\Parser\Tokenizer\Token;
36-
use PackageFactory\ComponentEngine\Parser\Tokenizer\TokenType;
3737

3838
final class ComponentDeclarationParser
3939
{
4040
use Singleton;
4141

42+
private static TokenTypes $TOKEN_TYPES_SPACE;
43+
4244
private ?PropertyDeclarationParser $propertyDeclarationParser = null;
4345
private ?ExpressionParser $returnParser = null;
4446

45-
/**
46-
* @param \Iterator<mixed,Token> $tokens
47-
* @return ComponentDeclarationNode
48-
*/
49-
public function parse(\Iterator &$tokens): ComponentDeclarationNode
47+
private function __construct()
5048
{
51-
$componentKeywordToken = $this->extractComponentKeywordToken($tokens);
52-
$name = $this->parseName($tokens);
53-
54-
$this->skipOpeningBracketToken($tokens);
49+
self::$TOKEN_TYPES_SPACE ??= TokenTypes::from(
50+
TokenType::SPACE,
51+
TokenType::END_OF_LINE
52+
);
53+
}
5554

56-
$props = $this->parseProps($tokens);
55+
public function parse(Lexer $lexer): ComponentDeclarationNode
56+
{
57+
$lexer->read(TokenType::KEYWORD_COMPONENT);
58+
$start = $lexer->getStartPosition();
59+
$lexer->skipSpace();
5760

58-
$this->skipReturnKeywordToken($tokens);
61+
$name = $this->parseName($lexer);
62+
$props = $this->parseProps($lexer);
63+
$return = $this->parseReturn($lexer);
5964

60-
$return = $this->parseReturn($tokens);
61-
$closingBracketToken = $this->extractClosingBracketToken($tokens);
65+
$lexer->read(TokenType::BRACKET_CURLY_CLOSE);
66+
$end = $lexer->getEndPosition();
6267

6368
return new ComponentDeclarationNode(
64-
rangeInSource: Range::from(
65-
$componentKeywordToken->boundaries->start,
66-
$closingBracketToken->boundaries->end
67-
),
69+
rangeInSource: Range::from($start, $end),
6870
name: $name,
6971
props: $props,
7072
return: $return
7173
);
7274
}
7375

74-
/**
75-
* @param \Iterator<mixed,Token> $tokens
76-
* @return Token
77-
*/
78-
private function extractComponentKeywordToken(\Iterator &$tokens): Token
76+
private function parseName(Lexer $lexer): ComponentNameNode
7977
{
80-
Scanner::assertType($tokens, TokenType::KEYWORD_COMPONENT);
81-
82-
$componentKeywordToken = $tokens->current();
78+
$lexer->read(TokenType::WORD);
79+
$componentNameToken = $lexer->getTokenUnderCursor();
8380

84-
Scanner::skipOne($tokens);
85-
Scanner::skipSpace($tokens);
86-
87-
return $componentKeywordToken;
88-
}
89-
90-
/**
91-
* @param \Iterator<mixed,Token> $tokens
92-
* @return ComponentNameNode
93-
*/
94-
private function parseName(\Iterator &$tokens): ComponentNameNode
95-
{
96-
Scanner::assertType($tokens, TokenType::STRING);
97-
98-
$componentNameToken = $tokens->current();
99-
100-
Scanner::skipOne($tokens);
101-
Scanner::skipSpace($tokens);
81+
$lexer->skipSpace();
10282

10383
return new ComponentNameNode(
104-
rangeInSource: $componentNameToken->boundaries,
84+
rangeInSource: $componentNameToken->rangeInSource,
10585
value: ComponentName::from($componentNameToken->value)
10686
);
10787
}
10888

109-
/**
110-
* @param \Iterator<mixed,Token> $tokens
111-
* @return void
112-
*/
113-
private function skipOpeningBracketToken(\Iterator &$tokens): void
114-
{
115-
Scanner::assertType($tokens, TokenType::BRACKET_CURLY_OPEN);
116-
Scanner::skipOne($tokens);
117-
Scanner::skipSpaceAndComments($tokens);
118-
}
119-
120-
/**
121-
* @param \Iterator<mixed,Token> $tokens
122-
* @return PropertyDeclarationNodes
123-
*/
124-
private function parseProps(\Iterator &$tokens): PropertyDeclarationNodes
89+
private function parseProps(Lexer $lexer): PropertyDeclarationNodes
12590
{
12691
$this->propertyDeclarationParser ??= PropertyDeclarationParser::singleton();
12792

128-
$items = [];
129-
while (Scanner::type($tokens) !== TokenType::KEYWORD_RETURN) {
130-
assert($this->propertyDeclarationParser !== null);
131-
$items[] = $this->propertyDeclarationParser->parse($tokens);
93+
$lexer->read(TokenType::BRACKET_CURLY_OPEN);
94+
$lexer->skipSpaceAndComments();
13295

133-
Scanner::skipSpaceAndComments($tokens);
96+
$items = [];
97+
while (!$lexer->peek(TokenType::KEYWORD_RETURN)) {
98+
$lexer->expect(TokenType::WORD);
99+
$items[] = $this->propertyDeclarationParser->parse($lexer);
100+
$lexer->skipSpaceAndComments();
134101
}
135102

136103
return new PropertyDeclarationNodes(...$items);
137104
}
138105

139-
/**
140-
* @param \Iterator<mixed,Token> $tokens
141-
* @return void
142-
*/
143-
private function skipReturnKeywordToken(\Iterator &$tokens): void
144-
{
145-
Scanner::assertType($tokens, TokenType::KEYWORD_RETURN);
146-
Scanner::skipOne($tokens);
147-
Scanner::skipSpaceAndComments($tokens);
148-
}
149-
150-
/**
151-
* @param \Iterator<mixed,Token> $tokens
152-
* @return ExpressionNode
153-
*/
154-
private function parseReturn(\Iterator &$tokens): ExpressionNode
106+
private function parseReturn(Lexer $lexer): ExpressionNode
155107
{
156-
$this->returnParser ??= new ExpressionParser(
157-
stopAt: TokenType::BRACKET_CURLY_CLOSE
158-
);
159-
160-
return $this->returnParser->parse($tokens);
161-
}
162-
163-
/**
164-
* @param \Iterator<mixed,Token> $tokens
165-
* @return Token
166-
*/
167-
private function extractClosingBracketToken(\Iterator &$tokens): Token
168-
{
169-
Scanner::assertType($tokens, TokenType::BRACKET_CURLY_CLOSE);
170-
171-
$closingBracketToken = $tokens->current();
108+
$this->returnParser ??= new ExpressionParser();
172109

173-
Scanner::skipOne($tokens);
110+
$lexer->read(TokenType::KEYWORD_RETURN);
111+
$lexer->readOneOf(self::$TOKEN_TYPES_SPACE);
112+
$lexer->skipSpaceAndComments();
174113

175-
return $closingBracketToken;
114+
return $this->returnParser->parse($lexer);
176115
}
177116
}

0 commit comments

Comments
 (0)