CoolFace
Apppublic

sourav-das/stem-separator

sourceHugging Facemitupdated 6mo agoView on Hugging Face
3likes
parse.js1115 linesDownload Raw Back to lib
1const util = require('./util')2 3let source4let parseState5let stack6let pos7let line8let column9let token10let key11let root12 13module.exports = function parse (text, reviver) {14    source = String(text)15    parseState = 'start'16    stack = []17    pos = 018    line = 119    column = 020    token = undefined21    key = undefined22    root = undefined23 24    do {25        token = lex()26 27        // This code is unreachable.28        // if (!parseStates[parseState]) {29        //     throw invalidParseState()30        // }31 32        parseStates[parseState]()33    } while (token.type !== 'eof')34 35    if (typeof reviver === 'function') {36        return internalize({'': root}, '', reviver)37    }38 39    return root40}41 42function internalize (holder, name, reviver) {43    const value = holder[name]44    if (value != null && typeof value === 'object') {45        if (Array.isArray(value)) {46            for (let i = 0; i < value.length; i++) {47                const key = String(i)48                const replacement = internalize(value, key, reviver)49                if (replacement === undefined) {50                    delete value[key]51                } else {52                    Object.defineProperty(value, key, {53                        value: replacement,54                        writable: true,55                        enumerable: true,56                        configurable: true,57                    })58                }59            }60        } else {61            for (const key in value) {62                const replacement = internalize(value, key, reviver)63                if (replacement === undefined) {64                    delete value[key]65                } else {66                    Object.defineProperty(value, key, {67                        value: replacement,68                        writable: true,69                        enumerable: true,70                        configurable: true,71                    })72                }73            }74        }75    }76 77    return reviver.call(holder, name, value)78}79 80let lexState81let buffer82let doubleQuote83let sign84let c85 86function lex () {87    lexState = 'default'88    buffer = ''89    doubleQuote = false90    sign = 191 92    for (;;) {93        c = peek()94 95        // This code is unreachable.96        // if (!lexStates[lexState]) {97        //     throw invalidLexState(lexState)98        // }99 100        const token = lexStates[lexState]()101        if (token) {102            return token103        }104    }105}106 107function peek () {108    if (source[pos]) {109        return String.fromCodePoint(source.codePointAt(pos))110    }111}112 113function read () {114    const c = peek()115 116    if (c === '\n') {117        line++118        column = 0119    } else if (c) {120        column += c.length121    } else {122        column++123    }124 125    if (c) {126        pos += c.length127    }128 129    return c130}131 132const lexStates = {133    default () {134        switch (c) {135        case '\t':136        case '\v':137        case '\f':138        case ' ':139        case '\u00A0':140        case '\uFEFF':141        case '\n':142        case '\r':143        case '\u2028':144        case '\u2029':145            read()146            return147 148        case '/':149            read()150            lexState = 'comment'151            return152 153        case undefined:154            read()155            return newToken('eof')156        }157 158        if (util.isSpaceSeparator(c)) {159            read()160            return161        }162 163        // This code is unreachable.164        // if (!lexStates[parseState]) {165        //     throw invalidLexState(parseState)166        // }167 168        return lexStates[parseState]()169    },170 171    comment () {172        switch (c) {173        case '*':174            read()175            lexState = 'multiLineComment'176            return177 178        case '/':179            read()180            lexState = 'singleLineComment'181            return182        }183 184        throw invalidChar(read())185    },186 187    multiLineComment () {188        switch (c) {189        case '*':190            read()191            lexState = 'multiLineCommentAsterisk'192            return193 194        case undefined:195            throw invalidChar(read())196        }197 198        read()199    },200 201    multiLineCommentAsterisk () {202        switch (c) {203        case '*':204            read()205            return206 207        case '/':208            read()209            lexState = 'default'210            return211 212        case undefined:213            throw invalidChar(read())214        }215 216        read()217        lexState = 'multiLineComment'218    },219 220    singleLineComment () {221        switch (c) {222        case '\n':223        case '\r':224        case '\u2028':225        case '\u2029':226            read()227            lexState = 'default'228            return229 230        case undefined:231            read()232            return newToken('eof')233        }234 235        read()236    },237 238    value () {239        switch (c) {240        case '{':241        case '[':242            return newToken('punctuator', read())243 244        case 'n':245            read()246            literal('ull')247            return newToken('null', null)248 249        case 't':250            read()251            literal('rue')252            return newToken('boolean', true)253 254        case 'f':255            read()256            literal('alse')257            return newToken('boolean', false)258 259        case '-':260        case '+':261            if (read() === '-') {262                sign = -1263            }264 265            lexState = 'sign'266            return267 268        case '.':269            buffer = read()270            lexState = 'decimalPointLeading'271            return272 273        case '0':274            buffer = read()275            lexState = 'zero'276            return277 278        case '1':279        case '2':280        case '3':281        case '4':282        case '5':283        case '6':284        case '7':285        case '8':286        case '9':287            buffer = read()288            lexState = 'decimalInteger'289            return290 291        case 'I':292            read()293            literal('nfinity')294            return newToken('numeric', Infinity)295 296        case 'N':297            read()298            literal('aN')299            return newToken('numeric', NaN)300 301        case '"':302        case "'":303            doubleQuote = (read() === '"')304            buffer = ''305            lexState = 'string'306            return307        }308 309        throw invalidChar(read())310    },311 312    identifierNameStartEscape () {313        if (c !== 'u') {314            throw invalidChar(read())315        }316 317        read()318        const u = unicodeEscape()319        switch (u) {320        case '$':321        case '_':322            break323 324        default:325            if (!util.isIdStartChar(u)) {326                throw invalidIdentifier()327            }328 329            break330        }331 332        buffer += u333        lexState = 'identifierName'334    },335 336    identifierName () {337        switch (c) {338        case '$':339        case '_':340        case '\u200C':341        case '\u200D':342            buffer += read()343            return344 345        case '\\':346            read()347            lexState = 'identifierNameEscape'348            return349        }350 351        if (util.isIdContinueChar(c)) {352            buffer += read()353            return354        }355 356        return newToken('identifier', buffer)357    },358 359    identifierNameEscape () {360        if (c !== 'u') {361            throw invalidChar(read())362        }363 364        read()365        const u = unicodeEscape()366        switch (u) {367        case '$':368        case '_':369        case '\u200C':370        case '\u200D':371            break372 373        default:374            if (!util.isIdContinueChar(u)) {375                throw invalidIdentifier()376            }377 378            break379        }380 381        buffer += u382        lexState = 'identifierName'383    },384 385    sign () {386        switch (c) {387        case '.':388            buffer = read()389            lexState = 'decimalPointLeading'390            return391 392        case '0':393            buffer = read()394            lexState = 'zero'395            return396 397        case '1':398        case '2':399        case '3':400        case '4':401        case '5':402        case '6':403        case '7':404        case '8':405        case '9':406            buffer = read()407            lexState = 'decimalInteger'408            return409 410        case 'I':411            read()412            literal('nfinity')413            return newToken('numeric', sign * Infinity)414 415        case 'N':416            read()417            literal('aN')418            return newToken('numeric', NaN)419        }420 421        throw invalidChar(read())422    },423 424    zero () {425        switch (c) {426        case '.':427            buffer += read()428            lexState = 'decimalPoint'429            return430 431        case 'e':432        case 'E':433            buffer += read()434            lexState = 'decimalExponent'435            return436 437        case 'x':438        case 'X':439            buffer += read()440            lexState = 'hexadecimal'441            return442        }443 444        return newToken('numeric', sign * 0)445    },446 447    decimalInteger () {448        switch (c) {449        case '.':450            buffer += read()451            lexState = 'decimalPoint'452            return453 454        case 'e':455        case 'E':456            buffer += read()457            lexState = 'decimalExponent'458            return459        }460 461        if (util.isDigit(c)) {462            buffer += read()463            return464        }465 466        return newToken('numeric', sign * Number(buffer))467    },468 469    decimalPointLeading () {470        if (util.isDigit(c)) {471            buffer += read()472            lexState = 'decimalFraction'473            return474        }475 476        throw invalidChar(read())477    },478 479    decimalPoint () {480        switch (c) {481        case 'e':482        case 'E':483            buffer += read()484            lexState = 'decimalExponent'485            return486        }487 488        if (util.isDigit(c)) {489            buffer += read()490            lexState = 'decimalFraction'491            return492        }493 494        return newToken('numeric', sign * Number(buffer))495    },496 497    decimalFraction () {498        switch (c) {499        case 'e':500        case 'E':501            buffer += read()502            lexState = 'decimalExponent'503            return504        }505 506        if (util.isDigit(c)) {507            buffer += read()508            return509        }510 511        return newToken('numeric', sign * Number(buffer))512    },513 514    decimalExponent () {515        switch (c) {516        case '+':517        case '-':518            buffer += read()519            lexState = 'decimalExponentSign'520            return521        }522 523        if (util.isDigit(c)) {524            buffer += read()525            lexState = 'decimalExponentInteger'526            return527        }528 529        throw invalidChar(read())530    },531 532    decimalExponentSign () {533        if (util.isDigit(c)) {534            buffer += read()535            lexState = 'decimalExponentInteger'536            return537        }538 539        throw invalidChar(read())540    },541 542    decimalExponentInteger () {543        if (util.isDigit(c)) {544            buffer += read()545            return546        }547 548        return newToken('numeric', sign * Number(buffer))549    },550 551    hexadecimal () {552        if (util.isHexDigit(c)) {553            buffer += read()554            lexState = 'hexadecimalInteger'555            return556        }557 558        throw invalidChar(read())559    },560 561    hexadecimalInteger () {562        if (util.isHexDigit(c)) {563            buffer += read()564            return565        }566 567        return newToken('numeric', sign * Number(buffer))568    },569 570    string () {571        switch (c) {572        case '\\':573            read()574            buffer += escape()575            return576 577        case '"':578            if (doubleQuote) {579                read()580                return newToken('string', buffer)581            }582 583            buffer += read()584            return585 586        case "'":587            if (!doubleQuote) {588                read()589                return newToken('string', buffer)590            }591 592            buffer += read()593            return594 595        case '\n':596        case '\r':597            throw invalidChar(read())598 599        case '\u2028':600        case '\u2029':601            separatorChar(c)602            break603 604        case undefined:605            throw invalidChar(read())606        }607 608        buffer += read()609    },610 611    start () {612        switch (c) {613        case '{':614        case '[':615            return newToken('punctuator', read())616 617        // This code is unreachable since the default lexState handles eof.618        // case undefined:619        //     return newToken('eof')620        }621 622        lexState = 'value'623    },624 625    beforePropertyName () {626        switch (c) {627        case '$':628        case '_':629            buffer = read()630            lexState = 'identifierName'631            return632 633        case '\\':634            read()635            lexState = 'identifierNameStartEscape'636            return637 638        case '}':639            return newToken('punctuator', read())640 641        case '"':642        case "'":643            doubleQuote = (read() === '"')644            lexState = 'string'645            return646        }647 648        if (util.isIdStartChar(c)) {649            buffer += read()650            lexState = 'identifierName'651            return652        }653 654        throw invalidChar(read())655    },656 657    afterPropertyName () {658        if (c === ':') {659            return newToken('punctuator', read())660        }661 662        throw invalidChar(read())663    },664 665    beforePropertyValue () {666        lexState = 'value'667    },668 669    afterPropertyValue () {670        switch (c) {671        case ',':672        case '}':673            return newToken('punctuator', read())674        }675 676        throw invalidChar(read())677    },678 679    beforeArrayValue () {680        if (c === ']') {681            return newToken('punctuator', read())682        }683 684        lexState = 'value'685    },686 687    afterArrayValue () {688        switch (c) {689        case ',':690        case ']':691            return newToken('punctuator', read())692        }693 694        throw invalidChar(read())695    },696 697    end () {698        // This code is unreachable since it's handled by the default lexState.699        // if (c === undefined) {700        //     read()701        //     return newToken('eof')702        // }703 704        throw invalidChar(read())705    },706}707 708function newToken (type, value) {709    return {710        type,711        value,712        line,713        column,714    }715}716 717function literal (s) {718    for (const c of s) {719        const p = peek()720 721        if (p !== c) {722            throw invalidChar(read())723        }724 725        read()726    }727}728 729function escape () {730    const c = peek()731    switch (c) {732    case 'b':733        read()734        return '\b'735 736    case 'f':737        read()738        return '\f'739 740    case 'n':741        read()742        return '\n'743 744    case 'r':745        read()746        return '\r'747 748    case 't':749        read()750        return '\t'751 752    case 'v':753        read()754        return '\v'755 756    case '0':757        read()758        if (util.isDigit(peek())) {759            throw invalidChar(read())760        }761 762        return '\0'763 764    case 'x':765        read()766        return hexEscape()767 768    case 'u':769        read()770        return unicodeEscape()771 772    case '\n':773    case '\u2028':774    case '\u2029':775        read()776        return ''777 778    case '\r':779        read()780        if (peek() === '\n') {781            read()782        }783 784        return ''785 786    case '1':787    case '2':788    case '3':789    case '4':790    case '5':791    case '6':792    case '7':793    case '8':794    case '9':795        throw invalidChar(read())796 797    case undefined:798        throw invalidChar(read())799    }800 801    return read()802}803 804function hexEscape () {805    let buffer = ''806    let c = peek()807 808    if (!util.isHexDigit(c)) {809        throw invalidChar(read())810    }811 812    buffer += read()813 814    c = peek()815    if (!util.isHexDigit(c)) {816        throw invalidChar(read())817    }818 819    buffer += read()820 821    return String.fromCodePoint(parseInt(buffer, 16))822}823 824function unicodeEscape () {825    let buffer = ''826    let count = 4827 828    while (count-- > 0) {829        const c = peek()830        if (!util.isHexDigit(c)) {831            throw invalidChar(read())832        }833 834        buffer += read()835    }836 837    return String.fromCodePoint(parseInt(buffer, 16))838}839 840const parseStates = {841    start () {842        if (token.type === 'eof') {843            throw invalidEOF()844        }845 846        push()847    },848 849    beforePropertyName () {850        switch (token.type) {851        case 'identifier':852        case 'string':853            key = token.value854            parseState = 'afterPropertyName'855            return856 857        case 'punctuator':858            // This code is unreachable since it's handled by the lexState.859            // if (token.value !== '}') {860            //     throw invalidToken()861            // }862 863            pop()864            return865 866        case 'eof':867            throw invalidEOF()868        }869 870        // This code is unreachable since it's handled by the lexState.871        // throw invalidToken()872    },873 874    afterPropertyName () {875        // This code is unreachable since it's handled by the lexState.876        // if (token.type !== 'punctuator' || token.value !== ':') {877        //     throw invalidToken()878        // }879 880        if (token.type === 'eof') {881            throw invalidEOF()882        }883 884        parseState = 'beforePropertyValue'885    },886 887    beforePropertyValue () {888        if (token.type === 'eof') {889            throw invalidEOF()890        }891 892        push()893    },894 895    beforeArrayValue () {896        if (token.type === 'eof') {897            throw invalidEOF()898        }899 900        if (token.type === 'punctuator' && token.value === ']') {901            pop()902            return903        }904 905        push()906    },907 908    afterPropertyValue () {909        // This code is unreachable since it's handled by the lexState.910        // if (token.type !== 'punctuator') {911        //     throw invalidToken()912        // }913 914        if (token.type === 'eof') {915            throw invalidEOF()916        }917 918        switch (token.value) {919        case ',':920            parseState = 'beforePropertyName'921            return922 923        case '}':924            pop()925        }926 927        // This code is unreachable since it's handled by the lexState.928        // throw invalidToken()929    },930 931    afterArrayValue () {932        // This code is unreachable since it's handled by the lexState.933        // if (token.type !== 'punctuator') {934        //     throw invalidToken()935        // }936 937        if (token.type === 'eof') {938            throw invalidEOF()939        }940 941        switch (token.value) {942        case ',':943            parseState = 'beforeArrayValue'944            return945 946        case ']':947            pop()948        }949 950        // This code is unreachable since it's handled by the lexState.951        // throw invalidToken()952    },953 954    end () {955        // This code is unreachable since it's handled by the lexState.956        // if (token.type !== 'eof') {957        //     throw invalidToken()958        // }959    },960}961 962function push () {963    let value964 965    switch (token.type) {966    case 'punctuator':967        switch (token.value) {968        case '{':969            value = {}970            break971 972        case '[':973            value = []974            break975        }976 977        break978 979    case 'null':980    case 'boolean':981    case 'numeric':982    case 'string':983        value = token.value984        break985 986    // This code is unreachable.987    // default:988    //     throw invalidToken()989    }990 991    if (root === undefined) {992        root = value993    } else {994        const parent = stack[stack.length - 1]995        if (Array.isArray(parent)) {996            parent.push(value)997        } else {998            Object.defineProperty(parent, key, {999                value,1000                writable: true,1001                enumerable: true,1002                configurable: true,1003            })1004        }1005    }1006 1007    if (value !== null && typeof value === 'object') {1008        stack.push(value)1009 1010        if (Array.isArray(value)) {1011            parseState = 'beforeArrayValue'1012        } else {1013            parseState = 'beforePropertyName'1014        }1015    } else {1016        const current = stack[stack.length - 1]1017        if (current == null) {1018            parseState = 'end'1019        } else if (Array.isArray(current)) {1020            parseState = 'afterArrayValue'1021        } else {1022            parseState = 'afterPropertyValue'1023        }1024    }1025}1026 1027function pop () {1028    stack.pop()1029 1030    const current = stack[stack.length - 1]1031    if (current == null) {1032        parseState = 'end'1033    } else if (Array.isArray(current)) {1034        parseState = 'afterArrayValue'1035    } else {1036        parseState = 'afterPropertyValue'1037    }1038}1039 1040// This code is unreachable.1041// function invalidParseState () {1042//     return new Error(`JSON5: invalid parse state '${parseState}'`)1043// }1044 1045// This code is unreachable.1046// function invalidLexState (state) {1047//     return new Error(`JSON5: invalid lex state '${state}'`)1048// }1049 1050function invalidChar (c) {1051    if (c === undefined) {1052        return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)1053    }1054 1055    return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`)1056}1057 1058function invalidEOF () {1059    return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)1060}1061 1062// This code is unreachable.1063// function invalidToken () {1064//     if (token.type === 'eof') {1065//         return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)1066//     }1067 1068//     const c = String.fromCodePoint(token.value.codePointAt(0))1069//     return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`)1070// }1071 1072function invalidIdentifier () {1073    column -= 51074    return syntaxError(`JSON5: invalid identifier character at ${line}:${column}`)1075}1076 1077function separatorChar (c) {1078    console.warn(`JSON5: '${formatChar(c)}' in strings is not valid ECMAScript; consider escaping`)1079}1080 1081function formatChar (c) {1082    const replacements = {1083        "'": "\\'",1084        '"': '\\"',1085        '\\': '\\\\',1086        '\b': '\\b',1087        '\f': '\\f',1088        '\n': '\\n',1089        '\r': '\\r',1090        '\t': '\\t',1091        '\v': '\\v',1092        '\0': '\\0',1093        '\u2028': '\\u2028',1094        '\u2029': '\\u2029',1095    }1096 1097    if (replacements[c]) {1098        return replacements[c]1099    }1100 1101    if (c < ' ') {1102        const hexString = c.charCodeAt(0).toString(16)1103        return '\\x' + ('00' + hexString).substring(hexString.length)1104    }1105 1106    return c1107}1108 1109function syntaxError (message) {1110    const err = new SyntaxError(message)1111    err.lineNumber = line1112    err.columnNumber = column1113    return err1114}1115