C-like Expressions

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).

Types

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'.

  • bool
  • int8
  • uint8
  • int16
  • uint16
  • int32
  • uint32
  • int64
  • uint64
  • float
  • double
  • string
  • binary

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)

Operators

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.

Grammar

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

TODO

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++

Contact Us Directly