Snap! Websites
An Open Source CMS System in C++
The snapwebsites library includes a parser (yacc like tool) which can be used to generate grammars and thus support different mini-languages that are used internally by the Snap! system to enhance the capabilities by letting end users enter really advanced expressions or definitions.
For example, the domain and website definitions make use of a mini language that allows for a set of domains, a set of websites and each include a set of parameters with optional data.
One extension that is part of the library is support for advanced C-like expressions that are linked to the Cassandra database. At this point the expressions are read-only (it cannot modified the database).
The C-like expression supports C-like types. We do not currently support 'char' but we may add it later. At this point you can make use of a string first character as a 'char'.
By default, all literals are defined as int64 for integers, double for floating points, and string for strings. To convert data to another type, use the name of a type as a function name. For example, make the number 32 an 8 bit number with:
int8(32)
Most of the C operators are supported in some way. However, we do not support any pointer related operators since we do not support that special type.
The table below shows you what operator functions against why type. Remember that you can cast a value to another type. The operators are ordered by priority, highest to lowest.
Priority | Operator | Boolean | Integer | Floating Point | String | Binary |
---|---|---|---|---|---|---|
15. Unary | ! | Yes | Yes | Yes | Yes | Yes |
~ | Yes | Yes | – | – | – | |
+ | Yes | Yes | Yes | Yes | Yes | |
- | Yes | Yes | Yes | – | – | |
( expr ) | – | – | – | – | – | |
14. Multiplicative | * | Yes | Yes | Yes | Yes | – |
/ | Yes | Yes | Yes | – | – | |
% | Yes | Yes | – | – | – | |
13. Additive | + | Yes | Yes | Yes | Yes | Yes |
- | Yes | Yes | Yes | – | – | |
12. Shift | << | Yes | Yes | – | – | – |
>> | Yes | Yes | – | – | – | |
11. Relational | < | Yes | Yes | Yes | Yes | Yes |
<= | Yes | Yes | Yes | Yes | Yes | |
> | Yes | Yes | Yes | Yes | Yes | |
>= | Yes | Yes | Yes | Yes | Yes | |
<? | Yes | Yes | Yes | Yes | Yes | |
>? | Yes | Yes | Yes | Yes | Yes | |
10. Equality | == | Yes | Yes | Yes | Yes | Yes |
!= | Yes | Yes | Yes | Yes | Yes | |
9. Bitwise AND | & | Yes | Yes | – | – | – |
8. Bitwise XOR | ^ | Yes | Yes | – | – | – |
7. Bitwise OR | | | Yes | Yes | – | – | – |
6. Logical AND | && | Yes | Yes | Yes | Yes | Yes |
5. Logical XOR | ^^ | Yes | Yes | Yes | Yes | Yes |
4. Logical OR | || | Yes | Yes | Yes | Yes | Yes |
3. Conditional | ?: | – | – | – | – | – |
2. Assignment | := | – | – | – | – | – |
1. List | , | – | – | – | – | – |
The few operators that have no specific type specified are considered type agnostic. They work with all types.
The process accepts lists of expressions each separated by a comma, however, they have to be defined between parenthesis (this is done that way to simplify the grammar.)
The "^^" operator is an addition. It does not exist in C/C++. It transforms the left hand and right hand expressions to booleans before computing the XOR. Otherwise it is very similar to the "^" operator.
The "<?" and ">?" operators are duplicates of a feature that was available in g++ a while back. It means minimum and maximum or the two specified parameters.
The "+" operator concatenates strings and binary buffers.
The "*" operator can be used with a string as the left hand parameter and an itneger as the right hand side parameter. This duplicates the string that number of times. The integer should not be too large or you'll crash (out of memory). The integer must be positive or zero.
The following is the grammar to make it simpler to understand for those who can read yacc like grammars. The grammar shows the priority of the operators.
expr: assignment
assignment: conditional
| IDENTIFIER ':=' conditional
conditional: logical-or
| conditional '?' expr ':' logical-or
logical-or: logical-xor
| logical-or '||' logical-xor
logical-xor: logical-and
| logical-xor '^^' logical-and
logical-and: bitwise-or
| logical-and '&&' bitwise-or
bitwise-or: bitwise-xor
| bitwise-or '|' bitwise-xor
bitwise-xor: bitwise-and
| bitwise-xor '^' bitwise-and
bitwise-and: equality
| bitwise-and '&' equality
equality: relational
| equality '==' relational
| equality '!=' relational
relational: shift
| relational '<' shift
| relational '<=' shift
| relational '>' shift
| relational '>=' shift
| relational '<?' shift
| relational '>?' shift
shift: additive
| shift '<<' additive
| shift '>>' additive
additive: multiplicative
| additive '<<' multiplicative
| additive '>>' multiplicative
multiplicative: unary
| multiplicative '*' unary
| multiplicative '/' unary
| multiplicative '%' unary
unary: '!' unary
| '~' unary
| '+' unary
| '-' unary
| '(' expr-list ')'
| qualified-name '(' expr-list ')'
| IDENTIFIER
| 'true'
| 'false'
| STRING
| INTEGER
| FLOAT
expr-list: expr
| expr-list ',' expr
qualified-name: IDENTIFIER
| qualified-name '::' IDENTIFIER
We are planning to add the ~= operator (relational used to match a string against a regex.)
Trigonometric and other floating point functions will be added with time.
The modulo operator will be made available for floating point numbers.
Snap! Websites
An Open Source CMS System in C++