Formula Parsing Mechanism
Relevant source files
The following files were used as context for generating this wiki page:
The Formula Parsing Mechanism in nth-check is responsible for transforming CSS nth-child type expressions into a structured numerical format. This process follows the W3C Selectors Level 3 specification, enabling the library to interpret strings like 2n+3, even, or odd into an internal representation consisting of a step size (a) and an offset (b).
Sources: src/parse.ts:1-5, README.md:5-10
This mechanism serves as the first stage in a pipeline that eventually produces optimized matching functions or index generators. By decoupling parsing from execution, the library ensures that complex string manipulation occurs only once, while the resulting numerical tuple [a, b] can be reused for high-performance operations.
Sources: src/index.ts:28-30, src/compile.ts:18-20
Parsing Architecture
The parsing logic is primarily contained within the parse function. It utilizes a stateful scanner approach to traverse the input string, extracting signs, integers, and the characteristic n token.
Input Normalization
Before specific tokens are identified, the formula undergoes basic normalization:
- Trimming leading and trailing whitespace.
- Conversion to lowercase to ensure case-insensitivity.
- Direct mapping of special keywords
even(mapped to[2, 0]) andodd(mapped to[2, 1]).
Sources: src/parse.ts:18-29
The Parsing Flow
The parser follows a specific grammar to extract the values for a and b. The expected pattern generally follows [['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]?.
Sources: src/parse.ts:31-62
Internal Parser Components
The parse function uses several internal helper functions to manage the cursor (index) and interpret character data.
Character Handling Helpers
readSign(): Checks the current character for+or-. Returns-1for negative signs and1otherwise, incrementing the cursor if a sign is found.readNumber(): Iteratively consumes characters between ASCII0(48) and9(57). It returns the parsed integer ornullif no digits were present at the current position.skipWhitespace(): Consumes characters defined as whitespace in the CSS spec: space, tab, carriage return, line feed, and form feed (ASCII 32, 9, 13, 10, 12).
Sources: src/parse.ts:4-6, src/parse.ts:68-107
Data Structure: The Nth-Tuple
The parser returns a fixed-length array (tuple) of two numbers: [a, b].
a(Step): The multiplier for the sequence (e.g., in3n+1,ais 3).b(Offset): The starting offset (e.g., in3n+1,bis 1).
Sources: src/parse.ts:17, README.md:46-50
Validation and Error Handling
The parser is designed to be strict. It throws an Error if the formula contains unexpected characters or if a numeric component is expected but missing.
| Valid Input | Parsed Result [a, b] | Description |
|---|---|---|
even | [2, 0] | Standard keyword |
2n+3 | [2, 3] | Standard formula |
n-1 | [1, -1] | Implicit a=1 |
-n | [-1, 0] | Negative implicit a |
5 | [0, 5] | Pure offset (no n) |
Sources: src/fixtures/rules.ts:1-35
Error Cases
A Parse Error is triggered if:
- The
numberread for the offset isnull(when expected). - The
indexhas not reached the end of theformulastring after processing valid tokens, indicating trailing invalid content. - Invalid characters are encountered (e.g., "asdf", "2n+-0").
Sources: src/parse.ts:58-61, src/fixtures/rules.ts:37-48, src/parse.spec.ts:7-11
Integration with Compilation
The output of the parsing mechanism is directly consumed by compile and generate. While the parser treats b as a 1-based index (matching CSS logic), the compilation layer adjusts this value to a 0-based index for standard JavaScript array/index compatibility.
Sources: src/index.ts:28-30, src/compile.ts:33-35
Summary
The Formula Parsing Mechanism provides the foundation for the nth-check utility by robustly converting CSS-compliant strings into mathematical components. By strictly following the W3C grammar and providing clear internal helpers for sign and number detection, it ensures that even complex expressions with varied spacing and signing are correctly interpreted before reaching the execution phase.
Sources: src/parse.ts, README.md