-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Midhun Devasia
committed
Apr 25, 2021
0 parents
commit 3fa12da
Showing
29 changed files
with
2,013 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.travis.yml export-ignore | ||
.gitattributes export-ignore | ||
.gitignore export-ignore | ||
tests export-ignore | ||
phpunit.xml.dist export-ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
vendor/ | ||
phpunit.xml | ||
composer.lock | ||
*.cache | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
language: php | ||
|
||
php: | ||
- 7.2 | ||
- 7.4 | ||
- 8.0.1 | ||
|
||
before_script: | ||
- composer install | ||
|
||
script: | ||
- ./vendor/bin/phpunit --testdox tests |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# json-ast : JSON to AST parser in PHP | ||
|
||
[![Latest Stable Version](https://img.shields.io/packagist/v/midhundevasia/json-ast.svg?style=flat-square)](https://packagist.org/packages/midhundevasia/json-ast) | ||
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.0-8892BF.svg?style=flat-square)](https://php.net/) | ||
[![Build Status](https://travis-ci.com/midhundevasia/json-ast.svg?branch=master)](https://travis-ci.com/midhundevasia/json-ast) | ||
|
||
## Install | ||
$ composer require midhundevasia/json-ast | ||
|
||
## Usage | ||
<?php | ||
use JsonAst\Parser; | ||
$parser = new Parser(); | ||
$parser->parse( | ||
'{"hello" : "World"}', | ||
['loc' => true, 'source' => null] | ||
); | ||
|
||
|
||
## Tests | ||
$ ./vendor/bin/phpunit --testdox tests | ||
|
||
## Todo | ||
- write more test cases | ||
- code coverage | ||
|
||
## License | ||
json-ast is licensed under GNU General Public License (GPLv3) - see the `LICENSE` file for details. | ||
|
||
## Credits | ||
Inspired from following repositories. | ||
|
||
https://github.com/vtrushin/json-to-ast | ||
https://github.com/vtrushin/code-error-fragment | ||
|
||
##### Development | ||
$ vendor/bin/phpcbf src | ||
$ vendor/bin/php-cs-fixer fix src |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "midhundevasia/json-ast", | ||
"type": "library", | ||
"version" : "0.0.1", | ||
"description": "JSON to AST parser in PHP", | ||
"homepage": "https://github.com/midhundevasia/json-ast", | ||
"license": ["GPL-3.0+"], | ||
"authors": [ | ||
{ | ||
"name": "Midhun Devasia", | ||
"email": "[email protected]", | ||
"homepage": "http://midhundev.asia" | ||
} | ||
], | ||
"keywords": [ | ||
"json", "json-ast", "ast parser", "json ast", "json parser" | ||
], | ||
"support": { | ||
"issues": "https://github.com/midhundevasia/json-ast/issues" | ||
}, | ||
"require": { | ||
"php": ">=7.2" | ||
}, | ||
"require-dev": { | ||
"phpunit/phpunit": "^8", | ||
"squizlabs/php_codesniffer": "^3.0@dev", | ||
"friendsofphp/php-cs-fixer": "^2.19@dev" | ||
}, | ||
"autoload": { | ||
"psr-4": { "JsonAst\\": "src/" }, | ||
"exclude-from-classmap": [ | ||
"/tests/" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
|
||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd" | ||
backupGlobals="false" | ||
colors="true" | ||
bootstrap="vendor/autoload.php" | ||
failOnRisky="true" | ||
failOnWarning="true" | ||
> | ||
<php> | ||
<ini name="error_reporting" value="-1" /> | ||
</php> | ||
|
||
<testsuites> | ||
<testsuite name="JSON AST Test Suite"> | ||
<directory>./tests/</directory> | ||
</testsuite> | ||
</testsuites> | ||
|
||
<filter> | ||
<whitelist> | ||
<directory>./src</directory> | ||
<exclude> | ||
<directory>./tests</directory> | ||
<directory>./vendor</directory> | ||
</exclude> | ||
</whitelist> | ||
</filter> | ||
|
||
</phpunit> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
namespace JsonAst\Exception; | ||
|
||
use JsonAst\Helper\CodeFragment; | ||
|
||
class Exception | ||
{ | ||
public function exceptionHandler($exception) | ||
{ | ||
print 'SyntaxError: ' . $exception->getMessage() . PHP_EOL; | ||
} | ||
|
||
public function getError() | ||
{ | ||
|
||
} | ||
|
||
protected function setErrorMessage($message, $input, $line, $column, $source) | ||
{ | ||
$code = (new CodeFragment)::getFragment($input, $line, $column, []); | ||
$message = $line ? $message . "\n" . $code : $message; | ||
return $message; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
|
||
namespace JsonAst\Exception; | ||
|
||
class ParserException extends Exception | ||
{ | ||
const UNEXPECTED_END = 1; | ||
const UNEXPECTED_TOKEN = 2; | ||
|
||
public function __construct($type, $input, $tokenList, $index, $source) | ||
{ | ||
switch ($type) { | ||
case self::UNEXPECTED_END: | ||
$this->unexpectedEnd($input, $tokenList, $source); | ||
break; | ||
|
||
case self::UNEXPECTED_TOKEN: | ||
$this->unexpectedToken($input, $tokenList, $index, $source); | ||
break; | ||
} | ||
} | ||
|
||
public function unexpectedEnd($input, $tokenList, $source) | ||
{ | ||
$loc = count($tokenList) > 0 | ||
? $tokenList[count($tokenList) - 1]['loc']['end'] | ||
: ['line' => 1, 'column' => 1]; | ||
|
||
@set_exception_handler(array($this, 'exceptionHandler')); | ||
throw new \Exception( | ||
$this->setErrorMessage( | ||
'Unexpected end of input', | ||
$input, | ||
$loc['line'], | ||
$loc['column'], | ||
$source | ||
) | ||
); | ||
} | ||
|
||
public function unexpectedToken($input, $tokenList, $index, $source) | ||
{ | ||
$line = $tokenList[$index]['loc']['start']['line']; | ||
$column = $tokenList[$index]['loc']['start']['column']; | ||
$startOffset = $tokenList[$index]['loc']['start']['offset']; | ||
$endOffset = $tokenList[$index]['loc']['end']['offset']; | ||
@set_exception_handler(array($this, 'exceptionHandler')); | ||
$token = substr($input, $startOffset , 1); | ||
throw new \Exception( | ||
$this->setErrorMessage( | ||
sprintf( | ||
'Unexpected token <%s> at %d:%d', $token, $line, $column | ||
), | ||
$input, | ||
$line, | ||
$column, | ||
$source | ||
) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
namespace JsonAst\Exception; | ||
|
||
class TokenizerException extends Exception | ||
{ | ||
const UNEXPECTED_SYMBOL = 1; | ||
|
||
public function __construct($message, $type, $input, $line, $column, $source) | ||
{ | ||
$this->line = $line; | ||
$this->column = $column; | ||
$this->input = $input; | ||
$this->source = $source; | ||
|
||
switch ($type) { | ||
case self::UNEXPECTED_SYMBOL: | ||
$this->unexpectedSymbol($message, $input, $source); | ||
break; | ||
} | ||
} | ||
|
||
public function unexpectedSymbol($symbol) | ||
{ | ||
@set_exception_handler(array($this, 'exceptionHandler')); | ||
throw new \Exception( | ||
$this->setErrorMessage( | ||
sprintf( | ||
'Unexpected symbol <%s> at %d:%d', | ||
$symbol, | ||
$this->line, | ||
$this->column | ||
), | ||
$this->input, | ||
$this->line, | ||
$this->column, | ||
$this->source | ||
) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
|
||
namespace JsonAst\Helper; | ||
|
||
class CodeFragment | ||
{ | ||
public static function getFragment($code, $linePos, $columnPos, $settings) | ||
{ | ||
$settings = array_merge_recursive( | ||
[ | ||
'extraLines' => 2, | ||
'tabSize' => 4 | ||
], | ||
$settings | ||
); | ||
$lines = preg_split('/\r\n?|\n|\f/', $code); | ||
$startLinePos = max(1, $linePos - $settings['extraLines']) - 1; | ||
$endLinePos = min($linePos + $settings['extraLines'], count($lines)); | ||
$maxNumLength = strlen($endLinePos); | ||
$previousLines = self::printLines($lines, $startLinePos, $linePos, $maxNumLength, $settings); | ||
$targetLineBeforeCursor = self::printLine( | ||
substr( | ||
$lines[$linePos - 1], | ||
0, | ||
$columnPos - 1 | ||
), | ||
$linePos, | ||
$maxNumLength, | ||
$settings | ||
); | ||
|
||
$cursorLine = str_repeat(' ', strlen($targetLineBeforeCursor)) . '^'; | ||
$nextLines = self::printLines($lines, $linePos, $endLinePos, $maxNumLength, $settings); | ||
|
||
return implode( | ||
"\n", | ||
array_filter( | ||
[$previousLines, $cursorLine, $nextLines], | ||
function ($value) { | ||
return $value ?? false; | ||
} | ||
) | ||
); | ||
} | ||
|
||
private static function printLines($lines, $start, $end, $maxNumLength, $settings) | ||
{ | ||
$code = array_slice($lines, $start, $end); | ||
array_walk( | ||
$code, | ||
function (&$line, $index, $data) { | ||
$line = self::printLine($line, $data['start'] + $index + 1, $data['max'], $data['settings']); | ||
}, | ||
['start' => $start, 'end' => $end, 'max' => $maxNumLength, 'settings' => $settings] | ||
); | ||
|
||
return implode("\n", $code); | ||
} | ||
|
||
private static function printLine($line, $position, $maxNumLength, $settings) | ||
{ | ||
$formattedNum = str_pad($position, $maxNumLength, ' '); | ||
$tabReplacement = str_repeat(' ', $settings['tabSize']); | ||
|
||
return $formattedNum . ' | ' . preg_replace('/\t/', $tabReplacement, $line); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
namespace JsonAst\Helper; | ||
|
||
class Location | ||
{ | ||
public static function loc( | ||
$startLine, | ||
$startColumn, | ||
$startOffset, | ||
$endLine, | ||
$endColumn, | ||
$endOffset, | ||
$source | ||
) { | ||
return [ | ||
'start' => [ | ||
'line' => $startLine, | ||
'column' => $startColumn, | ||
'offset' => $startOffset | ||
], | ||
'end' => [ | ||
'line' => $endLine, | ||
'column' => $endColumn, | ||
'offset' => $endOffset | ||
], | ||
'source' => $source ?? null | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
namespace JsonAst\Helper; | ||
|
||
class NumberHelper | ||
{ | ||
public static function isDigit1to9($char) | ||
{ | ||
return ($char >= '1' && $char <= '9'); | ||
} | ||
|
||
public static function isExp($char) | ||
{ | ||
return ($char === 'e' || $char === 'E'); | ||
} | ||
|
||
public static function isDigit($char) | ||
{ | ||
return ($char >= '0' && $char <= '9'); | ||
} | ||
|
||
public static function isHex($char) | ||
{ | ||
return ( | ||
self::isDigit($char) | ||
|| ($char >= 'a' && $char <= 'f') | ||
|| ($char >= 'A' && $char <= 'F') | ||
); | ||
} | ||
} |
Oops, something went wrong.