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

Support for properties in NEON statement syntax in section services - PART 2 #73

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
"dev-master": "3.5-dev"
}
}
}
4 changes: 2 additions & 2 deletions src/Neon/Decoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function parseToNode(string $input): Node
{
$lexer = new Lexer;
$parser = new Parser;
$tokens = $lexer->tokenize($input);
return $parser->parse($tokens);
$stream = $lexer->tokenize($input);
return $parser->parse($stream);
}
}
9 changes: 9 additions & 0 deletions src/Neon/Exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,13 @@
*/
class Exception extends \Exception
{
public ?Position /*readonly*/ $position = null;


public function __construct(string $message, ?Position $position = null, ?\Throwable $previous = null)
{
$message .= $position ? ' ' . $position : '';
$this->position = $position;
parent::__construct($message, 0, $previous);
}
}
32 changes: 26 additions & 6 deletions src/Neon/Lexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,45 @@ public function tokenize(string $input): TokenStream
}

$types = array_keys(self::Patterns);
$offset = 0;
$position = new Position;

$tokens = [];
foreach ($matches as $match) {
$type = $types[count($match) - 2];
$tokens[] = new Token($match[0], $type === Token::Char ? $match[0] : $type);
$offset += strlen($match[0]);
$tokens[] = new Token($type === Token::Char ? $match[0] : $type, $match[0], $position);
$position = $this->advance($position, $match[0]);
}

$tokens[] = new Token(Token::End, '', $position);

$stream = new TokenStream($tokens);
if ($offset !== strlen($input)) {
$s = str_replace("\n", '\n', substr($input, $offset, 40));
$stream->error("Unexpected '$s'", count($tokens));
if ($position->offset !== strlen($input)) {
$s = str_replace("\n", '\n', substr($input, $position->offset, 40));
throw new Exception("Unexpected '$s'", $position);
}

return $stream;
}


private function advance(Position $position, string $str): Position
{
if ($lines = substr_count($str, "\n")) {
return new Position(
$position->line + $lines,
strlen($str) - strrpos($str, "\n"),
$position->offset + strlen($str),
);
} else {
return new Position(
$position->line,
$position->column + strlen($str),
$position->offset + strlen($str),
);
}
}


public static function requiresDelimiters(string $s): bool
{
return preg_match('~[\x00-\x1F]|^[+-.]?\d|^(true|false|yes|no|on|off|null)$~Di', $s)
Expand Down
4 changes: 2 additions & 2 deletions src/Neon/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ abstract class Node implements \IteratorAggregate
{
public ?int $startTokenPos = null;
public ?int $endTokenPos = null;
public ?int $startLine = null;
public ?int $endLine = null;
public ?Position $start = null;
public ?Position $end = null;


abstract public function toValue(): mixed;
Expand Down
9 changes: 9 additions & 0 deletions src/Neon/Node/LiteralNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,13 @@ public function toString(): string
throw new \LogicException;
}
}


public function setMemberFlag(): void
{
if(is_string($this->value) && str_starts_with($this->value, '::')){
$this->value .= '()';
}
}

}
8 changes: 4 additions & 4 deletions src/Neon/Node/StringNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function toValue(): string
}


public static function parse(string $s): string
public static function parse(string $s, Nette\Neon\Position $position): string
{
if (preg_match('#^...\n++([\t ]*+)#', $s, $m)) { // multiline
$res = substr($s, 3, -3);
Expand All @@ -52,14 +52,14 @@ public static function parse(string $s): string

return preg_replace_callback(
'#\\\\(?:ud[89ab][0-9a-f]{2}\\\\ud[c-f][0-9a-f]{2}|u[0-9a-f]{4}|.)#i',
function (array $m): string {
function (array $m) use ($position): string {
$sq = $m[0];
if (isset(self::EscapeSequences[$sq[1]])) {
return self::EscapeSequences[$sq[1]];
} elseif ($sq[1] === 'u' && strlen($sq) >= 6) {
return json_decode('"' . $sq . '"') ?? throw new Nette\Neon\Exception("Invalid UTF-8 sequence $sq");
return json_decode('"' . $sq . '"') ?? throw new Nette\Neon\Exception("Invalid UTF-8 sequence $sq", $position);
} else {
throw new Nette\Neon\Exception("Invalid escaping sequence $sq");
throw new Nette\Neon\Exception("Invalid escaping sequence $sq", $position);
}
},
$res,
Expand Down
Loading