## CtplLexerExpr CtplLexerExpr — Syntax analyser for mathematical/test expressions |

## Synopsis

    #include <ctpl/ctpl.h>

    #define             CTPL_LEXER_EXPR_ERROR
    enum                CtplLexerExprError;
    CtplTokenExpr *     ctpl_lexer_expr_lex                 (CtplInputStream *stream,
                                                             GError **error);
    CtplTokenExpr *     ctpl_lexer_expr_lex_full            (CtplInputStream *stream,
                                                             gboolean lex_all,
                                                             GError **error);
    CtplTokenExpr *     ctpl_lexer_expr_lex_string          (const gchar *expr,
                                                             gssize len,
                                                             GError **error);

## Description

Syntax analyser for mathematical or test expressions creating a token tree from an expression.

To analyse an expression, use `ctpl_lexer_expr_lex()`. The resulting expression should be freed with `ctpl_token_expr_free()` when no longer needed.

An expression is something like a mathematical expression that can include references to variables. The allowed things are:

Binary operators | addition (`+`), subtraction (`-`), multiplication (`*`), division (`/`), modulo (`%`), and the boolean equality (`==`), non-equality (`!=`), inferiority (`<`), inferiority-or-equality (`<=`), superiority (`>`), superiority-or-equality (`>=`), AND (`&&`), and OR (`||`). The boolean operators results to the integer 0 if their expression evaluates to false, or to the positive integer 1 if their expression evaluates to true. This result might be used as a plain integer. The operators' priority is very common: boolean operators have the higher priority, followed by division, modulo and multiplication, and finally addition and subtraction which have the lower priority. When two operators have the same priority, the left one is prior over the right one.
Unary operators | The unary operators plus (`+`) and minus (`-`), that may precede any numeric operand.
Operands | Any numeric constant that `ctpl_input_stream_read_number()` supports, any reference to any environment variable, or any string literal that `ctpl_input_stream_read_string_literal()` supports. An operand may be suffixed with an index of the form `[<expression>]`.
Parentheses | Parentheses may be placed to delimit sub-expressions, allowing a fine control over operator priority.

Example 12. A simple expression

    1
    42 * 2

Example 13. A more complicated expression

    1
    (foo + 1) * 3 - 2 * bar

Example 14. An expression with indexes

    1
    array[array[idx + 1]] * array[idx]

Of course, the latter examples supposes that the environment contains the variables `foo`, `bar`, `array` and `idx`, and that they contains appropriate values for latter evaluation.

## Details

### CTPL_LEXER_EXPR_ERROR

    #define CTPL_LEXER_EXPR_ERROR (ctpl_lexer_expr_error_quark ())

Error domain of CtplLexerExprError.

### enum CtplLexerExprError

    typedef enum _CtplLexerExprError
    {
      CTPL_LEXER_EXPR_ERROR_MISSING_OPERAND,
      CTPL_LEXER_EXPR_ERROR_MISSING_OPERATOR,
      CTPL_LEXER_EXPR_ERROR_SYNTAX_ERROR,
      CTPL_LEXER_EXPR_ERROR_FAILED
    } CtplLexerExprError;

Error codes that lexing functions can throw, from the `CTPL_LEXER_EXPR_ERROR` domain.

`CTPL_LEXER_EXPR_ERROR_MISSING_OPERAND` | An operand is missing
`CTPL_LEXER_EXPR_ERROR_MISSING_OPERATOR` | An operator is missing
`CTPL_LEXER_EXPR_ERROR_SYNTAX_ERROR` | The expression has invalid syntax
`CTPL_LEXER_EXPR_ERROR_FAILED` | An error occurred without any precision on what failed.

### ctpl_lexer_expr_lex ()

    CtplTokenExpr *     ctpl_lexer_expr_lex                 (CtplInputStream *stream,
                                                             GError **error);

Tries to lex the expression in `stream`. If you want to lex a CtplInputStream that (may) hold other data after the expression, see `ctpl_lexer_expr_lex_full()`.

`stream` : | A CtplInputStream from where read the expression
`error` : | Return location for errors, or `NULL` to ignore them.
Returns : | A new CtplTokenExpr or `NULL` on error.

### ctpl_lexer_expr_lex_full ()

    CtplTokenExpr *     ctpl_lexer_expr_lex_full            (CtplInputStream *stream,
                                                             gboolean lex_all,
                                                             GError **error);

Tries to lex the expression in `stream`.

`stream` : | A CtplInputStream
`lex_all` : | Whether to lex `stream` until EOF or until the end of a valid expression. This is useful for expressions inside other data.
`error` : | Return location for errors, or `NULL` to ignore them.
Returns : | A new CtplTokenExpr or `NULL` on error.

### ctpl_lexer_expr_lex_string ()

    CtplTokenExpr *     ctpl_lexer_expr_lex_string          (const gchar *expr,
                                                             gssize len,
                                                             GError **error);

Tries to lex the expression in `expr`. See `ctpl_lexer_expr_lex()`.

`expr` : | An expression
`len` : | Length of `expr` or -1 to read the whole string
`error` : | Return location for errors, or `NULL` to ignore them
Returns : | A new CtplTokenExpr or `NULL` on error.