首页 > 解决方案 > 使用 Parsimmon 解析用户在 JavaScript 中输入的数组

问题描述

我正在研究如何解析用户输入的 JavaScript 数组,例如'[1, 2, 3, 4, [1, 2, 3], "test", "test hello"]'. 现在,我发现 Parsimmon 似乎是一个很好的工具。该库附带了一个 JSON 解析器示例,如下所示:

let JSONParser = P.createLanguage({
            // This is the main entry point of the parser: a full JSON value.
            value: r =>
                P.alt(
                    r.object,
                    r.array,
                    r.string,
                    r.number,
                    r.null,
                    r.true,
                    r.false
                ).thru(parser => whitespace.then(parser)),

            // The basic tokens in JSON, with optional whitespace afterward.
            lbrace: () => word("{"),
            rbrace: () => word("}"),
            lbracket: () => word("["),
            rbracket: () => word("]"),
            comma: () => word(","),
            colon: () => word(":"),

            // `.result` is like `.map` but it takes a value instead of a function, and
            // `.always returns the same value.
            null: () => word("null").result(null),
            true: () => word("true").result(true),
            false: () => word("false").result(false),

            // Regexp based parsers should generally be named for better error reporting.
            string: () =>
                token(P.regexp(/"((?:\\.|.)*?)"/, 1))
                    .map(interpretEscapes)
                    .desc("string"),

            number: () =>
                token(P.regexp(/-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?/))
                    .map(Number)
                    .desc("number"),

            // Array parsing is just ignoring brackets and commas and parsing as many nested
            // JSON documents as possible. Notice that we're using the parser `json` we just
            // defined above. Arrays and objects in the JSON grammar are recursive because
            // they can contain any other JSON document within them.
            array: r => r.lbracket.then(r.value.sepBy(r.comma)).skip(r.rbracket),

            // Object parsing is a little trickier because we have to collect all the key-
            // value pairs in order as length-2 arrays, then manually copy them into an
            // object.
            pair: r => P.seq(r.string.skip(r.colon), r.value),

            object: r =>
                r.lbrace
                    .then(r.pair.sepBy(r.comma))
                    .skip(r.rbrace)
                    .map(pairs => {
                        let object = {};
                        pairs.forEach(pair => {
                            let [key, value] = pair;
                            object[key] = value;
                        });
                        return object;
                    })
        });

现在,我尝试在不使用 createLanguage 函数的情况下为 Array 实现自己的解析器,这是我目前的实现:

let comma = word2(',');
let lBracket = word2('[');
let rBracket = word2(']');
let arrayParser = P.lazy(
            () =>
                // P.seq(
                lBracket.then(
                    P.alt(
                        P.digits,
                        // stringParser.trim(P.optWhitespace).sepBy(P.string(','))
                        // P.digits.sepBy1(P.string(',')),
                        arrayParser
                    ).thru(parser => P.optWhitespace.then(parser)).sepBy(comma)
                ).skip(
                    rBracket.trim(P.optWhitespace)
                )
            // )
        );

该实现适用于解析以下内容:

'[1, 2, 3, 4]'

但不适用于解析嵌套数组:

'[1, 2, 3, [1, 2, 3], 4]'

如果有人愿意回答,我想了解我做错了什么。

谢谢!

标签: javascriptstring-parsingparser-combinators

解决方案


推荐阅读