-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathParser.js
More file actions
90 lines (89 loc) · 2.44 KB
/
Parser.js
File metadata and controls
90 lines (89 loc) · 2.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Null parser
function parseNull (data) {
if (data.startsWith('null')) return [null, data.slice(4)]
return null
}
// Boolean parser
function parseBool (data) {
if (data.startsWith('true')) return [true, data.slice(4)]
if (data.startsWith('false')) return [false, data.slice(5)]
return null
}
// Number parser
function parseNumber (data) {
let num = /^[-]?[0-9]+(\.[0-9]+(?:[Ee][+-]?[0-9]+)?)?/.exec(data)
if (num) return [Number(num[0]), data.slice(num[0].length)]
return null
}
// String parser
function parseString (data) {
let str = /^"(([^"\\\u0000-\u001F])*((\\[\\"/bnrtf])*(\\\u[0-9A-Za-z]{4})*)*)*"/.exec(data)
if (str) return [str[1], data.slice(str[0].length)]
return null
}
// Array parsers
function parseArray (data) {
if (!data.startsWith('[')) return null
data = data.slice(1)
let arr = []
while (!data.startsWith(']')) {
data = parseWhiteSpace(data)
data = parseValue(data)
arr.push(data[0])
data = data[1]
if (data.startsWith(',')) data = data.slice(1)
data = parseWhiteSpace(data)
}
return [arr, data.slice(1)]
}
// Object parser
function parseObject (data) {
if (!data.startsWith('{')) return null
data = data.slice(1)
let obj = {}
while (!data.startsWith('}')) {
data = parseWhiteSpace(data)
if (data.startsWith(',')) return null
data = parseValue(data)
let key = data[0]
data = parseWhiteSpace(data[1])
if (data.startsWith(':')) data = data.slice(1)
data = parseWhiteSpace(data)
data = parseValue(data)
let value = data[0]
obj[key] = value
data = parseWhiteSpace(data[1])
if (data.startsWith(',')) data = data.slice(1)
data = parseWhiteSpace(data)
}
return [obj, data.slice(1)]
}
// Whitespace parser
function parseWhiteSpace (data) {
let first = data.search(/\S/)
if (first === -1) return ''
return data.slice(first)
}
// factoryParser
function factoryParser (...parsers) {
return function (data) {
for (let parser of parsers) {
data = parseWhiteSpace(data)
let result = parser(data)
if (result !== null) return result
}
return null
}
}
const parseValue = factoryParser(parseNull, parseBool, parseNumber, parseString, parseObject, parseArray)
// Main function
function main (data) {
let valid = parseValue(data)
if (valid) return valid
return 'Invalid JSON'
}
const fs = require('fs')
fs.readFile('twitter.json', (err, data) => {
if (err) throw err
console.log(JSON.stringify(main(data.toString())))
})