# rizin-math-parser

A tree-sitter grammar for the Rizin `RzNum` mathematical expression
language. Used by `librz_util` to evaluate user-supplied numerical
expressions such as those accepted by the `?` and `?v` commands.

## Regenerating the parser

The parser source files (`src/parser.c`, `src/grammar.json`,
`src/node-types.json`, `src/tree_sitter/parser.h`) are produced by
`tree-sitter generate` from `grammar.js`. They are regenerated by the
build system when the `tree-sitter` CLI and `node` are available; the
pre-generated files committed in the repository are used otherwise.

Manual regeneration:

    cd subprojects/rizin-math-parser
    tree-sitter generate

## Running the corpus tests

    cd subprojects/rizin-math-parser
    tree-sitter test

## Supported features

See `test/corpus/main.txt` for the full reference. Highlights:

- numeric literals in decimal, binary (`0b`), ternary (`0t`), octal
  (`0o`) and hexadecimal (`0x`) bases, with an optional fractional
  part and `[eEpP]` exponent (whose digits are required)
- C-style integer suffixes (`u`, `l`, `U`, `L`, `f`, `F`)
- SI / IEC byte units (`KiB`, `KB`, `MiB`, `MB`, `GiB`, `GB`, `TiB`,
  `TB`, `PiB`, `PB`, `EiB`, `EB`)
- arithmetic `+ - * / %` and the `mod` keyword
- exponentiation `**` and the `log` keyword
- bitwise `& | ^ ~`, logical not `!`, shifts `<< >>` and rotations
  `<<< >>>`
- comparisons `< <= > >=` and equality `== !=`
- unary `+` and `-` as operators (not part of the number literal)
- function calls `name(arg1, arg2, ...)`
- variables, including Rizin-style names with dots (e.g.
  `sym.func.1000055d4`) and Unicode identifiers
- Rizin special variables as a dedicated `special_variable` rule
  (`$$`, `$$$`, `$F`, `$S`, `$SS`, ...)
- address with explicit width and endianness:
  `0x1234:le32` / `0xDEADBEEF:be64` / `0x1000:8`
- string-as-bytes literal: `"ABC"`
- `let` and plain assignment to a variable
- pre-increment `++x` and pre-decrement `--x`

## Reserved words

`let` is always reserved (always produces a parse error in variable
position). `mod`, `log`, `le` and `be` are reserved within their
positional contexts (modulo, logarithm, address suffix); bare uses
parse as variables at the grammar level and are rejected by the
evaluator.
