---
title: "math-calc-parser-lex-normalization — Mova code model"
description: "Mova code model of math/src/calc.rs: components with their labels, obernants and the model text."
url: "https://groupants.elamur.ai/free/en/mova/math/src/calc.rs.groupant/parser.groupant/lex-normalization.groupant/"
---
Elamur: [Mova](https://md.mova.elamur.ai/free/en/) · [Dictionary](https://md.dictionary.elamur.ai/free/en/) · [Research](https://md.research.elamur.ai/free/en/) · **Groupants**

This page as HTML: <https://groupants.elamur.ai/free/en/mova/math/src/calc.rs.groupant/parser.groupant/lex-normalization.groupant/>

# math-calc-parser-lex-normalization

The groupant beside math/src/calc.rs in the Mova repository: what the code computes, what it never does, how to go back from its outputs, its invariants, cost and checks.

## Facts

- **kind:** groupant_fragment
- **status:** partial source bound model
- **source:** [`math/src/calc.rs`](https://github.com/ElamurAI/mova-free/blob/main/math/src/calc.rs)
- **source SHA-256:** `81be7f264f451792…`
- **covers:** State (character vector, cursor, tokens) advances left to right. Numeric runs admit digits and dots, then an optional well-formed exponent suffix. Alphabetic/underscore starts identifiers; bracket/equality/multiplication/minus specials precede the ordered symbol table. Unknown characters return Err with no token vector. Recognized aliases collapse to canonical Sym tokens. (bytes 6237–9052)
- **part of:** [math-calc-parser](https://md.groupants.elamur.ai/free/en/mova/math/src/calc.rs.groupant/parser.groupant/)
- **repository folder:** [`math/src/calc.rs.groupant/parser.groupant/lex-normalization.groupant`](https://github.com/ElamurAI/mova-free/tree/main/math/src/calc.rs.groupant/parser.groupant/lex-normalization.groupant)
- **repository commit:** `48f2e6f74146`

> **Implementation material.** A Mova code model describes this code at one source revision: partial models, finite checks and their stated scope. It is not a reviewed general exposition, and its labels are shown as written, never raised.

## Components

| component | label | where |
|---|---|---|
| **approximant** | partial | [Forward](#forward) |
| **ast** | partial | `../../syntax.json` |
| **cost** | partial | [Cost](#cost) |
| **descriptant** | present | [Epoch](#epoch) |
| **invariant** | partial | [Invariant](#invariant) |
| **tests** | bounded actual helper checks | [Tests](#tests) |

## Obernants

The typed relations around the forward model: the behaviour complement (what the code never does), the reverse reconstruction (every input compatible with an output) and specialised views.

| id | type | label | where |
|---|---|---|---|
| `behavior_complement` | behavior_complement | partial source derived model | [behavior_complement](#behavior-complement) |
| `reverse_reconstruction` | reverse_reconstruction | partial source derived model | [reverse_reconstruction](#reverse-reconstruction) |
| `exponent_admission` | exponent_admission | partial source derived model | [exponent_admission](#exponent-admission) |
| `unicode_coordinates` | unicode_coordinates | partial source derived model | [unicode_coordinates](#unicode-coordinates) |
| `numeric_validation_split` | numeric_validation_split | partial source derived model | [numeric_validation_split](#numeric-validation-split) |
| `symbol_precedence` | symbol_precedence | partial source derived model | [symbol_precedence](#symbol-precedence) |

## Model text


### Scope

Source-derived bounded relation for the manifest byte interval. All relations observe one invocation and its stated state effects. Valid caller structures and finite values where specified are premises. No universal proof, percentage-error surrogate or production replacement is claimed.

### Forward

State (character vector, cursor, tokens) advances left to right. Numeric runs admit digits and dots, then an optional well-formed exponent suffix. Alphabetic/underscore starts identifiers; bracket/equality/multiplication/minus specials precede the ordered symbol table. Unknown characters return Err with no token vector. Recognized aliases collapse to canonical Sym tokens.

### Invariant

On successful lexing the cursor reaches the character count; identifiers preserve spelling and number strings preserve their scanned characters. Tokenization does not itself validate numeric spelling.

### Cost

O(C) scans and O(C) character/token storage with a fixed 22-entry symbol table; symbol candidate allocations are bounded constants per nonword character.

### behavior_complement

For successful normalized multiplication tokens, transitions emitting × or · rather than Sym(*) are excluded. Unknown nonwhitespace characters exclude Ok; malformed 1..2 is not excluded by lex and fails later in primary.

### reverse_reconstruction

A Sym(*) token admits *, × and · source spellings. A Sym(^) admits ^ and **. Whitespace insertion and = versus == are distinct antecedents; original UTF-8 offsets cannot be reconstructed from tokens.

### exponent_admission

Holding preceding digit run fixed, e/E joins Num only when followed by a digit or sign plus digit. 1e becomes Num(1),Id(e); 1e-2 is one Num. Oracle: inspect lex outputs on these bounded strings.

### unicode_coordinates

Cursor counts Rust chars, not UTF-8 bytes. Equivalent × and * advance one character but differing byte counts. Source anchors use bytes; lexical cost uses characters.

### numeric_validation_split

Num(1..2) is reachable from lex; parse_q in primary decides rejection. A lexical success therefore cannot certify a rational literal. Oracle: lex succeeds and parse fails.

### symbol_precedence

The ordered table tests ** before *, != before !, <= before <. Fixed suffix overlap determines token count; changing this order changes the E accepted by parse.

### Tests

Actual helper fixture: `calc::wave34::syntax_zero_and_binding_boundaries`. See file-root wave34-evidence.md for named profile/control receipts. Complement relations above are exclusions, not merely test lists; inverse relations retain compatible antecedents. Unexecuted paths remain source-derived.

### Epoch

2026-10-31 wave34: new descendant refining the existing parent; prior parent descriptions and evidence retained as historical snapshots. Production code is unchanged; inline synthetic tests add bounded observations.
