You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					1115 lines
				
				22 KiB
			
		
		
			
		
	
	
					1115 lines
				
				22 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								const util = require('./util')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let source
							 | 
						||
| 
								 | 
							
								let parseState
							 | 
						||
| 
								 | 
							
								let stack
							 | 
						||
| 
								 | 
							
								let pos
							 | 
						||
| 
								 | 
							
								let line
							 | 
						||
| 
								 | 
							
								let column
							 | 
						||
| 
								 | 
							
								let token
							 | 
						||
| 
								 | 
							
								let key
							 | 
						||
| 
								 | 
							
								let root
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = function parse (text, reviver) {
							 | 
						||
| 
								 | 
							
								    source = String(text)
							 | 
						||
| 
								 | 
							
								    parseState = 'start'
							 | 
						||
| 
								 | 
							
								    stack = []
							 | 
						||
| 
								 | 
							
								    pos = 0
							 | 
						||
| 
								 | 
							
								    line = 1
							 | 
						||
| 
								 | 
							
								    column = 0
							 | 
						||
| 
								 | 
							
								    token = undefined
							 | 
						||
| 
								 | 
							
								    key = undefined
							 | 
						||
| 
								 | 
							
								    root = undefined
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    do {
							 | 
						||
| 
								 | 
							
								        token = lex()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This code is unreachable.
							 | 
						||
| 
								 | 
							
								        // if (!parseStates[parseState]) {
							 | 
						||
| 
								 | 
							
								        //     throw invalidParseState()
							 | 
						||
| 
								 | 
							
								        // }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        parseStates[parseState]()
							 | 
						||
| 
								 | 
							
								    } while (token.type !== 'eof')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (typeof reviver === 'function') {
							 | 
						||
| 
								 | 
							
								        return internalize({'': root}, '', reviver)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return root
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function internalize (holder, name, reviver) {
							 | 
						||
| 
								 | 
							
								    const value = holder[name]
							 | 
						||
| 
								 | 
							
								    if (value != null && typeof value === 'object') {
							 | 
						||
| 
								 | 
							
								        if (Array.isArray(value)) {
							 | 
						||
| 
								 | 
							
								            for (let i = 0; i < value.length; i++) {
							 | 
						||
| 
								 | 
							
								                const key = String(i)
							 | 
						||
| 
								 | 
							
								                const replacement = internalize(value, key, reviver)
							 | 
						||
| 
								 | 
							
								                if (replacement === undefined) {
							 | 
						||
| 
								 | 
							
								                    delete value[key]
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    Object.defineProperty(value, key, {
							 | 
						||
| 
								 | 
							
								                        value: replacement,
							 | 
						||
| 
								 | 
							
								                        writable: true,
							 | 
						||
| 
								 | 
							
								                        enumerable: true,
							 | 
						||
| 
								 | 
							
								                        configurable: true,
							 | 
						||
| 
								 | 
							
								                    })
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            for (const key in value) {
							 | 
						||
| 
								 | 
							
								                const replacement = internalize(value, key, reviver)
							 | 
						||
| 
								 | 
							
								                if (replacement === undefined) {
							 | 
						||
| 
								 | 
							
								                    delete value[key]
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    Object.defineProperty(value, key, {
							 | 
						||
| 
								 | 
							
								                        value: replacement,
							 | 
						||
| 
								 | 
							
								                        writable: true,
							 | 
						||
| 
								 | 
							
								                        enumerable: true,
							 | 
						||
| 
								 | 
							
								                        configurable: true,
							 | 
						||
| 
								 | 
							
								                    })
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return reviver.call(holder, name, value)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let lexState
							 | 
						||
| 
								 | 
							
								let buffer
							 | 
						||
| 
								 | 
							
								let doubleQuote
							 | 
						||
| 
								 | 
							
								let sign
							 | 
						||
| 
								 | 
							
								let c
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function lex () {
							 | 
						||
| 
								 | 
							
								    lexState = 'default'
							 | 
						||
| 
								 | 
							
								    buffer = ''
							 | 
						||
| 
								 | 
							
								    doubleQuote = false
							 | 
						||
| 
								 | 
							
								    sign = 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (;;) {
							 | 
						||
| 
								 | 
							
								        c = peek()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This code is unreachable.
							 | 
						||
| 
								 | 
							
								        // if (!lexStates[lexState]) {
							 | 
						||
| 
								 | 
							
								        //     throw invalidLexState(lexState)
							 | 
						||
| 
								 | 
							
								        // }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const token = lexStates[lexState]()
							 | 
						||
| 
								 | 
							
								        if (token) {
							 | 
						||
| 
								 | 
							
								            return token
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function peek () {
							 | 
						||
| 
								 | 
							
								    if (source[pos]) {
							 | 
						||
| 
								 | 
							
								        return String.fromCodePoint(source.codePointAt(pos))
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function read () {
							 | 
						||
| 
								 | 
							
								    const c = peek()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (c === '\n') {
							 | 
						||
| 
								 | 
							
								        line++
							 | 
						||
| 
								 | 
							
								        column = 0
							 | 
						||
| 
								 | 
							
								    } else if (c) {
							 | 
						||
| 
								 | 
							
								        column += c.length
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        column++
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (c) {
							 | 
						||
| 
								 | 
							
								        pos += c.length
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return c
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const lexStates = {
							 | 
						||
| 
								 | 
							
								    default () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '\t':
							 | 
						||
| 
								 | 
							
								        case '\v':
							 | 
						||
| 
								 | 
							
								        case '\f':
							 | 
						||
| 
								 | 
							
								        case ' ':
							 | 
						||
| 
								 | 
							
								        case '\u00A0':
							 | 
						||
| 
								 | 
							
								        case '\uFEFF':
							 | 
						||
| 
								 | 
							
								        case '\n':
							 | 
						||
| 
								 | 
							
								        case '\r':
							 | 
						||
| 
								 | 
							
								        case '\u2028':
							 | 
						||
| 
								 | 
							
								        case '\u2029':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '/':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            lexState = 'comment'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case undefined:
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            return newToken('eof')
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (util.isSpaceSeparator(c)) {
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This code is unreachable.
							 | 
						||
| 
								 | 
							
								        // if (!lexStates[parseState]) {
							 | 
						||
| 
								 | 
							
								        //     throw invalidLexState(parseState)
							 | 
						||
| 
								 | 
							
								        // }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return lexStates[parseState]()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    comment () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '*':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            lexState = 'multiLineComment'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '/':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            lexState = 'singleLineComment'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    multiLineComment () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '*':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            lexState = 'multiLineCommentAsterisk'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case undefined:
							 | 
						||
| 
								 | 
							
								            throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    multiLineCommentAsterisk () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '*':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '/':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            lexState = 'default'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case undefined:
							 | 
						||
| 
								 | 
							
								            throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        lexState = 'multiLineComment'
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    singleLineComment () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '\n':
							 | 
						||
| 
								 | 
							
								        case '\r':
							 | 
						||
| 
								 | 
							
								        case '\u2028':
							 | 
						||
| 
								 | 
							
								        case '\u2029':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            lexState = 'default'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case undefined:
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            return newToken('eof')
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    value () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '{':
							 | 
						||
| 
								 | 
							
								        case '[':
							 | 
						||
| 
								 | 
							
								            return newToken('punctuator', read())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'n':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            literal('ull')
							 | 
						||
| 
								 | 
							
								            return newToken('null', null)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 't':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            literal('rue')
							 | 
						||
| 
								 | 
							
								            return newToken('boolean', true)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'f':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            literal('alse')
							 | 
						||
| 
								 | 
							
								            return newToken('boolean', false)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '-':
							 | 
						||
| 
								 | 
							
								        case '+':
							 | 
						||
| 
								 | 
							
								            if (read() === '-') {
							 | 
						||
| 
								 | 
							
								                sign = -1
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            lexState = 'sign'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '.':
							 | 
						||
| 
								 | 
							
								            buffer = read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalPointLeading'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '0':
							 | 
						||
| 
								 | 
							
								            buffer = read()
							 | 
						||
| 
								 | 
							
								            lexState = 'zero'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '1':
							 | 
						||
| 
								 | 
							
								        case '2':
							 | 
						||
| 
								 | 
							
								        case '3':
							 | 
						||
| 
								 | 
							
								        case '4':
							 | 
						||
| 
								 | 
							
								        case '5':
							 | 
						||
| 
								 | 
							
								        case '6':
							 | 
						||
| 
								 | 
							
								        case '7':
							 | 
						||
| 
								 | 
							
								        case '8':
							 | 
						||
| 
								 | 
							
								        case '9':
							 | 
						||
| 
								 | 
							
								            buffer = read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalInteger'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'I':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            literal('nfinity')
							 | 
						||
| 
								 | 
							
								            return newToken('numeric', Infinity)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'N':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            literal('aN')
							 | 
						||
| 
								 | 
							
								            return newToken('numeric', NaN)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '"':
							 | 
						||
| 
								 | 
							
								        case "'":
							 | 
						||
| 
								 | 
							
								            doubleQuote = (read() === '"')
							 | 
						||
| 
								 | 
							
								            buffer = ''
							 | 
						||
| 
								 | 
							
								            lexState = 'string'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    identifierNameStartEscape () {
							 | 
						||
| 
								 | 
							
								        if (c !== 'u') {
							 | 
						||
| 
								 | 
							
								            throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        const u = unicodeEscape()
							 | 
						||
| 
								 | 
							
								        switch (u) {
							 | 
						||
| 
								 | 
							
								        case '$':
							 | 
						||
| 
								 | 
							
								        case '_':
							 | 
						||
| 
								 | 
							
								            break
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								            if (!util.isIdStartChar(u)) {
							 | 
						||
| 
								 | 
							
								                throw invalidIdentifier()
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            break
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        buffer += u
							 | 
						||
| 
								 | 
							
								        lexState = 'identifierName'
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    identifierName () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '$':
							 | 
						||
| 
								 | 
							
								        case '_':
							 | 
						||
| 
								 | 
							
								        case '\u200C':
							 | 
						||
| 
								 | 
							
								        case '\u200D':
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '\\':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            lexState = 'identifierNameEscape'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (util.isIdContinueChar(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return newToken('identifier', buffer)
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    identifierNameEscape () {
							 | 
						||
| 
								 | 
							
								        if (c !== 'u') {
							 | 
						||
| 
								 | 
							
								            throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        const u = unicodeEscape()
							 | 
						||
| 
								 | 
							
								        switch (u) {
							 | 
						||
| 
								 | 
							
								        case '$':
							 | 
						||
| 
								 | 
							
								        case '_':
							 | 
						||
| 
								 | 
							
								        case '\u200C':
							 | 
						||
| 
								 | 
							
								        case '\u200D':
							 | 
						||
| 
								 | 
							
								            break
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								            if (!util.isIdContinueChar(u)) {
							 | 
						||
| 
								 | 
							
								                throw invalidIdentifier()
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            break
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        buffer += u
							 | 
						||
| 
								 | 
							
								        lexState = 'identifierName'
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    sign () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '.':
							 | 
						||
| 
								 | 
							
								            buffer = read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalPointLeading'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '0':
							 | 
						||
| 
								 | 
							
								            buffer = read()
							 | 
						||
| 
								 | 
							
								            lexState = 'zero'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '1':
							 | 
						||
| 
								 | 
							
								        case '2':
							 | 
						||
| 
								 | 
							
								        case '3':
							 | 
						||
| 
								 | 
							
								        case '4':
							 | 
						||
| 
								 | 
							
								        case '5':
							 | 
						||
| 
								 | 
							
								        case '6':
							 | 
						||
| 
								 | 
							
								        case '7':
							 | 
						||
| 
								 | 
							
								        case '8':
							 | 
						||
| 
								 | 
							
								        case '9':
							 | 
						||
| 
								 | 
							
								            buffer = read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalInteger'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'I':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            literal('nfinity')
							 | 
						||
| 
								 | 
							
								            return newToken('numeric', sign * Infinity)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'N':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            literal('aN')
							 | 
						||
| 
								 | 
							
								            return newToken('numeric', NaN)
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    zero () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '.':
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalPoint'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'e':
							 | 
						||
| 
								 | 
							
								        case 'E':
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalExponent'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'x':
							 | 
						||
| 
								 | 
							
								        case 'X':
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'hexadecimal'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return newToken('numeric', sign * 0)
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    decimalInteger () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '.':
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalPoint'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'e':
							 | 
						||
| 
								 | 
							
								        case 'E':
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalExponent'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (util.isDigit(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return newToken('numeric', sign * Number(buffer))
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    decimalPointLeading () {
							 | 
						||
| 
								 | 
							
								        if (util.isDigit(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalFraction'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    decimalPoint () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case 'e':
							 | 
						||
| 
								 | 
							
								        case 'E':
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalExponent'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (util.isDigit(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalFraction'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return newToken('numeric', sign * Number(buffer))
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    decimalFraction () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case 'e':
							 | 
						||
| 
								 | 
							
								        case 'E':
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalExponent'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (util.isDigit(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return newToken('numeric', sign * Number(buffer))
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    decimalExponent () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '+':
							 | 
						||
| 
								 | 
							
								        case '-':
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalExponentSign'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (util.isDigit(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalExponentInteger'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    decimalExponentSign () {
							 | 
						||
| 
								 | 
							
								        if (util.isDigit(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'decimalExponentInteger'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    decimalExponentInteger () {
							 | 
						||
| 
								 | 
							
								        if (util.isDigit(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return newToken('numeric', sign * Number(buffer))
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    hexadecimal () {
							 | 
						||
| 
								 | 
							
								        if (util.isHexDigit(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'hexadecimalInteger'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    hexadecimalInteger () {
							 | 
						||
| 
								 | 
							
								        if (util.isHexDigit(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return newToken('numeric', sign * Number(buffer))
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    string () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '\\':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            buffer += escape()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '"':
							 | 
						||
| 
								 | 
							
								            if (doubleQuote) {
							 | 
						||
| 
								 | 
							
								                read()
							 | 
						||
| 
								 | 
							
								                return newToken('string', buffer)
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case "'":
							 | 
						||
| 
								 | 
							
								            if (!doubleQuote) {
							 | 
						||
| 
								 | 
							
								                read()
							 | 
						||
| 
								 | 
							
								                return newToken('string', buffer)
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '\n':
							 | 
						||
| 
								 | 
							
								        case '\r':
							 | 
						||
| 
								 | 
							
								            throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '\u2028':
							 | 
						||
| 
								 | 
							
								        case '\u2029':
							 | 
						||
| 
								 | 
							
								            separatorChar(c)
							 | 
						||
| 
								 | 
							
								            break
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case undefined:
							 | 
						||
| 
								 | 
							
								            throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        buffer += read()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    start () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '{':
							 | 
						||
| 
								 | 
							
								        case '[':
							 | 
						||
| 
								 | 
							
								            return newToken('punctuator', read())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This code is unreachable since the default lexState handles eof.
							 | 
						||
| 
								 | 
							
								        // case undefined:
							 | 
						||
| 
								 | 
							
								        //     return newToken('eof')
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        lexState = 'value'
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    beforePropertyName () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case '$':
							 | 
						||
| 
								 | 
							
								        case '_':
							 | 
						||
| 
								 | 
							
								            buffer = read()
							 | 
						||
| 
								 | 
							
								            lexState = 'identifierName'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '\\':
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								            lexState = 'identifierNameStartEscape'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '}':
							 | 
						||
| 
								 | 
							
								            return newToken('punctuator', read())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '"':
							 | 
						||
| 
								 | 
							
								        case "'":
							 | 
						||
| 
								 | 
							
								            doubleQuote = (read() === '"')
							 | 
						||
| 
								 | 
							
								            lexState = 'string'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (util.isIdStartChar(c)) {
							 | 
						||
| 
								 | 
							
								            buffer += read()
							 | 
						||
| 
								 | 
							
								            lexState = 'identifierName'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    afterPropertyName () {
							 | 
						||
| 
								 | 
							
								        if (c === ':') {
							 | 
						||
| 
								 | 
							
								            return newToken('punctuator', read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    beforePropertyValue () {
							 | 
						||
| 
								 | 
							
								        lexState = 'value'
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    afterPropertyValue () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case ',':
							 | 
						||
| 
								 | 
							
								        case '}':
							 | 
						||
| 
								 | 
							
								            return newToken('punctuator', read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    beforeArrayValue () {
							 | 
						||
| 
								 | 
							
								        if (c === ']') {
							 | 
						||
| 
								 | 
							
								            return newToken('punctuator', read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        lexState = 'value'
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    afterArrayValue () {
							 | 
						||
| 
								 | 
							
								        switch (c) {
							 | 
						||
| 
								 | 
							
								        case ',':
							 | 
						||
| 
								 | 
							
								        case ']':
							 | 
						||
| 
								 | 
							
								            return newToken('punctuator', read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    end () {
							 | 
						||
| 
								 | 
							
								        // This code is unreachable since it's handled by the default lexState.
							 | 
						||
| 
								 | 
							
								        // if (c === undefined) {
							 | 
						||
| 
								 | 
							
								        //     read()
							 | 
						||
| 
								 | 
							
								        //     return newToken('eof')
							 | 
						||
| 
								 | 
							
								        // }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function newToken (type, value) {
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								        type,
							 | 
						||
| 
								 | 
							
								        value,
							 | 
						||
| 
								 | 
							
								        line,
							 | 
						||
| 
								 | 
							
								        column,
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function literal (s) {
							 | 
						||
| 
								 | 
							
								    for (const c of s) {
							 | 
						||
| 
								 | 
							
								        const p = peek()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (p !== c) {
							 | 
						||
| 
								 | 
							
								            throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function escape () {
							 | 
						||
| 
								 | 
							
								    const c = peek()
							 | 
						||
| 
								 | 
							
								    switch (c) {
							 | 
						||
| 
								 | 
							
								    case 'b':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        return '\b'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case 'f':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        return '\f'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case 'n':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        return '\n'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case 'r':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        return '\r'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case 't':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        return '\t'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case 'v':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        return '\v'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case '0':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        if (util.isDigit(peek())) {
							 | 
						||
| 
								 | 
							
								            throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return '\0'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case 'x':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        return hexEscape()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case 'u':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        return unicodeEscape()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case '\n':
							 | 
						||
| 
								 | 
							
								    case '\u2028':
							 | 
						||
| 
								 | 
							
								    case '\u2029':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        return ''
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case '\r':
							 | 
						||
| 
								 | 
							
								        read()
							 | 
						||
| 
								 | 
							
								        if (peek() === '\n') {
							 | 
						||
| 
								 | 
							
								            read()
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return ''
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case '1':
							 | 
						||
| 
								 | 
							
								    case '2':
							 | 
						||
| 
								 | 
							
								    case '3':
							 | 
						||
| 
								 | 
							
								    case '4':
							 | 
						||
| 
								 | 
							
								    case '5':
							 | 
						||
| 
								 | 
							
								    case '6':
							 | 
						||
| 
								 | 
							
								    case '7':
							 | 
						||
| 
								 | 
							
								    case '8':
							 | 
						||
| 
								 | 
							
								    case '9':
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case undefined:
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return read()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function hexEscape () {
							 | 
						||
| 
								 | 
							
								    let buffer = ''
							 | 
						||
| 
								 | 
							
								    let c = peek()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!util.isHexDigit(c)) {
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    buffer += read()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    c = peek()
							 | 
						||
| 
								 | 
							
								    if (!util.isHexDigit(c)) {
							 | 
						||
| 
								 | 
							
								        throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    buffer += read()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return String.fromCodePoint(parseInt(buffer, 16))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function unicodeEscape () {
							 | 
						||
| 
								 | 
							
								    let buffer = ''
							 | 
						||
| 
								 | 
							
								    let count = 4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while (count-- > 0) {
							 | 
						||
| 
								 | 
							
								        const c = peek()
							 | 
						||
| 
								 | 
							
								        if (!util.isHexDigit(c)) {
							 | 
						||
| 
								 | 
							
								            throw invalidChar(read())
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        buffer += read()
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return String.fromCodePoint(parseInt(buffer, 16))
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const parseStates = {
							 | 
						||
| 
								 | 
							
								    start () {
							 | 
						||
| 
								 | 
							
								        if (token.type === 'eof') {
							 | 
						||
| 
								 | 
							
								            throw invalidEOF()
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        push()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    beforePropertyName () {
							 | 
						||
| 
								 | 
							
								        switch (token.type) {
							 | 
						||
| 
								 | 
							
								        case 'identifier':
							 | 
						||
| 
								 | 
							
								        case 'string':
							 | 
						||
| 
								 | 
							
								            key = token.value
							 | 
						||
| 
								 | 
							
								            parseState = 'afterPropertyName'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'punctuator':
							 | 
						||
| 
								 | 
							
								            // This code is unreachable since it's handled by the lexState.
							 | 
						||
| 
								 | 
							
								            // if (token.value !== '}') {
							 | 
						||
| 
								 | 
							
								            //     throw invalidToken()
							 | 
						||
| 
								 | 
							
								            // }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            pop()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case 'eof':
							 | 
						||
| 
								 | 
							
								            throw invalidEOF()
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This code is unreachable since it's handled by the lexState.
							 | 
						||
| 
								 | 
							
								        // throw invalidToken()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    afterPropertyName () {
							 | 
						||
| 
								 | 
							
								        // This code is unreachable since it's handled by the lexState.
							 | 
						||
| 
								 | 
							
								        // if (token.type !== 'punctuator' || token.value !== ':') {
							 | 
						||
| 
								 | 
							
								        //     throw invalidToken()
							 | 
						||
| 
								 | 
							
								        // }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === 'eof') {
							 | 
						||
| 
								 | 
							
								            throw invalidEOF()
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        parseState = 'beforePropertyValue'
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    beforePropertyValue () {
							 | 
						||
| 
								 | 
							
								        if (token.type === 'eof') {
							 | 
						||
| 
								 | 
							
								            throw invalidEOF()
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        push()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    beforeArrayValue () {
							 | 
						||
| 
								 | 
							
								        if (token.type === 'eof') {
							 | 
						||
| 
								 | 
							
								            throw invalidEOF()
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === 'punctuator' && token.value === ']') {
							 | 
						||
| 
								 | 
							
								            pop()
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        push()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    afterPropertyValue () {
							 | 
						||
| 
								 | 
							
								        // This code is unreachable since it's handled by the lexState.
							 | 
						||
| 
								 | 
							
								        // if (token.type !== 'punctuator') {
							 | 
						||
| 
								 | 
							
								        //     throw invalidToken()
							 | 
						||
| 
								 | 
							
								        // }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === 'eof') {
							 | 
						||
| 
								 | 
							
								            throw invalidEOF()
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        switch (token.value) {
							 | 
						||
| 
								 | 
							
								        case ',':
							 | 
						||
| 
								 | 
							
								            parseState = 'beforePropertyName'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '}':
							 | 
						||
| 
								 | 
							
								            pop()
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This code is unreachable since it's handled by the lexState.
							 | 
						||
| 
								 | 
							
								        // throw invalidToken()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    afterArrayValue () {
							 | 
						||
| 
								 | 
							
								        // This code is unreachable since it's handled by the lexState.
							 | 
						||
| 
								 | 
							
								        // if (token.type !== 'punctuator') {
							 | 
						||
| 
								 | 
							
								        //     throw invalidToken()
							 | 
						||
| 
								 | 
							
								        // }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (token.type === 'eof') {
							 | 
						||
| 
								 | 
							
								            throw invalidEOF()
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        switch (token.value) {
							 | 
						||
| 
								 | 
							
								        case ',':
							 | 
						||
| 
								 | 
							
								            parseState = 'beforeArrayValue'
							 | 
						||
| 
								 | 
							
								            return
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case ']':
							 | 
						||
| 
								 | 
							
								            pop()
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // This code is unreachable since it's handled by the lexState.
							 | 
						||
| 
								 | 
							
								        // throw invalidToken()
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    end () {
							 | 
						||
| 
								 | 
							
								        // This code is unreachable since it's handled by the lexState.
							 | 
						||
| 
								 | 
							
								        // if (token.type !== 'eof') {
							 | 
						||
| 
								 | 
							
								        //     throw invalidToken()
							 | 
						||
| 
								 | 
							
								        // }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function push () {
							 | 
						||
| 
								 | 
							
								    let value
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    switch (token.type) {
							 | 
						||
| 
								 | 
							
								    case 'punctuator':
							 | 
						||
| 
								 | 
							
								        switch (token.value) {
							 | 
						||
| 
								 | 
							
								        case '{':
							 | 
						||
| 
								 | 
							
								            value = {}
							 | 
						||
| 
								 | 
							
								            break
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        case '[':
							 | 
						||
| 
								 | 
							
								            value = []
							 | 
						||
| 
								 | 
							
								            break
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        break
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    case 'null':
							 | 
						||
| 
								 | 
							
								    case 'boolean':
							 | 
						||
| 
								 | 
							
								    case 'numeric':
							 | 
						||
| 
								 | 
							
								    case 'string':
							 | 
						||
| 
								 | 
							
								        value = token.value
							 | 
						||
| 
								 | 
							
								        break
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // This code is unreachable.
							 | 
						||
| 
								 | 
							
								    // default:
							 | 
						||
| 
								 | 
							
								    //     throw invalidToken()
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (root === undefined) {
							 | 
						||
| 
								 | 
							
								        root = value
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        const parent = stack[stack.length - 1]
							 | 
						||
| 
								 | 
							
								        if (Array.isArray(parent)) {
							 | 
						||
| 
								 | 
							
								            parent.push(value)
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            Object.defineProperty(parent, key, {
							 | 
						||
| 
								 | 
							
								                value,
							 | 
						||
| 
								 | 
							
								                writable: true,
							 | 
						||
| 
								 | 
							
								                enumerable: true,
							 | 
						||
| 
								 | 
							
								                configurable: true,
							 | 
						||
| 
								 | 
							
								            })
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (value !== null && typeof value === 'object') {
							 | 
						||
| 
								 | 
							
								        stack.push(value)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (Array.isArray(value)) {
							 | 
						||
| 
								 | 
							
								            parseState = 'beforeArrayValue'
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            parseState = 'beforePropertyName'
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        const current = stack[stack.length - 1]
							 | 
						||
| 
								 | 
							
								        if (current == null) {
							 | 
						||
| 
								 | 
							
								            parseState = 'end'
							 | 
						||
| 
								 | 
							
								        } else if (Array.isArray(current)) {
							 | 
						||
| 
								 | 
							
								            parseState = 'afterArrayValue'
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            parseState = 'afterPropertyValue'
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function pop () {
							 | 
						||
| 
								 | 
							
								    stack.pop()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const current = stack[stack.length - 1]
							 | 
						||
| 
								 | 
							
								    if (current == null) {
							 | 
						||
| 
								 | 
							
								        parseState = 'end'
							 | 
						||
| 
								 | 
							
								    } else if (Array.isArray(current)) {
							 | 
						||
| 
								 | 
							
								        parseState = 'afterArrayValue'
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								        parseState = 'afterPropertyValue'
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This code is unreachable.
							 | 
						||
| 
								 | 
							
								// function invalidParseState () {
							 | 
						||
| 
								 | 
							
								//     return new Error(`JSON5: invalid parse state '${parseState}'`)
							 | 
						||
| 
								 | 
							
								// }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This code is unreachable.
							 | 
						||
| 
								 | 
							
								// function invalidLexState (state) {
							 | 
						||
| 
								 | 
							
								//     return new Error(`JSON5: invalid lex state '${state}'`)
							 | 
						||
| 
								 | 
							
								// }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function invalidChar (c) {
							 | 
						||
| 
								 | 
							
								    if (c === undefined) {
							 | 
						||
| 
								 | 
							
								        return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function invalidEOF () {
							 | 
						||
| 
								 | 
							
								    return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This code is unreachable.
							 | 
						||
| 
								 | 
							
								// function invalidToken () {
							 | 
						||
| 
								 | 
							
								//     if (token.type === 'eof') {
							 | 
						||
| 
								 | 
							
								//         return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)
							 | 
						||
| 
								 | 
							
								//     }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//     const c = String.fromCodePoint(token.value.codePointAt(0))
							 | 
						||
| 
								 | 
							
								//     return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`)
							 | 
						||
| 
								 | 
							
								// }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function invalidIdentifier () {
							 | 
						||
| 
								 | 
							
								    column -= 5
							 | 
						||
| 
								 | 
							
								    return syntaxError(`JSON5: invalid identifier character at ${line}:${column}`)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function separatorChar (c) {
							 | 
						||
| 
								 | 
							
								    console.warn(`JSON5: '${formatChar(c)}' in strings is not valid ECMAScript; consider escaping`)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function formatChar (c) {
							 | 
						||
| 
								 | 
							
								    const replacements = {
							 | 
						||
| 
								 | 
							
								        "'": "\\'",
							 | 
						||
| 
								 | 
							
								        '"': '\\"',
							 | 
						||
| 
								 | 
							
								        '\\': '\\\\',
							 | 
						||
| 
								 | 
							
								        '\b': '\\b',
							 | 
						||
| 
								 | 
							
								        '\f': '\\f',
							 | 
						||
| 
								 | 
							
								        '\n': '\\n',
							 | 
						||
| 
								 | 
							
								        '\r': '\\r',
							 | 
						||
| 
								 | 
							
								        '\t': '\\t',
							 | 
						||
| 
								 | 
							
								        '\v': '\\v',
							 | 
						||
| 
								 | 
							
								        '\0': '\\0',
							 | 
						||
| 
								 | 
							
								        '\u2028': '\\u2028',
							 | 
						||
| 
								 | 
							
								        '\u2029': '\\u2029',
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (replacements[c]) {
							 | 
						||
| 
								 | 
							
								        return replacements[c]
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (c < ' ') {
							 | 
						||
| 
								 | 
							
								        const hexString = c.charCodeAt(0).toString(16)
							 | 
						||
| 
								 | 
							
								        return '\\x' + ('00' + hexString).substring(hexString.length)
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return c
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function syntaxError (message) {
							 | 
						||
| 
								 | 
							
								    const err = new SyntaxError(message)
							 | 
						||
| 
								 | 
							
								    err.lineNumber = line
							 | 
						||
| 
								 | 
							
								    err.columnNumber = column
							 | 
						||
| 
								 | 
							
								    return err
							 | 
						||
| 
								 | 
							
								}
							 |