/// Tree-sitter recovery sometimes reduces `int_domain` to bare `int` and then wraps the following
fn classify_unexpected_token_error(node: Node, source_code: &str) -> RecoverableParseError {
// NOTE: tree-sitter byte offsets can land inside UTF-8 codepoints; decoding lossily avoids panics.
// if the error node is before or at the first non-whitespace character, it's a malformed line error
// if the first non-whitespace character is after the error node, it could be a constraint continuation
if node.start_position().column <= first_non_witespace || error_node_out_of_range(node, source)
/// Checks if a line is a continuation of a constraint (i.e., it ends with a comma or has "such that" at the start).
/// Removes underscores, replaces certain keywords with more natural language, and adds appropriate articles.