mtparser/parser

Stages 2+3: classify each line, then parse command arguments.

Reading model (terminology per the official docs):

parse_statement is the single hub:

  1. blank → no statement (blank lines are skipped in the main loop)
  2. #… → Comment
  3. -- prefix → parse the dash command (parse_dash_command_statement) in endline-delimiter mode; a -- line IS a command, so unknown names are real errors here
  4. anything else → route by the first word (parse_command_statement); an unknown bare statement is just a query (parse_sql_statement). Errors from known commands are real errors in both forms.

Types

Parser state, threaded explicitly through the loop.

next_endline_as_delimiter reflects the -- prefix: while a -- command’s routing unit is being read, the endline (a newline, or the end of file for a final line without one) acts as its delimiter (“A -- command is terminated by a newline, regardless of how many delimiters it contains”). The flag is one-shot: set by parse_dash_command_statement, consumed by the one-line read in read_unit — reaching the endline consumes it, whoever reads there.

pub type ParserState {
  ParserState(delimiter: String, next_endline_as_delimiter: Bool)
}

Constructors

  • ParserState(delimiter: String, next_endline_as_delimiter: Bool)

Values

pub fn parse_expr(
  input: String,
  base_offset: Int,
) -> Result(ast.Expr, Nil)

Parse a condition expression. input is the argument text (e.g. "(1)"), base_offset the byte offset of its first byte in the source.

pub fn parse_interpolated_text(
  text: String,
) -> List(ast.TextPart)

Parse with base byte offset 0.

pub fn parse_interpolated_text_with_offset(
  text: String,
  base_offset: Int,
) -> List(ast.TextPart)

Parse, adding base_offset to every part’s span offset.

Scanning rules:

  • \$ → literal $
  • $ followed by a digit → register variable $0-$9 (mysqltest.cc var_get routes digits to var_reg; a single-character name)
  • $ followed by [a-zA-Z_] then [a-zA-Z0-9_]* → variable reference (mysqltest.cc my_isvar = alnum | ‘_’ — a - ENDS the name, so $i-1 is $i followed by the literal -1)
  • $ followed by anything else (or end of text) → literal $
  • everything else accumulates into literals
pub fn parse_statements(
  all: List(ast.Line),
) -> Result(
  #(List(ast.Statement), ParserState),
  error.ParserError,
)

Parse all lines into statements.

✨ Search Document