53 #include<unordered_map> 54 #include<boost/program_options.hpp> 58 #include"../AutomataInterface.hh" 66 namespace Poptions = boost::program_options;
74 const string program(
"dd-tagstates");
75 const string briefcomment(
": this program tags some states based on regular expressions (output file or standard output).");
76 const string detailedcomment=R
"( dd-tagstates tags a set of states to be initial or final based 77 on a regular expression. Regular expression are defined as proposed in 78 http://www.cplusplus.com/reference/regex/ECMAScript/ 80 Example 1: set to be acceptor any states such that its label contains 81 the substring 'o.p=ko' 83 dd-tagstates file.ddaut -r 'final:.*o\.p=ko.*' 85 Example 2: set to be non-acceptor any states such that its label contains the substring 'o.p=ok' 87 dd-tagstates file.ddaut -r 'nofinal:.*o\.p=ok.*' 89 Example 3: set to be initial any states such that its label contains the substring 'init' 91 dd-tagstates file.ddaut -r 'initial:.*init.*' 93 Example 4: set to be not initial any states such that its label is 's1' or 's2' or 's3' 95 dd-tagstates file.ddaut -r 'noinitial:s[1-3]' 97 Example 5: Applying Example 5: applying Examples 1-4 in one go. Tagging works 98 from left to right, we tag first 'final:.*o\.p=ko.*' then -r 'nofinal:.*o\.p=ok.*' 101 dd-tagstates file.ddaut -r 'final:.*o\.p=ko.*' -r 'nofinal:.*o\.p=ok.*' -r 'initial:.*init.*' -r 'noinitial:s[1-3]' 104 Example 6: tag a set of states S as acceptors and tag other states so that any prefix of a word accepted by a state of S 105 is also an accepted word. 107 dd-tagstates file.ddaut -r 'prefix-closed-final:.*o\.p=ko.*' 109 Example 7: swap the tags of the set of states S: swap-final if the state is final swap to non-final, if the state is 110 final then swap to final. swap-initial if the state is initial swap to non-initial, if the state is non-initial then swap 113 dd-tagstates file.ddaut -r 'swap-final:.*o\.p=ko.*' 'swap-initial:.*o\.p=ok.*' 130 Poptions::options_description & desc,
131 Poptions::variables_map & vm)
134 (
"help,h",
"produce help message")
135 (
"file,f", Poptions::value< string >(),
"file (.ddaut format)")
136 (
"regexp,r", Poptions::value< vector<string> >(),
137 R
"(A set of expressions inside a set of quotes: 'tag:regexp' 138 tag can be final, initial, nofinal, noinitial. 139 Regular expression regexp are on the name of 140 the states, for details see 141 http://www.cplusplus.com/reference/regex/ECMAScript/) 142 dd-tagstates applies the tags in the order written in 144 ("output,o", Poptions::value< string >(),
"outfile name (.ddaut format)")
146 Poptions::positional_options_description p;
149 Poptions::store(Poptions::command_line_parser(argc, argv).
options(desc).positional(p).run(), vm);
150 Poptions::notify(vm);
163 const std::unordered_map<std::string,Tag>
tagOf = {
169 {
"swap-initial",swapinitial},
191 std::list<DdAutFA::State> & acceptors)
193 std::list<DdAutFA::State> visitingStates;
197 visitingStates.push_back(state);
200 acceptors.push_back(state);
210 while(!visitingStates.empty())
212 auto current = visitingStates.front();
213 visitingStates.pop_front();
217 if(mapping[transition.target()] == 0)
219 visitingStates.push_back(transition.target());
222 acceptors.push_back(transition.target());
223 mapping[transition.target()]=2;
228 mapping[transition.target()]=1;
239 std::list<DdAutFA::State> visitingStates = acceptors;
240 while(!visitingStates.empty())
242 auto current = visitingStates.front();
243 for(
const auto & state : acceptors)
248 visitingStates.pop_front();
252 if(mapping[transition.source()] == 1)
254 mapping[transition.source()] = 2;
255 visitingStates.push_back(transition.source());
265 std::list<DdAutFA::State> acceptors;
272 auto pos = expr.find_first_of(
":");
273 if(pos== std::string::npos)
278 auto tagIt = tagOf.find(expr.substr(0,pos));
279 if(tagIt != tagOf.end())
280 {
auto regexp = expr.substr(pos+1);
281 std::regex reg(regexp);
285 for(
auto & stateProperty: sManager.
storage())
287 if(std::regex_match(stateProperty,reg))
301 tagDdAutStates2(
const string & fileName,
const string & output,
const std::vector<std::string> & regexp)
306 ifstream file(fileName.c_str());
324 return printCommandLineError(
Msg(
"Error when converting the DdAutFileDescriptor from %1% to a Finite Automaton") % fileName);
326 for(
const auto & expr : regexp)
337 ofstream outfile(output.c_str());
338 if(outfile.is_open())
352 size_t tagDdAutStates(
const string & fileName,
const string & output,
const std::vector<std::string> & regexp)
359 return printCommandLineError(
Msg(
"Expecting an output file with a name ending with .ddaut, but I read %1%") % output);
383 std::string fileName, output;
384 std::vector<std::string> regexp;
388 Poptions::options_description desc(
"Options");
389 Poptions::variables_map vm;
397 fileName = vm[
"file"].as<std::string> ();
399 if(vm.count(
"output"))
401 output = vm[
"output"].as<std::string>();
403 if(vm.count(
"regexp"))
405 regexp = vm[
"regexp"].as<std::vector<std::string>>();
408 catch(Poptions::required_option & e)
412 catch(Poptions::error & e)
Diades::Graph::ConstNodeMap< Type > CstStMap
StatePropertyManager< DdAutStateLabel, DdAutStateId > DdAutStateManager
StatePropertyId statePropertyId(const StateProperty &stateProperty)
const size_t ERROR_UNHANDLED_EXCEPTION
size_t printCommandLineError(const string &msg)
bool faFromDescriptor(const DdAutFileDescriptor &descriptor, DdAutFA &fa, DdAutStateManager &sManager, DdAutEventManager &eManager)
vector< string > options(numberOfOptions)
OutputTransitionIterator outputTransitionBegin(State s) const
InitialStateIterator initialStateEnd() const
InputTransitionIterator inputTransitionBegin(State s) const
bool faToDdAutFile(ostream &stream, const ConstManagedDdAutFA &mFa)
bool match(const std::string &fileName, const std::string &suffix) const
typename SM::Transition Transition
FiniteAutomaton< DdAutStateId, DdAutEventId > DdAutFA
std::pair< AcceptingStateIterator, bool > setAcceptingState(State state)
string tag(SpecialisedActiveDiagnoser::Tag tag)
OutputTransitionIterator outputTransitionEnd(State s) const
unsigned numberOfStates() const
InputTransitionIterator inputTransitionEnd(State s) const
void setInitial(State state)
Graph::Graph & behaviour()
InitialStateIterator initialStateBegin() const
EventManager< DdAutEventLabel, DdAutEventId > DdAutEventManager
StateMachine< DdAutStateId, DdAutEventId > DdAutFsm
const StatePropertyId & getStatePropertyId(State state) const
const std::vector< Info > & storage() const
void unsetInitial(State state)
const StateProperty & getStateProperty(StatePropertyId id) const
AcceptingStateIterator unsetAcceptingState(State state)
void swapAcceptingState(State state)
swap the status of the state as accepting/non-accepting
State getState(const StatePropertyId &sProperty) const
void swapInitialState(State state)
swap the status of the state as initial/non-initial
virtual bool readStream(std::istream &stream)
void printUsage(const po::options_description &desc)