hron - human readable object notation
C# Java Groovy C++ F# C Other
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


hron - Human Readable Object Notation

XML and JSON (and others) aim to be human-readable, language independent, data interchange formats. However they are not without flaws:


  1. The XML author has to take care avoiding letters such as &<> and make sure to encode them properly. This hurts readability and writeability.


  1. JSON struggles with multi-line texts.
  2. JSON number values are, depending on platform, unserialized as double, long or decimal. This makes JSON number values less useful as, depending on how the value is unserialized, information may be lost. We have personally encountered this in a financial application with disastrous end results.
  3. JSON lacks strong deserializers on the .NET platform. There are many attempts but none feel as strong as the XMLDOM did already in 1998.


hron stands for human readable objection notation:

  1. we put human readable in the acronym to remind us why we started thinking about hron in the first place.
  2. hron supports multi-line texts
  3. hron doesn't require you to escape "special" characters
  4. In hron, we made indention significant (as in python) in order to eliminate end tags and to improve readability
  5. hron has objects and values. Objects consist of other objects or values. Values are always text values.
  6. There is no special array type. Arrays are created by first adding a named object or value and then just adding another one witout a name. This creates a two element array.

hron sample

# This is an ini file using hron

# object values are started with '@'
		Hello World from hron!
		Hello there!

		String values in hron are started with '='

		Just as in Python, indentation is significant in hron

		Indentation promotes readability but also allows hron string values 
		to be multi-line and relieves them from the need for escaping. 

		Let us say that again, there exists _no_ character escaping in hron. 
		Letters like this are fine in an hron string: &<>\"'@=

		This helps readability!
		Data Source=.\SQLEXPRESS;Initial Catalog=Customers

The above would (in groovy/java lingo, replace Map with dictionary for .Net) parse to a map with two keys: 'Greeting' and 'DataBaseConnection' where the value for key Greeting is a map with two string values and the value for key DataBaseConnection is a list which contains two map objects. For a good examlpe of what is an is not valid, take a look at the parser unit tests , some of which are quite descriptive.

Is There a Parser for Language X?

Possibly! Check in the languages sub directory.

We are busy implementing parsers in various languages, some as reference implementations with little concern for parser performance (i.e. the groovy parser), others with specific performance metrics in mind (like the java one). Shortly upcoming parsers include scala and c++.

If you can not find a parser in your language, fork the repo and write one! We welcome all contributions. We would especially welcome an implementation in javascript and any insane implementations in long forgotten or obscure languages, because...well because we like computer languages (hey lispers, you listening?).

We are also working on a standardized set of test files, both positive and negative, which will constitute a smoke test for new parsers.

hron grammar (EBNF)

Rules for the grammar notation:

  1. The symbol "::=" serves the same purpose as colon in Bison.
  2. Unquoted parentheses group expressions.
  3. A trailing unquoted asterisk (*) indicates 0 or more repetitions.
  4. A trailing unquoted plus (+) indicates 1 or more repetitions.
  5. Unquoted square brackets indicate an optional expression.
  6. "p EXCEPT q" means that parser succeeds if p succeeds and q fails


anychar         ::= <parses any character>
whitespace      ::= <parses any whitespace character>
eos             ::= <parses END OF STREAM>
eol             ::= <parses END OF LINE (END OF STREAM counts as END OF LINE)>
any_indention   ::= <parses any indention>
indention       ::= <parses the current indention>
indent          ::= <increases indention by one>
dedent          ::= <decreases indention by one>

empty_string    ::= (whitespace EXCEPT eol)*
string          ::= (anychar EXCEPT eol)*
comment_string  ::= any_indention "#" string

preprocessor    ::= "!" string eol
preprocessors   ::= preprocessor*

empty_line      ::= empty_string eol
comment_line    ::= comment_string eol
nonempty_line   ::= indention string eol
value_line      ::= nonempty_line | comment_line | empty_line
value_lines     ::= (value_line EXCEPT eos)*

value           ::= indention "=" string eol indent values_lines dedent
empty           ::= empty_string eol
comment         ::= comment_string eol
object          ::= indention "@" string eol indent members dedent
member          ::= value | object | comment | empty
members         ::= (member EXCEPT eos)* 

hron ::= preprocessors members

Who Are We?

Just a few guys who got tired of name spaces and entity escaping and figured the world would be a better place with a simple, human readable data interchange format.

Current contributors:

Mårten Rånge

hron language specification, BNF, and implementations in C#, C++ and F#.

Matias Bjarland

Contributions to hron language specification, implementations in groovy and java.

Mattias Karlsson

Together with Mårten responsible for spawning the idea for hron. Contributions to language specification, invaluable feedback.

Daniel Brännström

Contributed hron parsers for numerous languages such as Haskell, JavaScript, Python and PowerShell.