⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 from_xmpl.cpp

📁 vxworks的系统故障诊断项目
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            break; // pit points to the last iterator smaller than prop
        }
        pit = it;
        ++it;
    }

    // if we reached it==end, pit is last(), so this works in either case
    clause_props.insert(pit, prop);
    nclause_props++;
}

bool from_xmpl::clause_eq_clause_props(const L2rClause *cls) {
    // See if the clause matches.
    // Clauses are in increasing order, so we can check in linear time.
    unsigned cp_size = nclause_props;
    if(cp_size != cls->nprops()) return false;

    // for each element in clause_props, make sure it's in cls->props_
    unsigned i=0;
    Slist<L2rProposition*>::iterator pit=clause_props.begin();
    for( ; i < cp_size ; ++pit, ++i) {
        if(*pit != cls->prop(i))
            return false;
    }

    return true;
}


L2rClause *from_xmpl::find_or_create_clause() {
    // in case we get <clause/> which we actually do
    if(nclause_props==0) return 0;

    // foreach clause
    for(clausesIT it = clauses_.begin(); it != clauses_.end(); ++it) {
        L2rClause *cls = *it;
        // if we find a match, use it
        if(clause_eq_clause_props(cls))
            return cls;
    }

    // if we get here, then the clause represented by clause_props
    // doesn't match any clause in clauses_
    L2rClause *cls = new dbg_L2rClause(component_name, nclauses_++,
            nclause_props,
            list_to_array(clause_props),
            false);
    clauses_.push_front(cls);
    verbose(cls->toOStream_long(_STD_ cout));
    return cls;
}


/***************************************************************************
        Callback functions
 ***************************************************************************/

// All variables are attributes.
void from_xmpl::start_attribute(const MBA_string& name, const MBA_string& type) {
    MBA_string full_name = component_name + "." + name;
    dbg_L2rEnumeration *en = find_enum(type);
    L2rVariable *newvar = create_variable(en, full_name);

    if(name == "mode") {
        modevar_ = newvar;
        modevar_->setKind(vk_mode);
    }
}

// Note a variable is in fact commandable.
// Commandable variables must have the noCommand value in their domain.
// In fact, it must be index 0 (which is ensured by the code that makes the
// enumerations).
void from_xmpl::start_cmd(const MBA_string& varname) {
    L2rVariable *var = find_variable(varname);
    L2_assert(var->type()->hasDebug(), L2_fatal_error,
            ("Enumeration of variable "+varname+
             " has no debugging information"));
    const dbg_L2rEnumeration *en =
        static_cast<const dbg_L2rEnumeration*>(var->type());
    L2_assert(en->name(0) == noCommand, L2_parse_model_error,
            ("Enumeration "+ en->name() + " of commandable variable "+varname+
             "\nshould have the `noCommand' value"));
    var->setKind(vk_commanded);
}

// Note a variable is in fact observable.
void from_xmpl::start_obs(const MBA_string& varname) {
    L2rVariable *var = find_variable(varname);
    var->setKind(vk_observed);
}


// Initial value for a variable.
void from_xmpl::start_assign(const MBA_string& prop) {
    // split the proposition
    int eq_index = prop.find("=");
    L2_assert(eq_index != MBA_string::npos, L2_parse_model_error,
            ("no '=' parsing assign "));
    MBA_string varname(prop.c_str(), eq_index);
    MBA_string valuename(prop.c_str()+eq_index+1); // skip the =

    // find the internal representation
    L2rVariable *var = find_variable(varname);
    int value = find_enum_member(var->type(), valuename);
    var->setInitial(value);
}

// An enumeration; the values are space-separated.
void from_xmpl::start_attributetype(const MBA_string& name, const MBA_string& values) {
    // extract a list of strings from the single values string
    Slist<MBA_string> memnames;
    for(unsigned i=0; i<values.size(); /* iteration is done inside */ ) {
        // skip a word
        unsigned j;
        for(j=i; j<values.size() && values[j]!=' '; j++) ;
        memnames.push_back(MBA_string(values.c_str()+i, j-i));
        i=j;

        // skip whitespace
        for( ; i<values.size() && values[i]==' '; i++) ;
    }
    create_enum(name, memnames);
}

// Start a new component; we just store the name to prepend it.
void from_xmpl::start_component(const MBA_string& name) {
    component_name = name;
}

// We need to know we're parsing a clause.
void from_xmpl::start_clause() {
    parsing_clause = true;
}

// We need to know we're parsing a prop.
void from_xmpl::start_prop() {
    parsing_prop = true;
}

// Currently we only handle a single state (eg mode) variable and it
// must be called mode.
void from_xmpl::start_statevector(const MBA_string& vector) {
    L2_assert(vector=="mode", L2_reader_error,
            ("mode variable must be called `mode', not `"+vector+"'"));
}

void from_xmpl::start_transition(const MBA_string& from, const MBA_string& to,
        const MBA_string& name, const MBA_string& prob) {
    parsing_transition = true;
    transition_name = name;

    transition_from = find_enum_member(modevar_->type(), from);
    transition_to   = find_enum_member(modevar_->type(), to);

    if(prob=="") {
        // probability is only specified for failures,
        // so this must be a nominal transition
        transition_isNominal = true;
        transition_rank = 0;
    }
    else {
        transition_isNominal = false;
        transition_rank = convert_to_rank(prob);
    }
}

