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 codestyle 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-namespace → use-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-statement →
usestrict
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-declaration →
modulemodule-name{module-entity0+}
module-name → identifier
module-entity → import-declaration
module-entity → define-declaration
module-entity → sources-declaration
module-entity → resources-declaration
module-entity → base-declaration
module-entity → test-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-declaration →
importpath-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-declaration →
basepath-literal
define
A define adds a key/value pair for the underlying language preprocessor,
available to the module sources.
Grammar
define-declaration →
definedefine-key=define-value
define-key → identifier
define-value → literal
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-declaration →
sources{sources-entity0+}
sources-entity → file-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-declaration →
filepath-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-declaration →
resources{resources-entity0+}
resources-entity → data-declaration
data
A data is an element of the module that represents a resource.
Grammar
data-declaration →
datadata-name data-typeopt{data-entity0+}
data-name → identifier
data-type → identifier
data-entity → file-declaration
data-entity → stream-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 aerb::AudioSamplevalue from an audio sample file.FormatSsd130x: Creates astd::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-declaration →
streamstream-format
stream-format →mono
stream-format →interleaved
stream-format →planar
Language Bindings
The generated instance will have the types AudioSampleMono, AudioSampleInterleaved
and AudioSamplePlanar.
AudioSampleMonostores the sample as a single array for floating point values,AudioSampleInterleavedstores the sample as an array of frames, each frame being an array of channels,AudioSamplePlanarstores the sample as an array of channels, each channel being an array of samples.