Erbb Grammar

This document describes what sequence of tokens form valid inputs of the language.

How to Read the Grammar

The notation used to describe the formal grammar of erbb has the following conventions:

  • An arrow (→) is used to mark grammar productions and can be read as “can consist of”,

  • Alternative grammar productions are either separated by verticals bars (|) or are broken into multiple grammar production rules lines,

  • Keywords and symbols are indicated using bold inline code style text,

  • Optional syntactic categories and literals are marked by a trailing subscript (opt),

  • Syntactic category or literal repetitions of 0 or more are marked by a trailing subscript (0+),

  • Syntactic category or literal repetitions of 1 or more are marked by a trailing subscript (1+).

Global namespace

The global namespace is the root of the grammar. One and only one module declaration is valid.

Grammar

global-namespaceuse-strict-statementopt module-declaration

use strict

This statement enables more compile-time checks by enabling all warnings and turning them into errors. When this statement is not used, the compiler will use its default configuration, which has reduced warning checks and doesn’t report them as errors.

Grammar

use-strict-statementuse strict

module

A module defines a physical module, a unique piece of hardware to produce. it is a set of multiple import, sources, base, define, etc. declarations.

Grammar

module-declarationmodule module-name { module-entity0+ }
module-nameidentifier
module-entityimport-declaration
module-entitydefine-declaration
module-entitysources-declaration
module-entityresources-declaration
module-entitybase-declaration

import

An import merges the parsed content of the associated path into the parent module.

The path is relative to the current parsed file.

Grammar

import-declarationimport path-literal

base

A base defines a header search path for the module sources.

The path is relative to the current parsed file. This is typically used in libraries, to disambiguate file includes with the same name.

Grammar

base-declarationbase path-literal

define

A define adds a key/value pair for the underlying language preprocessor, available to the module sources.

Grammar

define-declarationdefine define-key = define-value
define-keyidentifier
define-valueliteral

Language Bindings

define-key is exported to the target language preprocessor.

For example the following erbb source code:

module Foo {
   define MY_FLAG=1
   sources {
      file "Foo.cpp"
      file "Foo.h"
   }
}

Defines MY_FLAG for all sources in the module:

// Foo.cpp
void  process () {
   #if MY_FLAG == 1
      // do something
   #else
      // do something else
   #endif
}

Predefined keys

Some predefined keys are available for the system and are prefixed by erb_. This allows for example to instrument the buffer size or tell the SdRam system how much memory it can allocate at max.

sources

The sources defines the source code of the module.

Grammar

sources-declarationsources { sources-entity0+ }
sources-entityfile-declaration

file

A file defines a file to compile in the module sources.

The path is relative to the current parsed file. This is typically C++ source and header files, audio sample files, but can be also the erbb file.

Grammar

file-declarationfile path-literal

resources

The resources defines the resources of the module, like an audio sample. They are piece of data compiled with the program for convenience.

Grammar

resources-declarationresources { resources-entity0+ }
resources-entitydata-declaration

data

A data is an element of the module that represents a resource.

Grammar

data-declarationdata data-name data-typeopt { data-entity0+ }
data-nameidentifier
data-typeidentifier
data-entityfile-declaration
data-entitystream-declaration

Language Bindings

data-name is exported to the target language used to develop the module DSP, such as C++ or Max.

For example the following erbb source code:

module Foo {
   data osc_sample AudioSample {
      file "osc_sample.wav"
   }
}

Exports the osc_sample in C++:

void  process () {
   float val = data.osc_sample.frames [0].channels [0];

   // 'data.osc_sample' is a 'erb::AudioSample <float, length, nbr_channels>'
   // where 'length' and 'nbr_channels' are automatically deduced from
   // the input file.
}

Omitting data-type results in raw data.

module Foo {
   data raw {
      file "raw.bin"
   }
}
   uint8_t val = data.raw [0];
   
   // 'data.raw' is a 'std::array <uint8_t, size>' where 'size' is the size of
   // the input file.

Supported Types

  • AudioSample: Creates a erb::AudioSample value from an audio sample file.

  • FormatSsd130x: Creates a std::array <uint8_t, ...> value from an image file.

stream

A stream defines the representation of frames, channels and samples for an AudioSample data type. When not specified, mono audio samples are assumed mono and multi-channels audio samples are assumed interleaved, to maximize cache coherency and simplify processing using SIMD instructions.

Grammar

stream-declarationstream stream-format
stream-formatmono
stream-formatinterleaved
stream-formatplanar

Language Bindings

The generated instance will have the types AudioSampleMono, AudioSampleInterleaved and AudioSamplePlanar.

  • AudioSampleMono stores the sample as a single array for floating point values,

  • AudioSampleInterleaved stores the sample as an array of frames, each frame being an array of channels,

  • AudioSamplePlanar stores the sample as an array of channels, each channel being an array of samples.