Skip to main content

Module grammar

Module grammar 

Source
Expand description

Conservative R-grammar validation for the r! proc-macro.

This module implements a reject-only-known-bad strategy: walk the proc_macro2::TokenStream and emit a syn::Error for constructs that R’s parser is guaranteed to reject. Anything that cannot be confidently classified as an error is accepted silently.

§Non-goals

A complete R grammar over Rust tokens is not achievable:

  • Single-quoted strings ('hello') and backtick-quoted names (`foo`) already die at the Rust lexer — nothing to validate.
  • %op% tokenises as %, ident, % — looks like two leading % ops; we accept it rather than risk false positives.
  • R formulas (~), ?, unary operators and other niche constructs may look syntactically ambiguous — we accept those too.

§Accepted forms (must never be rejected)

  • ;-statement sequences (a <- 1L; b <- 2L; a + b)
  • <- assignment (tokenises as < + - joint punct)
  • <<- assignment (tokenises as < + < + -)
  • -> assignment (tokenises as - + > joint punct)
  • %in%, %*%, and all other %op% operators
  • Empty (missing) arguments anywhere: x[,1], f(, x), matrix(, 2, 2) — R’s sublist grammar allows empty slots in every call form, ( and [ alike (they become the missing-arg sentinel at evaluation)
  • 2 ** 3 — R’s parser accepts ** as an undocumented synonym for ^
  • ~ formulas
  • \(x) x+1 lambda syntax (R 4.1+; \ alone doesn’t survive Rust lexing unless inside a string literal, so no R-side validation needed)

Functions§

check_consecutive_binary_ops 🔒
Returns an error if two consecutive non-unary binary operators appear with nothing between them (x * * y, x / / y).
check_trailing_binary_op 🔒
Returns an error if the sequence ends with a binary operator.
flatten_top_level 🔒
is_comma 🔒
is_pure_binary_op 🔒
Returns true for operators that are clearly binary and NOT unary-capable in R. +, -, !, ~, ? are unary-capable so we return false.
is_semicolon 🔒
preceding_binary_op_span 🔒
Returns the span of a binary operator token at pos if it is a binary op. Used to anchor the “empty paren after binary op” diagnostic.
punct_char_at 🔒
split_by_comma 🔒
split_by_semicolon 🔒
validate 🔒
Returns Ok(()) if the token stream passes the conservative validator, or an Err spanned to the first problematic token pair/group.
validate_control_flow_keyword 🔒
Validates that control-flow keywords (if, while, for, function, repeat) are followed by the correct next token.
validate_group 🔒
validate_sequence 🔒