Change vector parsing to allow matrix vectors

pull/1/head
trivernis 4 years ago
parent bd89f6863f
commit 386412f021

@ -68,5 +68,5 @@ pub struct Matrix {
#[derive(Debug, Clone, PartialOrd, PartialEq)]
pub struct Vector {
pub inner: Vec<Expression>,
pub inner: Vec<Vec<Expression>>,
}

@ -281,16 +281,49 @@ mod tests {
Expression {
children: vec![Element::Group(Group::Vector(Vector {
inner: vec![
Expression {
vec![Expression {
children: vec![Element::Literal(Literal::Number(Number {
number: "1".to_string()
}))]
},
Expression {
}],
vec![Expression {
children: vec![Element::Literal(Literal::Number(Number {
number: "2".to_string()
}))]
}
}]
]
}))]
}
);
assert_eq!(
parse("((1, 3), (2, 5))".to_string()),
Expression {
children: vec![Element::Group(Group::Vector(Vector {
inner: vec![
vec![
Expression {
children: vec![Element::Literal(Literal::Number(Number {
number: "1".to_string()
}))]
},
Expression {
children: vec![Element::Literal(Literal::Number(Number {
number: "3".to_string()
}))]
}
],
vec![
Expression {
children: vec![Element::Literal(Literal::Number(Number {
number: "2".to_string()
}))]
},
Expression {
children: vec![Element::Literal(Literal::Number(Number {
number: "5".to_string()
}))]
}
]
]
}))]
}

@ -283,29 +283,9 @@ impl TreeParser {
}
}
// Remapping the expression into a matrix
let expression_matrix = expressions
.iter()
.map(|e| {
let children = e.children.clone();
let mut expressions = Vec::new();
for elements in children.split(|e| e == &Element::Group(Group::MSep)) {
expressions.push(Expression {
children: elements.to_vec(),
})
}
expressions
})
.collect::<Vec<Vec<Expression>>>();
let expression_matrix = self.transform_vec_to_matrix(expressions);
// a matrix with no elements is invalid
if expression_matrix.is_empty() {
self.index = start_index;
return None;
}
/// a matrix with rows of different lengths is invalid
let first_length = expression_matrix.first().unwrap().len();
if !expression_matrix.iter().all(|e| e.len() == first_length) {
if !self.validate_matrix(&expression_matrix) {
self.index = start_index;
None
} else {
@ -341,11 +321,15 @@ impl TreeParser {
break;
}
}
if expressions.is_empty() {
let expression_matrix = self.transform_vec_to_matrix(expressions);
if !self.validate_matrix(&expression_matrix) {
self.index = start_index;
None
} else {
Some(Group::Vector(Vector { inner: expressions }))
Some(Group::Vector(Vector {
inner: expression_matrix,
}))
}
} else {
None
@ -442,4 +426,32 @@ impl TreeParser {
None
}
}
/// Remaps an expresion vector into a matrix of expressions by splitting on each MSep token
fn transform_vec_to_matrix(&self, expressions: Vec<Expression>) -> Vec<Vec<Expression>> {
expressions
.iter()
.map(|e| {
let children = e.children.clone();
let mut expressions = Vec::new();
for elements in children.split(|e| e == &Element::Group(Group::MSep)) {
expressions.push(Expression {
children: elements.to_vec(),
})
}
expressions
})
.collect::<Vec<Vec<Expression>>>()
}
/// Validates a matrix of expressions if every row has the same length
fn validate_matrix(&self, matrix: &Vec<Vec<Expression>>) -> bool {
if matrix.is_empty() {
false
} else {
let first_length = matrix.first().unwrap().len();
matrix.iter().all(|e| e.len() == first_length)
}
}
}

@ -1,11 +1,14 @@
pub const G_RPAREN: &'static [&str] = &["("];
pub const G_LPAREN: &'static [&str] = &[")"];
pub const G_RBRAC: &'static [&str] = &["["];
pub const G_LBRAC: &'static [&str] = &["]"];
pub const G_RBRACKET: &'static [&str] = &["["];
pub const G_LBRACKET: &'static [&str] = &["]"];
pub const G_RCURL: &'static [&str] = &["{"];
pub const G_LCURL: &'static [&str] = &["}"];
pub const G_RBRACE: &'static [&str] = &["{"];
pub const G_LBRACE: &'static [&str] = &["}"];
pub const G_RBRACE_HIDDEN: &'static [&str] = &["{:"];
pub const G_LBRACE_HIDDEN: &'static [&str] = &[":}"];
pub const G_LANGLE: &'static [&str] = &["(:", "<<", "langle"];
pub const G_RANGLE: &'static [&str] = &[":)", ">>", "rangle"];

@ -164,10 +164,10 @@ pub fn get_grouping_mappings() -> Vec<HashMap<TokenPattern, Grouping>> {
hashmap! {
G_RPAREN => Grouping::RParen,
G_LPAREN => Grouping::LParen,
G_RBRAC => Grouping::RBracket,
G_LBRAC => Grouping::LBracket,
G_RCURL => Grouping::RBrace,
G_LCURL => Grouping::LBrace,
G_RBRACKET => Grouping::RBracket,
G_LBRACKET => Grouping::LBracket,
G_RBRACE => Grouping::RBrace,
G_LBRACE => Grouping::LBrace,
G_ABS => Grouping::Abs,
G_FLOOR => Grouping::Floor,
G_CEIL => Grouping::Ceil,

Loading…
Cancel
Save