fastjson深度源码解析- 词法和语法解析(二) - 基础类型实现解析

本文深入探讨fastjson的JSON Token解析,分析JSONLexerBase成员函数,包括推断token类型、跳过注释、扫描字符串、数字、布尔值和标识符等关键过程,为后续的反序列化奠定基础。
摘要由CSDN通过智能技术生成

JSON Token解析

JSONLexerBase定义并实现了json串实现解析机制的基础,在理解后面反序列化之前,我们先来看看并理解重要的属性:

    /** 当前token含义 */
    protected int                            token;
    /** 记录当前扫描字符位置 */
    protected int                            pos;
    protected int                            features;

    /** 当前有效字符 */
    protected char                           ch;
    /** 流(或者json字符串)中当前的位置,每次读取字符会递增 */
    protected int                            bp;

    protected int                            eofPos;

    /** 字符缓冲区 */
    protected char[]                         sbuf;

    /** 字符缓冲区的索引,指向下一个可写
     *  字符的位置,也代表字符缓冲区字符数量
     */
    protected int                            sp;

    /**
     * number start position
     * 可以理解为 找到token时 token的首字符位置
     * 和bp不一样,这个不会递增,会在开始token前记录一次
     */
    protected int                            np;

JSONLexerBase成员函数

在开始分析词法分析实现过程中,我发现中解析存在大量重复代码实现或极其类似实现,重复代码主要解决类似c++内联调用,极其相似代码实现我会挑选有代表性的来说明(一般实现较为复杂),没有说明的成员函数可以参考代码注释。

推断token类型

fastjson token类型推断当前json字符串是那种类型的token, 比如是字符串、花括号和逗号等等。

    public final void nextToken() {
        /** 将字符buffer pos设置为初始0 */
        sp = 0;

        for (;;) {
            /** pos记录为流的当前位置 */
            pos = bp;

            if (ch == '/') {
                /** 如果是注释// 或者 \/* *\/ 注释,跳过注释 */
                skipComment();
                continue;
            }

            if (ch == '"') {
                /** 读取引号内的字符串 */
                scanString();
                return;
            }

            if (ch == ',') {
                /** 跳过当前,读取下一个字符 */
                next();
                token = COMMA;
                return;
            }

            if (ch >= '0' && ch <= '9') {
                /** 读取整数 */
                scanNumber();
                return;
            }

            if (ch == '-') {
                /** 读取负数 */
                scanNumber();
                return;
            }

            switch (ch) {
                /** 读取单引号后面的字符串,和scanString逻辑一致 */
                case '\'':
                    if (!isEnabled(Feature.AllowSingleQuotes)) {
                        throw new JSONException("Feature.AllowSingleQuotes is false");
                    }
                    scanStringSingleQuote();
                    return;
                case ' ':
                case '\t':
                case '\b':
                case '\f':
                case '\n':
                case '\r':
                    next();
                    break;
                case 't': // true
                    /** 读取字符true */
                    scanTrue();
                    return;
                case 'f': // false
                    /** 读取字符false */
                    scanFalse();
                    return;
                case 'n': // new,null
                    /** 读取为new或者null的token */
                    scanNullOrNew();
                    return;
                case 'T':
                case 'N': // NULL
                case 'S':
                case 'u': // undefined
                    /** 读取标识符,已经自动预读了下一个字符 */
                    scanIdent();
                    return;
                case '(':
                    /** 读取下一个字符 */
                    next();
                    token = LPAREN;
                    return;
                case ')':
                    next();
                    token = RPAREN;
                    return;
                case '[':
                    next();
                    token = LBRACKET;
                    return;
                case ']':
                    next();
                    token = RBRACKET;
                    return;
                case '{':
                    next();
                    token = LBRACE;
                    return;
                case '}':
                    next();
                    token = RBRACE;
                    return;
                case ':':
                    next();
                    token = COLON;
                    return;
                case ';':
                    next();
                    token = SEMI;
                    return;
                case '.':
                    next();
                    token = DOT;
                    return;
                case
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值