# Scanner Wrapper

`dflscanner.h` declares `Scanner`, the concrete `yyFlexLexer` subclass Flex generates `yylex()`'s body into (see [Lexer](dfllexer.md) for the actual token-recognition rules). This file is the class shell and the mutable scanning state that persists across calls to `yylex()`, not the lexical rules themselves - there is no separate `dflscanner.cpp`; the method body lives in the generated `dfllexer.cpp`.

## Construction

Takes the input stream, a `ParserTables&`, an `InputType` (the [lexer](dfllexer.md)'s three entry modes), and the `FileStackFileIndex` of the source being scanned, plus a `Status&` (defaulting to `Status::ignore`, see [Status](status.md)) that `error()` reports through.

## The included-file stack

`pushStream()` opens a new `std::ifstream` for an included file and remembers the `Location` active at the point of inclusion; `popStream()` reverses this when the included file (or, per [Lexer](dfllexer.md), a library section) ends, handing back the saved `Location` so the parent file's position resumes correctly. `cleanup()` (called from the destructor) clears both stacks at once - relying on each entry being a `std::unique_ptr<std::ifstream>`, whose own destructor closes the file, so partially-scanned nested includes are cleaned up correctly even if scanning stops mid-file rather than reaching a normal end of input.

## `error()`

The single place lexer actions report a problem: sets `Status::Syntax` on the scanner's `Status&` and attaches the given location (`l.loc()`, converting Bison's `Location` to the simulator's own [`Loc`](sourceloc.md)) via `Status::extend()`. Every `token::YYerror` return in [`dfllexer.l`](dfllexer.md) is preceded by a call here.

## Scanning state

The private members are exactly what [`dfllexer.l`](dfllexer.md)'s rule actions read and mutate as they scan: `sbuf` (the string literal being accumulated), `marker` (the closing delimiter expected for a long-quoted string), `stringStart` (the `Position` where the current string literal began - restored as the token's location once the string closes, so a multi-line string's token location points at its opening quote rather than wherever the closing quote happened to land), `section` (the library section name currently being searched for), `inParen`/`inBracket`/`inBrace` (nesting depth of `(...)`/`[...]`/`{...}`, used to decide whether a `NEWLINE` ends a statement or is swallowed), `inControl` (whether `analysis`/`sweep`/`save` are currently keywords or ordinary identifiers), and `atBeginning` (whether the synthetic `INNETLIST`/`INEXPR`/`INPARAMS` entry token has been emitted yet).

`skipLeadingWhitespace()` is declared here but has no callers in `dfllexer.l` - dead code, not currently exercised.
