[Home] [Downloads] [Search] [Help/forum]

Gammon Forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Suggestions
. . -> [Subject]  Add JSON lua module to MUSHclient distribution
Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?

Add JSON lua module to MUSHclient distribution

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Sat 28 Aug 2010 11:53 PM (UTC)
Message
Is there any chance we can get one of the pure Lua implementations of a JSON parser into the standard MUSHclient distribution, i.e. in the lua/ subdirectory? There's a decent comparison of some of the known JSON bindings (both pure Lua and not) on the Lua-Users wiki [1].

[1]: http://lua-users.org/wiki/JsonModules

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Nick Gammon   Australia  (21,324 posts)  [Biography] bio   Forum Administrator
Date Reply #1 on Sun 29 Aug 2010 04:50 AM (UTC)
Message
OK I added LuaJson to the distribution for 4.59.

This is a pure Lua implementation, quite fast on decoding, and which uses LPEG for its decoding logic, which appeals to me.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by WillFa   USA  (525 posts)  [Biography] bio
Date Reply #2 on Sun 29 Aug 2010 05:55 AM (UTC)
Message
Oh yea... After you made a comment about me doing an LPEG JSON module, I found it while doing the research and decided not to reinvent the wheel... I forgot to point it out tho. :)
[Go to top] top

Posted by Nick Gammon   Australia  (21,324 posts)  [Biography] bio   Forum Administrator
Date Reply #3 on Mon 30 Aug 2010 06:28 AM (UTC)
Message
To be honest, I was hoping you would simplify down his 19-file implementation to one small, simple module. :)

But no matter.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Twisol   USA  (2,257 posts)  [Biography] bio
Date Reply #4 on Mon 30 Aug 2010 06:45 AM (UTC)
Message
There was my pure-C binding to Jansson, but that didn't seem to go very far, so I thought I'd have better luck getting a pure-Lua solution in. Guess I was right! Thanks, Nick.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by WillFa   USA  (525 posts)  [Biography] bio
Date Reply #5 on Mon 30 Aug 2010 07:31 AM (UTC)

Amended on Mon 30 Aug 2010 07:34 AM (UTC) by WillFa

Message
Nick Gammon said:

To be honest, I was hoping you would simplify down his 19-file implementation to one small, simple module. :)

But no matter.


Oh, I could do that... It shouldn't take too much. The only thing that tripped me up a little was quoting unicode in strings... The quickest way to prototype escaped meta codes was with lots of little support function, and that didn't seem too elegant to me.

I'll probably do it this coming weekend (Labor Day weekend, 3 days off)... I suspect I need to revamp InfoBox for 4.59 as well.
[Go to top] top

Posted by Nick Gammon   Australia  (21,324 posts)  [Biography] bio   Forum Administrator
Date Reply #6 on Sun 05 Sep 2010 06:10 AM (UTC)

Amended on Sun 05 Sep 2010 10:37 AM (UTC) by Nick Gammon

Message
Just to kick-start this, here is my preliminary attempt to do a JSON grammar in LPEG.


-- See: http://www.ietf.org/rfc/rfc4627.txt?number=4627

