Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@wongjiahau
Last active November 26, 2021 04:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wongjiahau/2babde5ad533e5a185db05e871a36e6f to your computer and use it in GitHub Desktop.
Save wongjiahau/2babde5ad533e5a185db05e871a36e6f to your computer and use it in GitHub Desktop.
IBX (Infix Binary Expression)

IBX (Infix Binary Expression)

IBX is a easily-parsable data format meant for emulating language syntax (especially Domain Specific Language).

IBX consists of mostly binary trees constructed with infix syntax, thus the name infix binary expression.

IBX is inspired by LISP S-Expression and APL.

Syntax

Reserved characters

The following characters has special meaning in IBX, and thus cannot be used as part of an identifier.

Name Visual
Parenthesis ( )
Square brackets [ ]
Curly brackets { }
Single quote '
Double quote "
Backtick `

Tokens

Type Example
Identifier* foo + ->
String Literal "Hello World!"
Numeric Literal 123.783
Parenthesized expression (1 + 2 - 3)

Note: Identifier are either alphanumeric+underscore+dollar characters OR composed of non-whitespace, non-alphanumeric and non-reserved characters.

Binary Trees & Unary Trees

The main feature of IBX are binary trees that are left-associative[1].

Trees constructed based on the following rules:

Tokens Parsed Binary Tree
a b a b
a b c a b c
a b c d (a b c) d
a b c d e (a b c) d e
a b c d e f ((a b c) d e) f

Examples

Tokens Parsed Tree
1 ! 1 !
1 + 1 1 + 1
1 + 1 ! (1 + 1) !
1 + 2 - 3 (1 + 2) - 3
1 + 2 - 3 ! ((1 + 2) - 3) !
1 + 2 - 3 * 4 ((1 + 2) - 3) * 4

Array

Array is composed of a list of tokens enclosed within a pair of square brackets.

For example, the following array contains 3 elements.

["Hello world" 123 (1 + 3)]

Object

Object is composed of a binary tree enclosed within a pair of curly brackets. IBX object is similar to JSON object, however, the number of keys may be one less than the number of values, where the first value has an implicit key 0.
This particular difference allows IBX to better encode DSL than JSON as it is less verbose.

Example (when tokens count is odd):

IBX JSON-5
{"hello"} {0: "hello"}
{1 and 2} {0: 1, and: 2}
{1 < 2 < 3} {0: 1, "<": 2, "<": 3}

Example (when tokens count is even):

IBX JSON-5
{name "Bartholomew"} {name: "Bartholomew"}
{name "Ginger" size [1 2 3]} {name: "Ginger", size: [1,2,3]}

Emulation Examples

1. MongoDB Queries

Original (JSON-5)

{$and: [{likes: {$gt: 1}}, {age: {$ne: 1}}]}

IBX

likes $gt 1 $and (age $ne 1)

2. HTML

Original

<a class="link" href="https://hello.com">
  <span>Hello world</span>
  <span>Yo</span>
</a>

IBX

{a class "link" href "https://hello.com" _ [
  {span _ ["Hello world"]}
  {span _ ["yo"]}
]}

3. Javascript method chaining

Original

[1, 2, 3]
  .filter(x => x % 2 === 0)
  .map(x => x + 1)
  .reduce((a, b) => a + b, 0)

IBX

[1 2 3]
  filter (x => (x % 2 === 0))
  map (x => (x + 1))
  reduce [+ 0]

4. Cron Expression

Original

0 3 */2 3-4 FRI

IBX

[0 3 (* / 2) (3 - 4) FRI]

5. GraphQL Operations

Original

query GetKrabbyPatty($size: Size!) {
  getKrabbyPatty(size: $size) {
    id
    sauce
    cookedBy {
      name
    }
  }
}

IBX

query (GetKrabbyPatty {$size (!Size)}) {
  (getKrabbyPatty {size $size}) {
    id,
    sauce,
    cookedBy {
      name,
    }
  }
}

6. SQL Query

Original

select 
  id, species as name 
from 
  fruit 
where 
  kind = 'tropical' and color = 'red'
order by created_on;

IBX

{
  select 
    [id (species as name)]
  from 
    fruit
  where
    (kind = 'tropical' and (color = 'red'))
  orderBy
    created_on
}

Postscript

  1. Initially, IBX uses right-associativity instead of left-associativity due to influence from APL. However, after browsing through operators tables in various mainstream languages like C++ and JS, I found that most of the operators are left-associative, where right-associative operators are mostly assignment operators like = or +=. Thus I felt that left-associativity should appear more natural to most users, myself included.
// Note: the following grammar has not yet included Unary Tree
Ibx {
Exp
= BinaryExp
BinaryExp
= BinaryExp PriExp PriExp -- BinaryExp
| PriExp
PriExp
= Parenthesized
| Array
| Object
| ident
| number
| symbol
| string
Array
= "[" PriExp* "]"
Object
= "{" (PriExp PriExp)* "}" --EvenKeysObject
| "{" PriExp (PriExp PriExp)* "}" --OddKeysObject
Parenthesized
= "(" Exp ")"
symbol
= ~(space | alnum | brackets | quotes) any
brackets
= "{" | "}" | "(" | ")" | "[" | "]"
quotes
= "\"" | "'" | "`"
ident (an identifier)
= letter alnum*
number (a number)
= digit* "." digit+ -- fract
| digit+ -- whole
stringDelimiter = "\""
string = stringDelimiter (~stringDelimiter any)* stringDelimiter
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment