Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
75c33ac
add unsafe mode (Step: 1)
bluelovers Jan 17, 2017
4cc7250
add unsafe mode (Step: 2)
bluelovers Jan 17, 2017
bf33cbf
add unsafe mode (Step: 3)
bluelovers Jan 17, 2017
4639bce
add unsafe mode (Step: 4)
bluelovers Jan 17, 2017
024e128
add unsafe mode (Step: 5)
bluelovers Jan 17, 2017
e48e512
add unsafe mode (Step: 6)
bluelovers Jan 17, 2017
e53fc10
add unsafe mode (Step: 7)
bluelovers Jan 17, 2017
138842a
add unsafe mode (Step: 8)
bluelovers Jan 17, 2017
11cb3b7
add unsafe mode (Step: 9)
bluelovers Jan 17, 2017
0c711ae
add unsafe mode (Step: 10)
bluelovers Jan 17, 2017
986c3d4
Merge branch 'git-lazy-ci/1484656957.832194'
bluelovers Jan 17, 2017
5ba1e3a
support single-quoted 'ig"n\"o\'r\'e' = "ig\"n\"o'r'e", 'ignore' = "i…
bluelovers Jan 17, 2017
8131b42
support single-quoted 'ig"n\"o\'r\'e' = "ig\"n\"o'r'e", 'ignore' = "i…
bluelovers Jan 17, 2017
6374f7e
support single-quoted 'ig"n\"o\'r\'e' = "ig\"n\"o'r'e", 'ignore' = "i…
bluelovers Jan 17, 2017
cb5dc50
support single-quoted 'ig"n\"o\'r\'e' = "ig\"n\"o'r'e", 'ignore' = "i…
bluelovers Jan 17, 2017
e814dcc
support single-quoted 'ig"n\"o\'r\'e' = "ig\"n\"o'r'e", 'ignore' = "i…
bluelovers Jan 17, 2017
b0442b0
support single-quoted 'ig"n\"o\'r\'e' = "ig\"n\"o'r'e", 'ignore' = "i…
bluelovers Jan 17, 2017
bad6809
Merge branch 'git-lazy-ci/1484660281.606462'
bluelovers Jan 17, 2017
dcb75b0
. (Step: 1)
bluelovers Jan 17, 2017
5abdb85
. (Step: 2)
bluelovers Jan 17, 2017
f497e0f
.
bluelovers Jan 17, 2017
6020ed4
.
bluelovers Jan 18, 2017
5974f8c
. (Step: 1)
bluelovers Mar 9, 2017
b717540
. (Step: 2)
bluelovers Mar 9, 2017
4d42e65
. (Step: 3)
bluelovers Mar 9, 2017
11da80b
. (Step: 4)
bluelovers Mar 9, 2017
64f4cd8
. (Step: 5)
bluelovers Mar 9, 2017
a4360cf
. (Step: 6)
bluelovers Mar 9, 2017
85a2854
. (Step: 7)
bluelovers Mar 9, 2017
caf0f88
. (Step: 8)
bluelovers Mar 9, 2017
f70c121
Merge branch 'git-lazy-ci/1489066616.326482' into develop
bluelovers Mar 9, 2017
b1a336b
.
bluelovers Mar 9, 2017
f540ce3
.
bluelovers Mar 9, 2017
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
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=true
indent_style=tab
tab_width=4

[{.babelrc,.stylelintrc,.eslintrc,*.bowerrc,*.jsb3,*.jsb2,*.json}]
indent_style=space
indent_size=2

[{*.yml,*.yaml}]
indent_style=space
indent_size=2

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ temp/
tmp/