jsongrammar = lpeg.P {
  "JSON_text";  -- main rule name
  
  -- A JSON text is a serialized object or array.
  JSON_text = lpeg.V "object" + lpeg.V "array";
   
  -- separators
  name_separator  = lpeg.V "ws" * ":" * lpeg.V "ws"; 
  value_separator = lpeg.V "ws" * "," * lpeg.V "ws"; 
  
  -- whitespace
  ws    = ( lpeg.P " " + "\t" + "\n" + "\r" )^0;   -- zero or more of space, tab, newline, cr
  
  -- A JSON value MUST be an object, array, number, or string, or one of
  --  the following three literal names:  false, null, true
  value = lpeg.C (              -- capture values for now
          lpeg.P "false"  + 
                 "null"   + 
                 "true"   + 
          lpeg.V "object" + 
          lpeg.V "array"  + 
          lpeg.V "number" + 
          lpeg.V "string"
          );
  
  -- objects are comma-separated name/value pairs inside curly brackets 
  begin_object    = lpeg.V "ws" * "{" * lpeg.V "ws"; 
  end_object      = lpeg.V "ws" * "}" * lpeg.V "ws"; 
  
  object = lpeg.V "begin_object" * 
           ( lpeg.V "member" * ( lpeg.V "value_separator" * lpeg.V "member" )^0 )^-1 * 
           lpeg.V "end_object";
           
  -- object member is a name/value pair
  member = lpeg.V "string" * lpeg.V "name_separator" * lpeg.V "value";
  
  -- arrays are comma-separated values inside square brackets
  begin_array     = lpeg.V "ws" * "[" * lpeg.V "ws";
  end_array       = lpeg.V "ws" * "]" * lpeg.V "ws";
  
  array = lpeg.V "begin_array" * 
           ( lpeg.V "value" * ( lpeg.V "value_separator" *  lpeg.V "value" )^0 )^-1 * 
           lpeg.V "end_array";
  
  -- inside a string is \x or anything other than a quote
  char =  (lpeg.P '\\' * lpeg.P (1)) +
          (lpeg.P (1) -  '"');
  
  -- strings are "<something>"
  string = lpeg.P '"' * (lpeg.V "char"^0) * '"';
  
  -- numbers
  number    = (lpeg.P '-')^-1 * lpeg.V "int" * (lpeg.V "frac")^-1 * (lpeg.V "exp")^-1;
  digit     = lpeg.R "09";          -- any digit
  digit1_9  = lpeg.R "19";          -- digits 1 to 9
  e         = lpeg.P "e" + "E";     -- e or E
  exp       = lpeg.V "e" * (lpeg.P "-" + "+")^-1 * lpeg.V "digit"^1;  -- exponent
  frac      = lpeg.P "." * lpeg.V "digit"^1;                          -- fractional part
  int       = lpeg.P "." + (lpeg.V "digit1_9" * lpeg.V "digit"^0 );   -- integer part
  
   }    -- end of jsongrammar
           
result = lpeg.match (lpeg.Ct (jsongrammar), 
[[
 {
      "Image": {
          "Width":  800,
          "Height": 600,
          "Title":  "View from \"15th\" \r \n \\ Floor",
          "Thumbnail": {
              "Url":    "http://www.example.com/image/481989943",
              "Height": 125,
              "Width":  "100",
              "Nick": -1234e24
          },
          "IDs": [116, 943, 234, 38793]
        }
   }
]])

if result then
  print "matched!"
  tprint (result)
else
  print "no match"
end -- if


The outputting is not great, I threw in a lpeg.C (capture) around the value part, so I can see what JSON values are being output. This is the result:


matched!
1="{
          "Width":  800,
          "Height": 600,
          "Title":  "View from \"15th\" \r \n \\ Floor",
          "Thumbnail": {
              "Url":    "http://www.example.com/image/481989943",
              "Height": 125,
              "Width":  "100",
              "Nick": -1234e24
          },
          "IDs": [116, 943, 234, 38793]
        }
   "
2="800"
3="600"
4=""View from \"15th\" \r \n \\ Floor""
5="{
              "Url":    "http://www.example.com/image/481989943",
              "Height": 125,
              "Width":  "100",
              "Nick": -1234e24
          }"
6=""http://www.example.com/image/481989943""
7="125"
8=""100""
9="-1234e24"
10="[116, 943, 234, 38793]
        "
11="116"
12="943"
13="234"
14="38793"


I didn't look at the Lua JSON module (currently supplied with MUSHclient) but did look at the RFC which defines the JSON syntax, and tried to simply follow their grammar diagrams.

I gave up a bit on their fairly tedious string definitions and resorted to matching on "<something>" where the <something> is any character other than a quote, or the sequence \x where x can be anything. In practice the x should be limited to the values in the RFC (to be pedantic) and it should also allow for their somewhat imaginative idea of \uxxxx for Unicode sequences.

The outputting should be written in such a was that it outputs nice Lua tables, but this at least kicks of the grammar match.

References:

http://json.org/
http://www.ietf.org/rfc/rfc4627.txt?number=4627

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


6,096 views.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at FutureQuest]