Core rules
Precedences
The CSN.1 strings are built up using operators like math formulas.
The various operators have precedencies.
In order to control the exact sequence of the operators, CSN.1 uses the curly braces ({ and }) the same way mathematics uses the parenthesis.
For example:
< foo bar > ::= 10 { 00 | 01 } 11; |
Rule B1: bits
The most basic symbols available to CSN.1 are those related to the values a CSN.1 string can match.
There are only two values that can be matched: 0 or 1. Therefore:
Matches 0.
Matches 1.
These two statements match a 1-bit long string.
Rule B2: Null String
The null string is a string made of 0 bits (i.e. an empty string).
No matter where null is placed, it will always match.
Rule B3: Concatenation
The concatenation is the mean used by CSN.1 to express strings longer than 1 bit.
It is expressed by simpling placing the symbols one right after the others. For example:
matches a string made of 4 bits: 0, 0, 1 and 1.
Please note that the null string can be placed everywhere:
will match the same string of the first example.
Rule B4: Choice
The "choice" | or or symbols are used to express alternatives:
This means that the above CSN.1 statement will match both 0011 and 0001.
The precedence of the concatenation is higher. Therefore:
is
and not
Rule B5: Naming
The CSN.1 definitions can be named. The names are delimited between the < and the > signs.
A name must be formed following these rules:
-
it must not be empty;
-
case is not significant;
-
heading or tailing spaces are not significant;
-
any succession of space characters is treated as a single character;
-
the characters ":", "=", "(", ")", "<" and ">" are forbidden;
The use of spaces to clarify the legibility is encouraged.
Example:
Rule B6: Definition
The definition is used to associate a name to a CSN.1 string. Its general syntax is:
< name > ::= csn.1_string ;
|
References
The names here defined can be used to reference one definition from another.
For example, instead of defining:
< foo bar > ::= 10 {0|1} {0|1};
|
it is better to define:
< bit > ::= {0|1};
< foo bar > ::= 10 < bit > < bit >;
|
Recursion
The definitions can be used recursively. For example, to describe every bit string, we can define:
< bit > ::= {0|1};
< any string > ::= null | < any string > < bit >;
|
The above example matches any string, including the empty one.
The example below, matches 4-bit nibbles separated by a "1" bit and terminated by a "0" bit, like:
1 nibble 1 nibble ... 1 nibble 0
< bit > ::= {0|1};
< 4-bit nibble > ::= < bit > < bit > < bit > < bit >;
< nibble list > ::= 0 | 1 < 4-bit nibble > < nibble list >;
|
Rule B7: Spare bits
Spare bits are those unused bits that can be found usually at the end of the string.
They are defined as being any bit when decoding and 0 when encoding. In this way, the encoder is required to fill spare bits with 0; however, the decoder is allowed to accept any bit, permitting to skip data maybe added by future extensions.
The exact definition is:
< spare bits > ::= null | < spare bits > { <bit> = 0 }; |
The '=' symbol is a
send construction
: see the related
paragraph
.
Rule B8: Padding bits
CSN.1 definitions can use the L and H terminals instead of the 0/1 ones.
A L/H match is done comparing the current bit with the corresponding one of an hypotetical string made of infinite repetitions of the octet aligned 8-bit string 00101011 (0x2B).
The L bit is matched when the bit under test is the same of the one of the reference string in the same position; H is matched when it is not the same.
[A] 00101011 00101011 00101011
[B] 1111 11110000 0000
[C] LHLL HHLHHLHH LLHL
|
In the example above, the reference string [A] si aligned to the octet.
Our test string [B] starts with a 4 bit offset.
The CSN.1 string [C] would match against [B]
Please, note that the decoder/encoder, in order to use the L/R terminals, must be aware of the octet alignment of the bit string it is processing. Therefore, its input information is not only the string it has to decode (1111111100000000 in this example), but also the offset of the first bit of the string from the octet boundary.
Therefore, a L bit could be a 0 or a 1, according to the absolute position where it happens to be.
The "spare padding" definition is often used to fill the spare octets with 0x2B:
< spare padding > ::= L {null | < spare padding >}; |
|