Expand description
A three-address intermediate representation of a parsed pattern.
lower turns a Pattern into a Program: a set
of comparison blocks, one per [...] observation, plus a main block that
combines their results. Each comparison block is exactly the unit the matcher
enumerates binding sets over.
The IR is in SSA form — an instruction’s InstrId names the value it
produces, and there is no separate destination field.
§Example
use stix_pattern::{parse, ir};
let pattern = parse("[file:size > 1024]").unwrap();
let program = ir::lower(&pattern);
program.validate().expect("lowered programs are always valid");
assert_eq!(ir::render(&program), "[file:size > 1024]");§Deserialization
Deserializing a Program does not check its invariants. Call
Program::validate before using one that came from outside this process:
it is what rejects the shapes that would make render produce text that
does not parse or grow exponentially. Nesting depth is not limited:
render, Program::validate and Program::span_of are iterative, so
a deeply nested program cannot make any of them overflow the stack.
Validation also bounds rendered size. Each value may have at most one
consumer (IrError::MultipleUses) and each comparison block at most one
Observe (IrError::BlockObservedTwice), so every instruction is rendered
at most once and output is linear in the size of the program.
Structs§
- Block
- A straight-line sequence of instructions ending in a terminator.
- BlockId
- Identifies one block within a
Program. - InstrId
- Identifies one instruction, and therefore the value it produces.
- Instruction
- One instruction: an id, an operation, and optionally where it came from.
- Program
- A lowered pattern: comparison blocks plus the observation-tier block.
Enums§
- Block
Kind - Which tier a block belongs to.
- IrError
- A way a
Programcan be malformed. - Op
- One three-address operation.
- Operand
- Right-hand side of a
Op::Compare.
Constants§
- SCHEMA_
VERSION - Version of the serialized IR schema. Checked by
Program::validate.