Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Feature: Try out parsica #20

Draft
wants to merge 21 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a6bc964
WIP: Feature: Try out parsica
mhsdesign May 18, 2023
a3ef1fc
WIP: Parsica use bind instead of Parser::make
mhsdesign May 18, 2023
6f94ba3
WIP: Parsica rewrite Precedence to only use @api 50% slower due to `g…
mhsdesign May 19, 2023
6354184
WIP: Parsica speed up Precedence via custom strings parser
mhsdesign May 19, 2023
41b94c7
WIP: Parsica add MatchParser
mhsdesign May 19, 2023
590a5f1
WIP: Parsica NumberLiteralParser support for funny number formats
mhsdesign May 19, 2023
c58a9c9
WIP: Parsica TagNode Parsing
mhsdesign May 19, 2023
fc5fbf7
WIP: Parsica Improve Precedence handling and extract parser into sepa…
mhsdesign May 19, 2023
3870cd6
WIP: Parsica parse TemplateLiteralNode
mhsdesign May 19, 2023
ab5ddd3
WIP: Parsica cleanup MatchParser
mhsdesign May 19, 2023
df231cd
WIP: Parsica minor cleanups
mhsdesign May 19, 2023
018c156
WIP: Parsica implement Module Import Export Component Enum and Struct
mhsdesign May 19, 2023
ad4b62a
WIP: Parsica implement TagAttributes, Refine `SourcePath` handling en…
mhsdesign May 19, 2023
893015d
WIP: Parsica add correct whitespace handling in html tags
mhsdesign May 20, 2023
8aad772
WIP: Parsica simple comment handling in few places to make tests happ…
mhsdesign May 20, 2023
cc2c9c7
WIP: Parsica expression brace handling ()
mhsdesign May 21, 2023
1e87337
WIP: Parsica match node with multiple expressions as match arm
mhsdesign May 21, 2023
0b23265
WIP: Parsica clean up unnecessary flyweights (singletons)
mhsdesign May 21, 2023
b579257
TASK: ExpressionParser use lazy identity for nested parsers
mhsdesign May 29, 2023
0fa187a
TASK: Add instance cache for all expressionRootParser
mhsdesign May 29, 2023
8788d30
Merge branch 'main' into feature/parsica
grebaldi Jun 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"test": "./scripts/test"
},
"require": {
"php": ">=8.1"
"php": ">=8.1",
"parsica-php/parsica": "^0.8.1"
},
"autoload": {
"psr-4": {
Expand Down
11 changes: 7 additions & 4 deletions src/Definition/Precedence.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@

use PackageFactory\ComponentEngine\Parser\Tokenizer\TokenType;



enum Precedence: int
{
//
Expand Down Expand Up @@ -81,8 +79,13 @@ public static function forTokenType(TokenType $tokenType): self
};
}

public function mustStopAt(TokenType $tokenType): bool
public function mustStopAt(self $precedence): bool
{
return $precedence->value <= $this->value;
}

public function mustStopAtTokenType(TokenType $tokenType): bool
{
return self::forTokenType($tokenType)->value <= $this->value;
return $this->mustStopAt(self::forTokenType($tokenType));
}
}
7 changes: 7 additions & 0 deletions src/Definition/UnaryOperator.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,11 @@ public static function fromTokenType(TokenType $tokenType): self
default => throw new \Exception('@TODO: Unknown Unary Operator')
};
}

public function toPrecedence(): Precedence
{
return match ($this) {
self::NOT => Precedence::UNARY
};
}
}
2 changes: 1 addition & 1 deletion src/Module/Loader/ModuleFile/ModuleFileLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ final class ModuleFileLoader implements LoaderInterface
{
public function resolveTypeOfImport(ImportNode $importNode): TypeInterface
{
$pathToImportFrom = $importNode->source->path->resolveRelationTo(
$pathToImportFrom = $importNode->sourcePath->resolveRelationTo(
Path::fromString($importNode->path)
);
$source = Source::fromFile($pathToImportFrom->value);
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/AccessChainSegmentNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

final class AccessChainSegmentNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly AccessType $accessType,
public readonly IdentifierNode $accessor
) {
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/AccessChainSegmentNodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class AccessChainSegmentNodes implements \JsonSerializable
*/
public readonly array $items;

private function __construct(
public function __construct(
AccessChainSegmentNode ...$items
) {
$this->items = $items;
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/AccessNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

final class AccessNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly ExpressionNode $root,
public readonly AccessChainSegmentNodes $chain
) {
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/AttributeNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

final class AttributeNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly string $name,
public readonly ExpressionNode | StringLiteralNode $value
) {
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/AttributeNodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class AttributeNodes implements \JsonSerializable
*/
public readonly array $items;

private function __construct(
public function __construct(
AttributeNode ...$items
) {
$itemsAsHashMap = [];
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/BinaryOperationNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

final class BinaryOperationNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly ExpressionNode $left,
public readonly BinaryOperator $operator,
public readonly ExpressionNode $right
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/BooleanLiteralNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

final class BooleanLiteralNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly bool $value
) {
}
Expand Down
11 changes: 3 additions & 8 deletions src/Parser/Ast/ComponentDeclarationNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@

namespace PackageFactory\ComponentEngine\Parser\Ast;

use PackageFactory\ComponentEngine\Parser\Source\Source;
use PackageFactory\ComponentEngine\Parser\Parser\ComponentDeclaration\ComponentDeclarationParser;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Scanner;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Token;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Tokenizer;
use PackageFactory\ComponentEngine\Parser\Tokenizer\TokenType;

final class ComponentDeclarationNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly string $componentName,
public readonly PropertyDeclarationNodes $propertyDeclarations,
public readonly ExpressionNode $returnExpression
Expand All @@ -39,11 +38,7 @@ private function __construct(

public static function fromString(string $componentDeclarationAsString): self
{
return self::fromTokens(
Tokenizer::fromSource(
Source::fromString($componentDeclarationAsString)
)->getIterator()
);
return ComponentDeclarationParser::parseFromString($componentDeclarationAsString);
}

/**
Expand Down
9 changes: 3 additions & 6 deletions src/Parser/Ast/EnumDeclarationNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

namespace PackageFactory\ComponentEngine\Parser\Ast;

use PackageFactory\ComponentEngine\Parser\Parser\EnumDeclaration\EnumDeclarationParser;
use PackageFactory\ComponentEngine\Parser\Source\Source;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Scanner;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Token;
Expand All @@ -30,19 +31,15 @@

final class EnumDeclarationNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly string $enumName,
public readonly EnumMemberDeclarationNodes $memberDeclarations
) {
}

public static function fromString(string $enumDeclarationAsString): self
{
return self::fromTokens(
Tokenizer::fromSource(
Source::fromString($enumDeclarationAsString)
)->getIterator()
);
return EnumDeclarationParser::parseFromString($enumDeclarationAsString);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EnumDeclarationNode::fromString might as well be removed then.

}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/EnumMemberDeclarationNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

final class EnumMemberDeclarationNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly string $name,
public readonly null|StringLiteralNode|NumberLiteralNode $value
) {
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/EnumMemberDeclarationNodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class EnumMemberDeclarationNodes implements \JsonSerializable
*/
public readonly array $items;

private function __construct(
public function __construct(
EnumMemberDeclarationNode ...$items
) {
$itemsAsHashMap = [];
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/ExportNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

final class ExportNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly ComponentDeclarationNode | EnumDeclarationNode | StructDeclarationNode $declaration,
) {
}
Expand Down
30 changes: 18 additions & 12 deletions src/Parser/Ast/ExportNodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,35 @@

namespace PackageFactory\ComponentEngine\Parser\Ast;

use PackageFactory\ComponentEngine\Parser\Ast\ComponentDeclarationNode;
use PackageFactory\ComponentEngine\Parser\Ast\EnumDeclarationNode;
use PackageFactory\ComponentEngine\Parser\Ast\InterfaceDeclarationNode;

final class ExportNodes implements \JsonSerializable
{
/**
* @var array<string,ExportNode>
*/
public readonly array $items;

/**
* @param array<string,ExportNode> $items
*/
private function __construct(
array $items
public function __construct(
ExportNode ...$items
) {
$this->items = $items;
$itemsAsHashMap = [];
foreach ($items as $item) {
$name = match ($item->declaration::class) {
ComponentDeclarationNode::class => $item->declaration->componentName,
StructDeclarationNode::class => $item->declaration->structName,
EnumDeclarationNode::class => $item->declaration->enumName
};
if (array_key_exists($name, $itemsAsHashMap)) {
throw new \Exception('@TODO: Duplicate Export ' . $name);
}
$itemsAsHashMap[$name] = $item;
}

$this->items = $itemsAsHashMap;
}

public static function empty(): self
{
return new self([]);
return new self();
}

public function withAddedExport(ExportNode $export): self
Expand All @@ -59,7 +65,7 @@ public function withAddedExport(ExportNode $export): self
throw new \Exception('@TODO: Duplicate Export ' . $name);
}

return new self([...$this->items, ...[$name => $export]]);
return new self(...[...$this->items, ...[$name => $export]]);
}

public function get(string $name): ?ExportNode
Expand Down
14 changes: 5 additions & 9 deletions src/Parser/Ast/ExpressionNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,23 @@
namespace PackageFactory\ComponentEngine\Parser\Ast;

use PackageFactory\ComponentEngine\Definition\Precedence;
use PackageFactory\ComponentEngine\Parser\Source\Source;
use PackageFactory\ComponentEngine\Parser\Parser\Expression\ExpressionParser;
use PackageFactory\ComponentEngine\Parser\Tokenizer\LookAhead;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Scanner;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Token;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Tokenizer;
use PackageFactory\ComponentEngine\Parser\Tokenizer\TokenType;

final class ExpressionNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly IdentifierNode | NumberLiteralNode | BinaryOperationNode | UnaryOperationNode | AccessNode | TernaryOperationNode | TagNode | StringLiteralNode | MatchNode | TemplateLiteralNode | BooleanLiteralNode | NullLiteralNode $root
) {
}

/** @deprecated */
public static function fromString(string $expressionAsString): self
{
return self::fromTokens(
Tokenizer::fromSource(
Source::fromString($expressionAsString)
)->getIterator()
);
return ExpressionParser::parseFromString($expressionAsString);
}

/**
Expand Down Expand Up @@ -123,7 +119,7 @@ public static function fromTokens(\Iterator $tokens, Precedence $precedence = Pr

Scanner::skipSpaceAndComments($tokens);

while (!Scanner::isEnd($tokens) && !$precedence->mustStopAt(Scanner::type($tokens))) {
while (!Scanner::isEnd($tokens) && !$precedence->mustStopAtTokenType(Scanner::type($tokens))) {
switch (Scanner::type($tokens)) {
case TokenType::OPERATOR_BOOLEAN_AND:
case TokenType::OPERATOR_BOOLEAN_OR:
Expand Down
2 changes: 1 addition & 1 deletion src/Parser/Ast/ExpressionNodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ final class ExpressionNodes implements \JsonSerializable
*/
public readonly array $items;

private function __construct(
public function __construct(
ExpressionNode ...$items
) {
$this->items = $items;
Expand Down
9 changes: 3 additions & 6 deletions src/Parser/Ast/IdentifierNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

namespace PackageFactory\ComponentEngine\Parser\Ast;

use PackageFactory\ComponentEngine\Parser\Parser\Identifier\IdentifierParser;
use PackageFactory\ComponentEngine\Parser\Source\Source;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Scanner;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Token;
Expand All @@ -30,18 +31,14 @@

final class IdentifierNode implements \JsonSerializable
{
private function __construct(
public function __construct(
public readonly string $value
) {
}

public static function fromString(string $identifierAsString): self
{
return self::fromTokens(
Tokenizer::fromSource(
Source::fromString($identifierAsString)
)->getIterator()
);
return IdentifierParser::get()->tryString($identifierAsString)->output();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole method IdentifierNode::fromString should be moved to IdentifierParser::parseFromString I think.

}

/**
Expand Down
7 changes: 4 additions & 3 deletions src/Parser/Ast/ImportNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@
namespace PackageFactory\ComponentEngine\Parser\Ast;

use PackageFactory\ComponentEngine\Parser\Ast\IdentifierNode;
use PackageFactory\ComponentEngine\Parser\Source\Path;
use PackageFactory\ComponentEngine\Parser\Source\Source;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Scanner;
use PackageFactory\ComponentEngine\Parser\Tokenizer\Token;
use PackageFactory\ComponentEngine\Parser\Tokenizer\TokenType;

final class ImportNode implements \JsonSerializable
{
private function __construct(
public readonly Source $source,
public function __construct(
public readonly Path $sourcePath,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent move!

public readonly string $path,
public readonly IdentifierNode $name
) {
Expand Down Expand Up @@ -64,7 +65,7 @@ public static function fromTokens(\Iterator $tokens): \Iterator

while (true) {
$identifier = IdentifierNode::fromTokens($tokens);
yield new self($source, $path, $identifier);
yield new self($source->path, $path, $identifier);

Scanner::skipSpaceAndComments($tokens);
if (Scanner::type($tokens) === TokenType::COMMA) {
Expand Down
Loading