/test/temp/*
!/test/temp/.gitkeep
.idea
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
[![NPM version](https://badge.fury.io/js/json-parser.svg)](http://badge.fury.io/js/json-parser)
[![Build Status](https://travis-ci.org/kaelzhang/node-json-parser.svg?branch=master)](https://travis-ci.org/kaelzhang/node-json-parser)
<!-- [![Dependency Status](https://david-dm.org/kaelzhang/node-json-parser.svg)](https://david-dm.org/kaelzhang/node-json-parser) -->

# json-parser

JSON parser to parse JSON object and MAINTAIN comments.

This is a very low level module. For most situations, recommend to use [`comment-json`](https://www.npmjs.org/package/comment-json) instead.

## this version

this version base on kaelzhang/node-json-parser

but add support load unsafe/un-strict json

see test file

## Install

```sh
$ npm install json-parser --save
$ npm install json-parser2 --save
```

## Usage
Expand Down
288 changes: 4 additions & 284 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,286 +1,6 @@
'use strict';

var esprima = require('esprima');

exports.tokenize = tokenize;
exports.parse = parse;


function tokenize (code) {
var list = esprima.tokenize(code, {
comment: true,
loc: true
});
if (list.comment) {
return list;
}

var result = [];
var comments = [];
list.map(function (t) {
if (t.type === 'LineComment') {
t.type = 'Line';
comments.push(t);
} else if (t.type === 'BlockComment') {
t.type = 'Block';
comments.push(t);
} else {
result.push(t);
}
});
result.comments = comments;
return result;
}

var tokens;
var current;
var index;
var reviver;
var remove_comments;

function parse (code, rev, no_comments) {
tokens = tokenize(code);
reviver = rev;
remove_comments = no_comments;

if (!tokens.length) {
unexpected_end();
}

sort_comment_tokens();

index = -1;
next();

var result = walk();

if (Object(result) === result && !remove_comments) {
if (tokens.head_comments.length) {
result['//^'] = tokens.head_comments;
}

if (tokens.foot_comments.length) {
result['//$'] = tokens.foot_comments;
}
}

result = transform('', result);
reviver = null;
return result;
}


function transform (k, v) {
return reviver
? reviver(k, v)
: v;
}


function walk () {
var tt = type();
var negative = '';
if (tt === '-') {
next();
tt = type();
negative = '-';
}
switch (tt) {
case '{':
next();
return parse_object();
case '[':
next();
return parse_array();
case 'String':
case 'Boolean':
case 'Null':
case 'Numeric':
var value = current.value;
next();
return JSON.parse(negative + value);
}

unexpected();
}


function next () {
return current = tokens[++ index];
}


function expect (a) {
if (!is(a)) {
unexpected();
}
}


function unexpected () {
throw new SyntaxError('Unexpected token ' + current.value.slice(0, 1));
}

function unexpected_end () {
throw new SyntaxError('Unexpected end of input');
}


function parse_object () {
var obj = {};
var comment;
var started;
var name;
while (!is('}')){
if (started) {
expect(',');
next();
}
started = true;
expect('String');
name = JSON.parse(current.value);
if (current.comments && !remove_comments) {
obj['// ' + name] = current.comments;
}
next();
expect(':');
next();
obj[name] = transform(name, walk());
}
next();
return obj;
}


function parse_array () {
var array = [];
var started;
var i = 0;
while(!is(']')){
if (started) {
expect(',');
next();
}
started = true;
array[i] = transform(i, walk());
i ++;
}
next();
return array;
}


function type () {
if (!current) {
unexpected_end();
}

return current.type === 'Punctuator'
? current.value
: current.type;
}


function is (t) {
return type() === t;
}


function sort_comment_tokens () {
var ts = tokens;
var comments = ts.comments;
if (!comments) {
return;
}

function compare_to_then_push (condition, to, setup) {
var comment;
var first = true;
var host;
while((comment = comments[ci ++]) && condition(comment, to)){
if (first) {
host = setup();
}
first = false;
host.push(comment_content(comment));
}

ci --;
// Whether there are comments left.
return !!comment;
}

var head_comments = [];
var foot_comments = [];

var first = ts[0];
var ci = 0;
var comment = compare_to_then_push(left, first, function () {
return head_comments;
});

var i = 0;
var token;
var next;
for (; i < ts.length; i ++) {
if (!comment) {
break;
}

token = ts[i];
next = ts[i + 1];

if (token.type === 'String' && next && next.value === ':') {
comment = compare_to_then_push(left, token, function () {
token.comments || (token.comments = []);
return token.comments[0] || (token.comments[0] = []);
});

if (!comment) {
break;
}

comment = compare_to_then_push(right, token, function () {
token.comments || (token.comments = []);
return token.comments[1] || (token.comments[1] = []);
});
}
}

compare_to_then_push(function () {
return true
}, null, function () {
return foot_comments;
});

comments.length = 0;
delete ts.comments;

tokens.head_comments = head_comments;
tokens.foot_comments = foot_comments;
}


function left (a, b) {
return a
&& (
a.loc.start.line < b.loc.start.line
||
a.loc.start.line === b.loc.start.line
&& a.loc.start.column < b.loc.start.column
);
}


function right (a, b) {
return a
&& a.loc.start.line === b.loc.start.line
&& a.loc.start.column > b.loc.start.column;
}


function comment_content (comment) {
return comment.type === 'Block'
? '/*' + comment.value + '*/'
: '//' + comment.value;
}
Object.assign(module.exports, {
tokenize: require('./src/tokenize').tokenize,
parse: require('./src/index').parse,
});
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "json-parser",
"version": "1.1.5",
"name": "json-parser2",
"version": "2.1.5",
"description": "JSON parser to parse JSON object and MAINTAIN comments.",
"main": "index.js",
"scripts": {
"test": "./node_modules/.bin/mocha --reporter spec ./test/*.js"
"test": "mocha"
},
"repository": {
"type": "git",
"url": "git://github.com/kaelzhang/node-json-parser.git"
"url": "git://github.com/bluelovers/node-json-parser.git"
},
"keywords": [
"json-parser",
Expand All @@ -26,7 +26,7 @@
"author": "kaelzhang",
"license": "MIT",
"bugs": {
"url": "https://github.com/kaelzhang/node-json-parser/issues"
"url": "https://github.com/bluelovers/node-json-parser/issues"
},
"devDependencies": {
"mocha": "*",
Expand Down
Loading