A2UIAgent.Express.Syntax (A2UIAgent v0.1.1)

Copy Markdown View Source

Reads Express source into statements, following the grammar specification/inference_formats/express/Express.g4.

iex> A2UIAgent.Express.Syntax.parse(~s|root = Text("Hi", variant="h1")|)
{:ok, [{:assign, "root", {:call, "Text", ["Hi"], [{"variant", "h1"}]}}], []}

A statement is {:assign, target, value}, where the target is a variable name or a data path ("$/a/b"), or {:expr, value}. A value is a JSON literal (a string, number, boolean or nil), a list, or one of:

  • {:map, pairs} — a map literal, keys in source order;
  • {:path, path} — a data binding, $/a/b as "/a/b";
  • {:check, name, args} — a check rule such as ?regex("^a");
  • {:call, name, args, kwargs} — a call, keyword arguments as pairs in source order;
  • {:var, name} — a variable reference;
  • :skipped — the _ placeholder.

A keyword argument or map key given twice keeps its first place and its last value.

parse/1 returns the statements before the first syntax error with the errors it found, each {line, column, message, kind} where kind is :lexer for a character no token starts with and :parser otherwise. Lines count from 1 and columns from 0.

Summary

Types

An Express statement.

A syntax error: line, column, message and the stage that found it.

An Express value.

Functions

Whether name can be written as a bare Express identifier: it matches [a-zA-Z_][a-zA-Z0-9_]* and is not true, false, null or _.

Parses source. Returns {:ok, statements, errors}: when errors is not empty, statements holds the statements that start on a line before the first error.

Resolves the escapes a standard or triple-quoted string supports: \n, \r, \t, \\ and \". Any other backslash stays as written.

Types

statement()

(since 0.1.0)
@type statement() :: {:assign, String.t(), value()} | {:expr, value()}

An Express statement.

syntax_error()

(since 0.1.0)
@type syntax_error() ::
  {pos_integer(), non_neg_integer(), String.t(), :lexer | :parser}

A syntax error: line, column, message and the stage that found it.

value()

(since 0.1.0)
@type value() ::
  String.t()
  | number()
  | boolean()
  | nil
  | [value()]
  | {:map, [{String.t(), value()}]}
  | {:path, String.t()}
  | {:check, String.t(), [value()]}
  | {:call, String.t(), [value()], [{String.t(), value()}]}
  | {:var, String.t()}
  | :skipped

An Express value.

Functions

identifier?(name)

(since 0.1.0)
@spec identifier?(term()) :: boolean()

Whether name can be written as a bare Express identifier: it matches [a-zA-Z_][a-zA-Z0-9_]* and is not true, false, null or _.

iex> A2UIAgent.Express.Syntax.identifier?("content_grid")
true
iex> A2UIAgent.Express.Syntax.identifier?("content-grid")
false

parse(source)

(since 0.1.0)
@spec parse(String.t()) :: {:ok, [statement()], [syntax_error()]}

Parses source. Returns {:ok, statements, errors}: when errors is not empty, statements holds the statements that start on a line before the first error.

unescape(text)

(since 0.1.0)
@spec unescape(String.t()) :: String.t()

Resolves the escapes a standard or triple-quoted string supports: \n, \r, \t, \\ and \". Any other backslash stays as written.

iex> A2UIAgent.Express.Syntax.unescape(~S(a\nb\d))
"a\nb\\d"