Skip to content

Commit

Permalink
Added env lexer and printer
Browse files Browse the repository at this point in the history
  • Loading branch information
jaxwilko committed Jan 4, 2023
1 parent 3dfad63 commit c5de01a
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
94 changes: 94 additions & 0 deletions src/Parser/EnvLexer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace Winter\LaravelConfigWriter\Parser;

use Winter\LaravelConfigWriter\Contracts\DataFileLexerInterface;
use Winter\LaravelConfigWriter\Exceptions\EnvParserException;

class EnvLexer implements DataFileLexerInterface
{
public const T_ENV = 'T_ENV';
public const T_QUOTED_ENV = 'T_QUOTED_ENV';
public const T_ENV_NO_VALUE = 'T_ENV_NO_VALUE';
public const T_WHITESPACE = 'T_WHITESPACE';
public const T_COMMENT = 'T_COMMENT';

protected $tokenMap = [
'/^([\w]*)="?(.+)["|$]/' => self::T_QUOTED_ENV,
'/^([\w]*)="?(.*)(?:"|$)/' => self::T_ENV,
'/^(\w+)/' => self::T_ENV_NO_VALUE,
'/^(\s+)/' => self::T_WHITESPACE,
'/(#[\w\s]).*/' => self::T_COMMENT,
];

public function parse(array $src): array
{
$tokens = [];

foreach ($src as $line => $str) {
$read = 0;
do {
$result = $this->match($str, $line, $read);

if (is_null($result)) {
throw new EnvParserException("Unable to parse line " . ($line + 1) . ".");
}

$tokens[] = $result;

$read += strlen($result['match']);
} while ($read < strlen($str));
}

return $tokens;
}

public function match(string $str, int $line, int $offset): ?array
{
$str = substr($str, $offset);

foreach ($this->tokenMap as $pattern => $name) {
if (!preg_match($pattern, $str, $matches)) {
continue;
}

switch ($name) {
case static::T_ENV:
case static::T_QUOTED_ENV:
return [
'match' => $matches[0],
'env' => [
'key' => $matches[1],
'value' => $matches[2],
],
'token' => $name,
'line' => $line + 1
];
case static::T_ENV_NO_VALUE:
return [
'match' => $matches[0],
'env' => [
'key' => $matches[1],
'value' => '',
],
'token' => $name,
'line' => $line + 1
];
case static::T_COMMENT:
return [
'match' => $matches[0],
'token' => $name,
'line' => $line + 1
];
case static::T_WHITESPACE:
return [
'match' => $matches[1],
'token' => $name,
'line' => $line + 1
];
}
}

return null;
}
}
34 changes: 34 additions & 0 deletions src/Printer/EnvPrinter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Winter\LaravelConfigWriter\Printer;

use Winter\LaravelConfigWriter\Contracts\DataFilePrinterInterface;
use Winter\LaravelConfigWriter\Parser\EnvLexer;

class EnvPrinter implements DataFilePrinterInterface
{
public function render(array $ast): string
{
$output = '';

foreach ($ast as $item) {
switch ($item['token']) {
case EnvLexer::T_ENV:
$output .= sprintf('%s=%s', $item['env']['key'], $item['env']['value']);
break;
case EnvLexer::T_QUOTED_ENV:
$output .= sprintf('%s="%s"', $item['env']['key'], $item['env']['value']);
break;
case EnvLexer::T_ENV_NO_VALUE:
$output .= $item['env']['key'];
break;
case EnvLexer::T_COMMENT:
case EnvLexer::T_WHITESPACE:
$output .= $item['match'];
break;
}
}

return $output;
}
}

0 comments on commit c5de01a

Please sign in to comment.