Function parse_conditional

Source
pub fn parse_conditional(input: &str) -> IResult<&str, Conditional>
Expand description

Parse a conditional expression.

Parses ternary conditional expressions (condition ? true_expr : false_expr) with right associativity, or falls back to parsing logical OR expressions.

§Arguments

  • input - The input string slice to parse

§Returns

A IResult containing the remaining input and parsed Conditional expression.

§Grammar

conditional := or (S? '?' S? expression S? ':' S? conditional)?

Where S represents optional whitespace. The optional part makes the conditional operator right associative.

§Parsing Algorithm

  1. First parse a logical OR expression (parse_or)
  2. If followed by ?, parse the ternary operator components
  3. Otherwise, flatten the logical OR expression into a Conditional::Primary

§Examples

§Basic Conditional

use aimx::expressions::{parse_conditional, Conditional};

let (remaining, conditional) = parse_conditional("true ? 1 : 0").unwrap();
assert_eq!(remaining, "");
assert!(matches!(conditional, Conditional::Ternary(_, _, _)));

§Right Associativity

use aimx::expressions::{parse_conditional, Conditional};

// Parses as: true ? 1 : (false ? 2 : 3)
let (remaining, conditional) = parse_conditional("true ? 1 : false ? 2 : 3").unwrap();
assert_eq!(remaining, "");
assert!(matches!(conditional, Conditional::Ternary(_, _, _)));

§Complex Conditions

use aimx::expressions::{parse_conditional, Conditional};

let (remaining, conditional) = parse_conditional("1 < 2 & 3 > 4 ? 5 : 6").unwrap();
assert_eq!(remaining, "");
assert!(matches!(conditional, Conditional::Ternary(_, _, _)));

§Fallback to Logical OR

use aimx::expressions::{parse_conditional, Conditional};

// When no ternary operator is present, parses as logical OR
let (remaining, conditional) = parse_conditional("true | false").unwrap();
assert_eq!(remaining, "");
// This gets flattened to a Primary variant containing a LogicalOr
assert!(matches!(conditional, Conditional::Primary(_)));

§Whitespace Handling

use aimx::expressions::{parse_conditional, Conditional};

// Handles various whitespace patterns
let (remaining, conditional) = parse_conditional("true   ?   1   :   0").unwrap();
assert_eq!(remaining, "");
assert!(matches!(conditional, Conditional::Ternary(_, _, _)));

§Parenthesized Conditions

use aimx::expressions::{parse_conditional, Conditional};

let (remaining, conditional) = parse_conditional("(true | false) ? 1 : 0").unwrap();
assert_eq!(remaining, "");
assert!(matches!(conditional, Conditional::Ternary(_, _, _)));

§Error Cases

The function returns Err for:

  • Invalid syntax (missing ? or :)
  • Malformed expressions
  • Unbalanced parentheses
use aimx::expressions::{parse_conditional, Conditional};

// Missing colon - parses as logical OR instead
let (remaining, conditional) = parse_conditional("true ? 1").unwrap();
assert_eq!(remaining, "? 1");
// This gets flattened to a Primary variant containing a LogicalOr
assert!(matches!(conditional, Conditional::Primary(_) ));
 
// Missing question mark - parses as logical OR instead
let (remaining, conditional) = parse_conditional("true 1 : 0").unwrap();
assert_eq!(remaining, "1 : 0");
// This gets flattened to a Primary variant containing a LogicalOr
assert!(matches!(conditional, Conditional::Primary(_) ));