Unity.Parser (Unity v0.6.0)

Copy Markdown View Source

NimbleParsec-based expression parser for unit expressions.

Parses expressions like "3 meters to feet", "60 mph + 10 km/h", or "sqrt(9 m^2)" into an AST that the interpreter can evaluate.

The grammar supports:

  • Numeric literals (integers, floats, rationals with |).

  • Unit names (resolved via Unity.Aliases).

  • Arithmetic operators: +, -, *, /, ^.

  • Juxtaposition multiplication (space between units): kg m = kg * m.

  • per as a synonym for /.

  • Conversion operators: to, in, ->.

  • Parenthesized sub-expressions.

  • Function calls: sqrt(expr), abs(expr), etc.

  • Concatenated single-digit exponents: cm3 = cm^3.

  • Rational numbers: 1|3 = 1/3.

Summary

Functions

Parses the given binary as expression.

Parses a unit expression string into an AST.

Parses a unit expression string into an AST, raising on failure.

Parses the given binary as parse_expression.

Functions

expression(binary, opts \\ [])

@spec expression(binary(), keyword()) ::
  {:ok, [term()], rest, context, line, byte_offset}
  | {:error, reason, rest, context, line, byte_offset}
when line: {pos_integer(), byte_offset},
     byte_offset: non_neg_integer(),
     rest: binary(),
     reason: String.t(),
     context: map()

Parses the given binary as expression.

Returns {:ok, [token], rest, context, position, byte_offset} or {:error, reason, rest, context, line, byte_offset} where position describes the location of the expression (start position) as {line, offset_to_start_of_line}.

To column where the error occurred can be inferred from byte_offset - offset_to_start_of_line.

Options

  • :byte_offset - the byte offset for the whole binary, defaults to 0
  • :line - the line and the byte offset into that line, defaults to {1, byte_offset}
  • :context - the initial context value. It will be converted to a map

parse(input)

@spec parse(String.t()) :: {:ok, term()} | {:error, String.t()}

Parses a unit expression string into an AST.

Arguments

  • input - the expression string to parse.

Returns

  • {:ok, ast} on success.

  • {:error, message} on parse failure.

Examples

iex> Unity.Parser.parse("3 meters")
{:ok, {:quantity, 3, {:unit_name, "meters"}}}

iex> Unity.Parser.parse("3 meters to feet")
{:ok, {:convert, {:quantity, 3, {:unit_name, "meters"}}, {:unit_name, "feet"}}}

parse!(input)

@spec parse!(String.t()) :: term()

Parses a unit expression string into an AST, raising on failure.

Arguments

  • input - the expression string to parse.

Returns

The parsed AST.

Examples

iex> Unity.Parser.parse!("3 meters")
{:quantity, 3, {:unit_name, "meters"}}

parse_expression(binary, opts \\ [])

@spec parse_expression(binary(), keyword()) ::
  {:ok, [term()], rest, context, line, byte_offset}
  | {:error, reason, rest, context, line, byte_offset}
when line: {pos_integer(), byte_offset},
     byte_offset: non_neg_integer(),
     rest: binary(),
     reason: String.t(),
     context: map()

Parses the given binary as parse_expression.

Returns {:ok, [token], rest, context, position, byte_offset} or {:error, reason, rest, context, line, byte_offset} where position describes the location of the parse_expression (start position) as {line, offset_to_start_of_line}.

To column where the error occurred can be inferred from byte_offset - offset_to_start_of_line.

Options

  • :byte_offset - the byte offset for the whole binary, defaults to 0
  • :line - the line and the byte offset into that line, defaults to {1, byte_offset}
  • :context - the initial context value. It will be converted to a map