blob: 4861f12536e93b3348b82143dab51490c5266a4c [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::fs;
use std::collections::{HashSet,HashMap};
use std::collections::btree_map::BTreeMap;
use std::path::Path;
use pest::iterators::Pair;
use crate::pest::Parser;
use crate::core::syntax::interaction::Interaction;
use crate::core::syntax::action::*;
use crate::core::syntax::data::generic::TD_Generic;
use crate::core::syntax::data::var_ref::VariableReference;
use crate::core::context::general::GeneralContext;
use crate::core::context::execution::ExecutionContext;
use crate::core::syntax::data::td_type::TD_DataType;
use crate::core::syntax::data::builtin::float::TD_Float;
use crate::core::syntax::data::builtin::integer::TD_Integer;
use crate::core::syntax::data::builtin::string::TD_String;
use crate::core::syntax::data::builtin::bool::TD_Bool;
use crate::from_text::error::HibouParsingError;
use crate::process::log::ProcessLogger;
use crate::from_text::parser::*;
use crate::from_text::data::td_type::parse_type;
use crate::from_text::interaction::parse_interaction;
use crate::from_text::data::generic::parse_data;
use crate::from_text::hibou_options::{HibouOptions,parse_hibou_options};
use crate::process::hibou_process::HibouPreFilter;
use crate::from_text::hsf_file::ProcessKind;
pub struct InterpretationItemPlan {
pub lf_id : usize,
pub vr_id : usize,
pub assignment : ValueOrNewFresh
}
pub fn parse_setup(setup_pair : Pair<Rule>,
gen_ctx : &mut GeneralContext,
file_name : &str,
process_kind : &ProcessKind) -> Result<(Vec<InterpretationItemPlan>,HibouOptions),HibouParsingError> {
// ***
let mut got_section_explore_options : bool = false;
let mut got_section_analyze_options : bool = false;
let mut got_section_messages : bool = false;
let mut got_section_variables : bool = false;
let mut got_section_lifelines : bool = false;
let mut got_section_init : bool = false;
// ***
let mut interpretation_plan : Vec<InterpretationItemPlan> = Vec::new();
let mut hibou_options_opt : Option<HibouOptions> = None;
// ***
let mut contents = setup_pair.into_inner();
while let Some(current_pair) = contents.next() {
match current_pair.as_rule() {
Rule::EXPLORE_OPTION_SECTION => {
if got_section_explore_options {
return Err( HibouParsingError::HsfSetupError("several '@explore_option' sections declared".to_string()));
}
got_section_explore_options = true;
match process_kind {
&ProcessKind::Explore => {
match parse_hibou_options(current_pair,file_name, process_kind) {
Err(e) => {
return Err(e);
},
Ok( hoptions ) => {
hibou_options_opt = Some(hoptions);
}
}
},
_ => {}
}
},
Rule::ANALYZE_OPTION_SECTION => {
if got_section_analyze_options {
return Err( HibouParsingError::HsfSetupError("several '@analyze_option' sections declared".to_string()));
}
got_section_analyze_options = true;
match process_kind {
&ProcessKind::Analyze => {
match parse_hibou_options(current_pair,file_name, process_kind) {
Err(e) => {
return Err(e);
},
Ok( hoptions ) => {
hibou_options_opt = Some(hoptions);
}
}
},
_ => {}
}
},
Rule::HIBOU_MODEL_MS_DECL => {
if got_section_messages {
return Err( HibouParsingError::HsfSetupError("several '@message' sections declared".to_string()));
}
got_section_messages = true;
parse_message_decl(current_pair,gen_ctx);
},
Rule::HIBOU_MODEL_VAR_DECL => {
if got_section_variables {
return Err( HibouParsingError::HsfSetupError("several '@variable' sections declared".to_string()));
}
got_section_variables = true;
parse_variable_decl(current_pair,gen_ctx);
},
Rule::HIBOU_MODEL_LF_DECL => {
if got_section_lifelines {
return Err( HibouParsingError::HsfSetupError("several '@lifeline' sections declared".to_string()));
}
got_section_lifelines = true;
parse_lifeline_decl(current_pair,gen_ctx);
},
Rule::HIBOU_MODEL_VAR_INIT => {
if got_section_init {
return Err( HibouParsingError::HsfSetupError("several '@init' sections declared".to_string()));
}
got_section_init = true;
match parse_initialization(current_pair,gen_ctx) {
Err(e) => {
return Err(e);
},
Ok( iip ) => {
interpretation_plan = iip;
}
}
},
_ => {
unreachable!();
}
}
}
match hibou_options_opt {
None => {
match process_kind {
ProcessKind::Analyze => {
return Ok( (interpretation_plan,HibouOptions::default_analyze()) );
},
_ => {
return Ok( (interpretation_plan,HibouOptions::default_explore()) );
}
}
},
Some(hibou_options) => {
return Ok( (interpretation_plan,hibou_options) );
}
}
}
fn parse_message_decl(ms_decl_pair : Pair<Rule>, gen_ctx : &mut GeneralContext) -> Result<(),HibouParsingError> {
for msg_decl_pair in ms_decl_pair.into_inner() {
let mut msg_decl_content = msg_decl_pair.into_inner();
let ms_name : String = msg_decl_content.next().unwrap().as_str().chars().filter(|c| !c.is_whitespace()).collect();
let mut ms_spec : Vec<(TD_DataType,Option<String>)> = Vec::new();
match msg_decl_content.next() {
None => {},
Some( msg_pr_decl ) => {
for pr_decl_pair in msg_pr_decl.into_inner() {
match pr_decl_pair.as_rule() {
Rule::PRM_DECLARATION => {
let mut var_decl_content = pr_decl_pair.into_inner();
let vr_name : String = var_decl_content.next().unwrap().as_str().chars().filter(|c| !c.is_whitespace()).collect();
let td_type_pair = var_decl_content.next().unwrap();
let (td_type, is_clock) = parse_type(td_type_pair);
if is_clock {
panic!("message parameter argument cannot be a clock");
}
ms_spec.push( (td_type,Some(vr_name)) );
},
_ => {
let (td_type, is_clock) = parse_type(pr_decl_pair);
if is_clock {
panic!("message parameter argument cannot be a clock");
}
ms_spec.push( (td_type,None) );
}
}
}
}
}
gen_ctx.add_msg(ms_name,ms_spec);
}
return Ok(());
}
fn parse_variable_decl(vr_decl_pair : Pair<Rule>, gen_ctx : &mut GeneralContext ) {
for var_decl_pair in vr_decl_pair.into_inner() {
let mut var_decl_content = var_decl_pair.into_inner();
let vr_name : String = var_decl_content.next().unwrap().as_str().chars().filter(|c| !c.is_whitespace()).collect();
let td_type_pair = var_decl_content.next().unwrap();
let (td_type, is_clock) = parse_type(td_type_pair);
let new_vr_id = gen_ctx.get_vr_num();
gen_ctx.add_vr( vr_name.clone(), td_type);
if is_clock {
gen_ctx.add_as_clock( new_vr_id );
}
}
}
fn parse_lifeline_decl(lf_decl_pair : Pair<Rule>, gen_ctx : &mut GeneralContext ) {
for lf_pair in lf_decl_pair.into_inner() {
let lf_name : String = lf_pair.as_str().chars().filter(|c| !c.is_whitespace()).collect();
gen_ctx.add_lf(lf_name);
}
}
fn parse_initialization(init_pair : Pair<Rule>, gen_ctx : &GeneralContext ) -> Result<Vec<InterpretationItemPlan>, HibouParsingError> {
let mut interpretation_plan : Vec<InterpretationItemPlan> = Vec::new();
for var_init_pair in init_pair.into_inner() {
let mut var_init_contents = var_init_pair.into_inner();
// ***
let lf_id : usize;
{
let lf_name_pair = var_init_contents.next().unwrap();
let lf_name : String = lf_name_pair.as_str().chars().filter(|c| !c.is_whitespace()).collect();
match gen_ctx.get_lf_id( &lf_name) {
None => {
return Err( HibouParsingError::MissingLifelineDeclarationError(lf_name) );
},
Some( got_lf_id ) => {
lf_id = got_lf_id;
}
}
}
// ***
let vr_id : usize;
{
let vr_name_pair = var_init_contents.next().unwrap();
let vr_name : String = vr_name_pair.as_str().chars().filter(|c| !c.is_whitespace()).collect();
match gen_ctx.get_vr_id( &vr_name) {
None => {
return Err( HibouParsingError::MissingVariableDeclarationError(vr_name) );
},
Some( got_vr_id ) => {
vr_id = got_vr_id;
}
}
}
// ***
{
let assignment_pair = var_init_contents.next().unwrap();
match assignment_pair.as_rule() {
Rule::TD_VALUE => {
match parse_data(gen_ctx,assignment_pair,&None) {
Err(e) => {
return Err(e);
},
Ok( td_generic ) => {
interpretation_plan.push( InterpretationItemPlan{lf_id,vr_id,assignment:ValueOrNewFresh::Value(td_generic)});
}
}
},
Rule::NEW_FRESH => {
interpretation_plan.push( InterpretationItemPlan{lf_id,vr_id,assignment:ValueOrNewFresh::NewFresh});
},
_ => {
panic!("what rule then ? : {:?}", assignment_pair.as_rule() );
}
}
}
// ***
}
return Ok(interpretation_plan);
}