Mungo
A simple associative data language by Overkill
Easy to use, and stupidly easy to parse.
Table of Contents
About Mungo
Mungo is magical associative data language that easily chomps up silly datafiles with the ferocity of a mongoose (mungos mungo). Then through parsing, it can be excreted into native tabular/associative/structured form!
Here's what it looks like!
[ This is a comment! ]
* Potion
- Description:
"A miraculously disgusting concotion with curative properties. "
"Made from unicorn bladders, pidgeon blood and pixie sticks."
- Usable: Yes
- Heal: 50
* Sword
- Equippable: Yes
- Stats
= Attack: 37
= Critical: 42
- 'Description':
"Since ancient times, we have found the need to stab"
"people with sharp objects. This particular sharp object is *fancy* and magical!"
* Blah Blah
- Description:
'"' Blah Blah '" '
"accurately describes this item. But note the mixture of quotes and plain "
"text, and that the Blah Blah becomes BlahBlah."
- LOOK
> AT
+ THIS
| REALLY
= LONG
# LIST
~ OF: stuff
*We-can+even|just~get>away[hey comment in midtext]=with#this:"if we wanted"
[] are for comments.
"", '', `` are for string quotes.
*-+|~>=# are list delimiters, used to start a list block, associated with some key defined before it (unless it is the first, outermost delimiter).
: is the mapping delimiter, used to associate identifier keys with identifier values.
Simple! Amazing. Yummy. We made a format that looks decent, is simple to use, and easy to parse into a native data format.
We don't care about a lot of things. There aren't restrictions on what identifiers can be, only what few reserved characters they can't be. And these reserved characters can easily be writen anyways, because you can just put them in quotes. Whitespace is meaningless to the parser, giving you complete half-assed freedom to sprinkle it wherever you want. All the indentifier characters for a key or value are mashed into one string, making it simple. We don't care about validation beyond a few simple things regarding the special delimiters, and neither should you want strict enforcement on a simple-to-use data container language. Just use it.
Compare Me! Compare Me!
Awesome, right? But you think your builtin data types or alternative data expression languages are okay? You're just being silly. Cut it out. Allow me to demonstrate why you're plain wrong. Below are the equivalent in other languages (spaced so that literals are actually legible and don't break th' page).
vs. Python's Dictionaries
stuff = {
'BlahBlah':
{
'Description': '"BlahBlah"accurately describes this item. But note the mixture of quotes and plain'
+ 'text, and that the Blah Blah becomes BlahBlah.',
'LOOK':
{
'AT':
{
'THIS':
{
'REALLY':
{
'LONG':
{
'LIST':
{
'OF':
'stuff'
}
}
}
}
}
}
},
'We':
{
'can':
{
'even':
{
'just':
{
'get':
{
'away':
{
'with':
{
'this': 'if we wanted'
}
}
}
}
}
}
},
'Potion':
{
'Usable': 'Yes',
'Description': 'A miraculously disgusting concotion with curative properties.'
+ 'Made from unicorn bladders, pidgeon blood and pixie sticks.',
'Heal': '50'
},
'Sword':
{
'Stats':
{
'Attack': '37',
'Critical': '42'
},
'Description': 'Since ancient times, we have found the need to stab'
+ 'people with sharp objects. This particular sharp object is *fancy* and magical!',
'Equippable': 'Yes'
}
}
vs. Lua's Tables
stuff = {
BlahBlah = {
Description = '"BlahBlah"accurately describes this item. But note the mixture of quotes and plain'
.. 'text, and that the Blah Blah becomes BlahBlah.',
LOOK = {
AT = {
THIS = {
REALLY = {
LONG = {
LIST = {
OF = 'stuff'
}
}
}
}
}
}
},
We = {
can = {
even = {
just = {
get = {
away = {
with = {
this = 'if we wanted'
}
}
}
}
}
}
},
Potion = {
Usable = 'Yes',
Description = 'A miraculously disgusting concotion with curative properties.'
.. 'Made from unicorn bladders, pidgeon blood and pixie sticks.',
Heal = '50'
},
Sword = {
Stats = {
Attack = '37',
Critical = '42'
},
Description = 'Since ancient times, we have found the need to stab'
.. 'people with sharp objects. This particular sharp object is *fancy* and magical!',
Equippable = 'Yes'
}
}
vs. XML
...ugh. What an abortion of a "generic" data markup language. I don't even know if this XML is valid, but I can tell you it's looking pretty ugly.
<Item name="BlahBlah">
<Description>"BlahBlah"accurately describes this item. But note the mixture of quotes and plain
text, and that the Blah Blah becomes BlahBlah.</Description>
<LOOK>
<AT>
<THIS>
<REALLY>
<LONG>
<LIST>
<OF>stuff</OF>
</LIST>
</LONG>
</REALLY>
</THIS>
</AT>
</LOOK>
</Item>
<We>
<Can>
<Even>
<Just>
<Get>
<Away>
<With>
<This>if we wanted</This>
</With>
</Away>
</Get>
</Just>
</Even>
</Can>
</We>
<Item name="Potion">
<Usable>Yes</Usable>
<Description>A miraculously disgusting concotion with curative properties.
Made from unicorn bladders, pidgeon blood and pixie sticks.</Description>
<Heal>50</Heal>
</Item>
<Item name="Sword">
<Stats>
<Attack>37</Attack>
<Critical>42</Critical>
</Stats>
<Description>Since ancient times, we have found the need to stab
people with sharp objects. This particular sharp object is *fancy* and magical!</Description>
<Equippable>Yes</Equippable>
</Item>
vs. PHP's Arrays
$stuff = array(
'BlahBlah' => array(
'Description' => '"BlahBlah"accurately describes this item. But note the mixture of quotes and plain'
. 'text, and that the Blah Blah becomes BlahBlah.',
'LOOK' => array(
'AT' => array(
'THIS' => array(
'REALLY' => array(
'LONG' => array(
'LIST' => array(
'OF' =>
'stuff'
)
)
)
)
)
)
),
'We' => array(
'can' => array(
'even' => array(
'just' => array(
'get' => array(
'away' => array(
'with' => array(
'this' => 'if we wanted'
)
)
)
)
)
)
),
'Potion' => array(
'Usable' => 'Yes',
'Description' => 'A miraculously disgusting concotion with curative properties.'
. 'Made from unicorn bladders, pidgeon blood and pixie sticks.',
'Heal' => '50'
),
'Sword' => array(
'Stats' => array(
'Attack' => '37',
'Critical' => '42'
),
'Description' => 'Since ancient times, we have found the need to stab'
. 'people with sharp objects. This particular sharp object is *fancy* and magical!',
'Equippable' => 'Yes'
)
)
vs. Ruby's Hashes
stuff = {
'BlahBlah' => {
'Description' => '"BlahBlah"accurately describes this item. But note the mixture of quotes and plain'
+ 'text, and that the Blah Blah becomes BlahBlah.',
'LOOK' => {
'AT' => {
'THIS' => {
'REALLY' => {
'LONG' => {
'LIST' => {
'OF' => 'stuff'
}
}
}
}
}
}
},
'We' => {
'can' => {
'even' => {
'just' => {
'get' => {
'away' => {
'with' => {
'this' => 'if we wanted'
}
}
}
}
}
}
},
'Potion' => {
'Usable' => 'Yes',
'Description' => 'A miraculously disgusting concotion with curative properties.'
+ 'Made from unicorn bladders, pidgeon blood and pixie sticks.',
'Heal' => '50'
},
'Sword' => {
'Stats' =>
{
'Attack' => '37',
'Critical' => '42'
},
'Description' => 'Since ancient times, we have found the need to stab'
+ 'people with sharp objects. This particular sharp object is *fancy* and magical!',
'Equippable' => 'Yes'
}
}
vs. Java's HashMaps
I won't write out the whole thing for this. There aren't any nice constructs that'll reduce the amount you need to type to initialize the hash table. It becomes very clear a data association language parser would be greatly beneficial in a language without table literals.
HashMap<String, Object> stuff = new HashMap<String, Object>();
HashMap<String, Object> potion = new HashMap<String, Object>();
potion.put("Usable", "Yes");
potion.put("Description", "A miraculously disgusting concotion with curative properties."
+ "Made from unicorn bladders, pidgeon blood and pixie sticks.");
potion.put("Heal", "50");
stuff.put("Potion", potion);
HashMap<String, Object> sword = new HashMap<String, Object>();
sword.put("Equippable", "Yes");
sword.put("Description", "Since ancient times, we have found the need to stab"
+ "people with sharp objects. This particular sharp object is *fancy* and magical!");
HashMap<String, Object> stats = new HashMap<String, Object>();
stats.put("Attack", "37");
stats.put("Critical", "42");
sword.put("Stats", stats);
stuff.put("Sword", sword);
...Then again, you might opt for using classes instead, but then, if you want to load data it has to follow strict formatting requirements due to strict typing on everything. This is where a Mungo wrapper comes in handy, able to transform the data into a hashtable, which can then be indexed by smart methods that cast to the appropriate types in a class.
Bah, that's enough comparison, I think. So now you have incentive to use a ferocious and relentlessly great language like Mungo!
Parsers
Parser magic go! My parser code admittedly sucks for parsing efficiency, but they were written pretty quickly so whatever.
for Python
- mungo.py, a quick and dirty parser that reads a mungo file and spews out a Python dictionary. Simply do this to use it:
import mungo try: d = mungo.MungoToDict("myfile.mungo") except mungo.MungoParseException, detail: print "Failed to parse: ", detail
for Lua
- mungo.lua, a quick and dirty parser that reads a mungo file and spews out a Lua table. Simply do this to use it:
require "mungo" t, err = MungoToTable("myfile.mungo") if err then error("Failed to parse: " .. err) end
...But what about ____?
Well, I'd love to add support for other languages, but keep a few things in mind:
- I'm just one guy
- I like to think I have a life, sometimes. I'd much rather be making games, and I just made my job easier by writing those parsers.
- I need to know that language, or learn it before I can make a parser.
- I'd very much encourage other people to improve on this specification or make their own, better, parsers. They're simple!
That said, I'd probably be willing to port my parser to another language, but you'd need to give me time.
I have plans to eventually port this to C or Java, which would allow this interpreter to be used in strongly typed languages, and allow it to be embedded into pretty much any language that has C or Java bindings!
I will update the listing on this page when more parsers become available.
Contact Me
Having problems? Find a bug? Want to improve Mungo somehow and you've got free time or suggestions? Do you just want to say hello?
- Email: overkill9999 AT gmail DOT com.
- MSN: overkill9999 AT hotmail DOT com.
- AIM: Minimum Overkill.
- irc.esper.net, irc.lunarnet.org: Overkill, hanging out in a variety of channels.