Grammar.FirstChars (Ichor v0.7.3)

Copy Markdown View Source

The characters a token's match can begin with, worked out from its IR when a parser is generated.

A generated tokenizer does maximal munch: at every position it tries every token and keeps the longest match. Most of those tries fail on the very first character, so the generated lex_candidates/2 asks each token's start set first (Grammar.Native.TokenizerCompiler) and tries only the tokens that can begin with the next character.

Too much, never too little. Where a start set cannot be told exactly -- any character (.), a @native(...) token, a token that reaches itself again before consuming anything -- the answer is :any, and the token is always tried. A start set that holds a character the token cannot really begin with only costs a try; one that missed a character would change which token wins. Only the characters a non-empty match can begin with count: a zero-width match never wins maximal munch.

Summary

Types

t()

Sorted, merged {lo, hi} codepoint ranges, or :any.

Functions

The start set of token name, whose body and every token it refers to are in tokens.

Types

t()

@type t() :: {:ranges, [{non_neg_integer(), non_neg_integer()}]} | :any

Sorted, merged {lo, hi} codepoint ranges, or :any.

Functions

of(tokens, name)

@spec of(%{required(atom()) => Grammar.IR.expr()}, atom()) :: t()

The start set of token name, whose body and every token it refers to are in tokens.

iex> Grammar.FirstChars.of(%{KW: Grammar.IR.literal("let")}, :KW)
{:ranges, [{?l, ?l}]}