blob: 19a84bb66b607bb56c83635bca12a563df0506ed [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2021 CentraleSupelec, CEA-LIST
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Erwan Mahé (CentraleSupelec) - initial API and implementation
*******************************************************************************/
use std::collections::HashSet;
use crate::core::syntax::position::*;
use crate::core::syntax::interaction::*;
pub fn make_frontier(interaction : &Interaction) -> Vec<Position> {
match interaction {
&Interaction::Empty => {
return Vec::new();
},
&Interaction::Action(_) => {
return vec![Position::Epsilon];
},
&Interaction::Strict(ref i1, ref i2) => {
let mut front = push_frontier(&PositionKind::Left, make_frontier(i1));
if i1.express_empty() {
front.append( &mut push_frontier(&PositionKind::Right, make_frontier(i2)) )
}
return front;
},
&Interaction::Seq(ref i1, ref i2) => {
let mut front = push_frontier(&PositionKind::Left, make_frontier(i1));
for pos2 in push_frontier(&PositionKind::Right, make_frontier(i2)) {
let act = interaction.get_sub_interaction(&pos2 ).as_leaf();
if i1.avoids(act.lf_act.lf_id) {
front.push(pos2);
}
}
return front;
},
&Interaction::Alt(ref i1, ref i2) => {
let mut front = push_frontier(&PositionKind::Left, make_frontier(i1));
front.append( &mut push_frontier(&PositionKind::Right, make_frontier(i2)) );
return front;
},
&Interaction::Par(ref i1, ref i2) => {
let mut front = push_frontier(&PositionKind::Left, make_frontier(i1));
front.append( &mut push_frontier(&PositionKind::Right, make_frontier(i2)) );
return front;
},
&Interaction::Loop(_, ref i1) => {
return push_frontier(&PositionKind::Left, make_frontier(i1));
},
&Interaction::Scope(_, ref i1) => {
return push_frontier(&PositionKind::Left, make_frontier(i1));
}
}
}
enum PositionKind {
Left,
Right
}
fn push_frontier(pkind : &PositionKind, frontier : Vec<Position>) -> Vec<Position> {
let mut new_frontier : Vec<Position> = Vec::new();
// ***
for my_pos in frontier {
let new_pos : Position;
match pkind {
PositionKind::Left => {
new_pos = Position::Left( Box::new(my_pos ) );
},
PositionKind::Right => {
new_pos = Position::Right( Box::new(my_pos ) );
}
}
new_frontier.push( new_pos );
}
// ***
return new_frontier;
}