JSON_parse.ah2

Post your working scripts, libraries and tools.
MrDoge
Posts: 151
Joined: 27 Apr 2020, 21:29

JSON_parse.ah2

Post by MrDoge » 04 May 2022, 19:44

https://github.com/FuPeiJiang/JSON.ah2

Code: Select all

JSON_parse(str) {

    c_:=1

    return JSON_value()

    JSON_value() {

        char_:=SubStr(str, c_, 1)
        Switch char_ {
            case "{":
                obj_:=Map()
                ;object
                c_++
                loop {
                    skip_s()
                    if (SubStr(str, c_, 1) == "}") {
                        c_++
                        return obj_
                    }

                    ; key_:=JSON_objKey()
                    ; a or "a"
                    if (SubStr(str, c_, 1) == "`"") {
                        RegExMatch(str, "(?:\\.|.)*?(?=`")", &OutputVar, c_ + 1)
                        key_:=RegExReplace(OutputVar.0, "\\(.)", "$1")
                        c_+=OutputVar.Len
                    } else {
                        RegExMatch(str, ".*?(?=[\s:])", &OutputVar, c_)
                        key_:=OutputVar.0
                        c_+=OutputVar.Len
                    }

                    c_:=InStr(str, ":", true, c_) + 1
                    skip_s()

                    value_:=JSON_value()
                    obj_[key_]:=value_
                    obj_.DefineProp(key_, {Value: value_})

                    skip_s()
                    if (SubStr(str, c_, 1) == ",") {
                        c_++, skip_s()
                    }
                }
            case "[":
                arr_:=[]
                ;array
                c_++
                loop {
                    skip_s()
                    if (SubStr(str, c_, 1) == "]") {
                        c_++
                        return arr_
                    }

                    value_:=JSON_value()
                    arr_.Push(value_)

                    skip_s()
                    char_:=SubStr(str, c_, 1)
                    if (char_ == ",") {
                        c_++, skip_s()
                    }
                }
            case "`"":
                RegExMatch(str, "(?:\\.|.)*?(?=`")", &OutputVar, c_ + 1)
                unquoted:=RegExReplace(OutputVar.0, "\\(.)", "$1")
                c_+=OutputVar.Len + 2
                return unquoted
            case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9":
                RegExMatch(str, "[0-9.]*", &OutputVar, c_)
                c_+=OutputVar.Len
                return Number(OutputVar.0)
            case "t":
                ;"true"
                c_+=4
                return {a:1}
            case "f":
                ;"false"
                c_+=5
                return {a:0}
            case "n":
                ;"null"
                c_+=4
                return {a:-1}


        }
    }

    skip_s() {
        RegExMatch(str, "\s*", &OutputVar, c_)
        c_+=OutputVar.Len
    }
}
this time I cheated: used regex, used recursion, code should be fairly easy to understand, 96 lines
_______________README.md

true
{a:1}
false
{a:0}
null
{a:-1}

these are the only types that is Object()

JSON object is Map() with properties assigned
so JSON properties are defined Twice

Code: Select all

obj_[key_]:=value_
obj_.DefineProp(key_, {Value: value_})

Code: Select all

MsgBox JSON_parse(FileRead("AutoHotkey_L releases.json"))[1]["assets"][1]["browser_download_url"]
MsgBox JSON_parse(FileRead("AutoHotkey_L releases.json"))[1].assets[1].browser_download_url
both work

Return to “Scripts and Functions (v2)”