void from_xmpl::characters(const MBA_string& prop_str) {
    // ignore whitespace and other junk outside of the <term> tags
    if (!parsing_prop) return;

    // the string comes in the format:
    //     var=value
    // or
    //     !var=value
    // where value may be a member of var->type() or another variable
    bool isPositive;
    L2rVariable *var;

    unsigned i;
    if(prop_str[0] == '!') {
        isPositive = false;
        i = 1;
    }
    else {
        isPositive = true ;
        i = 0;
    }

    for(/*i already set*/ ; i<prop_str.size(); i++) {
        if(prop_str[i]=='=') break;
    }
    MBA_string varname;
    varname = component_name + ".";
    // read up to but not including the '=' ; also, skip '!' (which of course
    // changes the count)
    if(isPositive) varname = varname + MBA_string(prop_str.c_str(), i);
    else           varname = varname + MBA_string(prop_str.c_str()+1, i-1);

    // read starting from right after the '='
    MBA_string valuename(prop_str.c_str()+i+1);

    var = find_variable(varname);

    add_clause_prop(find_or_create_prop(var, isPositive, valuename));
}

void from_xmpl::end_component() {
    // fully-parsed already; unlike in the L2_writer,
    // we really don't care about components.
    component_name = "";

    // just for debugging, really
    modevar_ = 0;
    return;
}

void from_xmpl::end_clause() {
    // we may be creating a new clause here, or maybe not
    L2rClause *cls = find_or_create_clause();

    // this happens in a nominal, idle transition; we get a:
    // <clause/> tag, which has no propositions.  Looks like
    // a dirty hack to me, and I don't need it.
    if(!cls) return;

    // if we're in the background model, stuff the clause there;
    // if we're in a transition, put it there instead
    if(parsing_transition)
        transition_clauses.push_back(cls);
    else
        cls->putInBackground();

    parsing_clause = false;
    clause_props.erase();
    nclause_props = 0;
}

// Propositions are stored in clause_props, which
// is cleaned up in </ci:clause> so nothing left to do here
void from_xmpl::end_prop() {
    parsing_prop = false;
}

// Now we have the transition_clauses, so we can create the transition
void from_xmpl::end_transition() {
    L2rTransition *newtran = new dbg_L2rTransition(
            transition_name,
            modevar_, transition_from, transition_to,
            transition_clauses.size(),
            list_to_array(transition_clauses),false,
            transition_isNominal, transition_rank);
    X_.push_back(newtran);
    verbose(newtran->toOStream_long(_STD_ cout));

    // clear the variables that accumulated the info
    parsing_transition = false;
    transition_clauses.erase();
    // others don't matter; and we shouldn't clear modevar_
}

/***************************************************************************
        The 'mainline'
 ***************************************************************************/

bool try_to_open(const MBA_string& name) {
    _STD_ ifstream try_file(name.c_str());
    if(!try_file) {
        _STD_ cerr << "Error opening `" << name << "'";
#ifndef WIN32
        _STD_ cerr << ": " << strerror(errno);
#endif
        _STD_ cerr << _STD_ endl;
        return false;
    }
    else
        return true;
}

bool from_xmpl::read() {

    // parse the files.  Really easy now!
    XMLPlatformUtils::Initialize();

    HandlerBase_subclass handler (*this);
    SAXParser parser;
    parser.setDocumentHandler(&handler);
    parser.setErrorHandler(&handler);

    L2_TRY {

        // the main model file
        handler.filename = filename_ + ".xmpl";
        verbose(_STD_ cout << "Reading " << handler.filename << _STD_ endl);
        if(!try_to_open(handler.filename)) return false;
        parser.parse( (handler.filename).c_str());

        // the harness file
        handler.filename = filename_ + ".hrn";
        verbose(_STD_ cout << "Reading " << handler.filename << _STD_ endl);
        if(!try_to_open(handler.filename)) return false;
        parser.parse( (handler.filename).c_str());

        // the initial mode file
        handler.filename = filename_ + ".ini";
        verbose(_STD_ cout << "Reading " << handler.filename << _STD_ endl);
        if(!try_to_open(handler.filename)) return false;
        parser.parse( (handler.filename).c_str());
    }
#ifdef ENABLE_EXCEPTIONS
    catch(const XMLException& xcp) {
        L2_throw( L2_reader_error,
                (MBA_string("Error reading `") + handler.filename +"': "
                 + XMLString::transcode(xcp.getMessage()) + "\n"));
    }
#endif

    // Now, the bulk of this function's work: putting it all into
    // the L2_file structure.

    // We set the prop and transition IDs here only, since we have
    // to put them in a particular order.

    {
        // enumerations
        dest()->allocEnums(nenums_, true);
        for(enumsIT eit = enums_.begin(); eit != enums_.end(); ++eit) {
            dbg_L2rEnumeration *en = *eit;
            dest()->setEnum(en->id(), en);
        }
    }

    {
        // variables
        dest()->allocVars(vars_.size(), true);
        for(varsIT vit = vars_.begin(); vit != vars_.end(); ++vit) {
            dbg_L2rVariable *var = *vit;
            dest()->setVar(var->id(), var);
        }
    }

    {
        dest()->allocProps(nprops_);
        for(propsIT pit = props_.begin(); pit != props_.end(); ++pit) {
            L2rProposition *p = *pit;
            dest()->setProp(p->id(), p);
        }
    }


    {
        // clauses
        dest()->allocClauses(nclauses_, true);
        for(clausesIT cit = clauses_.begin(); cit != clauses_.end(); ++cit) {
            L2rClause *cls = *cit;
            dest()->setClause(cls->id(), cls);
        }
    }

    {
        // transitions ; these are just added in, don't even need to allocate
        transitionsIT xit = X_.begin();
        for(xit = X_.begin(); xit != X_.end(); ++xit) {
            dest()->addTransition(*xit);
        }
    }

    // didn't fail so we succeded!
    return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -