pub struct Node {
pub first: u64,
pub a: u32,
pub b: u32,
pub op: Op,
pub flags: u8,
}Expand description
One node. Twenty four bytes, and everything the matcher needs to decide what to do with it.
The FIRST set and the nullable bit live in here rather than in two arrays beside it. They used
to be parallel tables, on the theory that the filter could read eight bytes of FIRST and skip
the node entirely, and that theory was wrong in the case that matters. A node that survives the
filter is loaded immediately afterwards, and surviving is the common case: the filter is there
to cut the thirty six alternatives of Statement down, and the one that matches still has to be
walked. So the old layout paid three cache lines on every node it did not reject and saved two
on every node it did, and the walk visits far more of the first kind.
Fields§
§first: u64What this node can start with, as a set of token keys. A superset, always.
a: u32§b: u32§op: Op§flags: u8Per op, plus NULLABLE, which every op can carry.
Implementations§
Source§impl Node
impl Node
Sourcepub const RESERVED: u8
pub const RESERVED: u8
On an Identifier node: the keyword check is dropped, so any word matches.
This is the whole of ReservedIdentifierMatcher. It is worth knowing that upstream applies
it to the rule named ReservedKeyword, so a grammar rule that reads
ColLabel <- ReservedKeyword / ... does not test for a reserved word, it accepts any word
at all. Reading the grammar text alone would get that backwards.
Sourcepub const NULLABLE: u8
pub const NULLABLE: u8
This node can match without consuming a token, so its FIRST set says nothing about whether it applies and the filter has to let it through.