diff --git a/atrim2/src/atrim.cpp b/atrim2/src/atrim.cpp index 58e8c47ad1500baa6c69907f8a49d761df01580c..ea04560a24529d4a93ec1e0f34a584e7e22d55bc 100644 --- a/atrim2/src/atrim.cpp +++ b/atrim2/src/atrim.cpp @@ -5,8 +5,7 @@ * Author: Tomas Pecka */ -#include <iostream> -#include <getopt.h> +#include <tclap/CmdLine.h> #include <factory/DataFactory.hpp> #include <exception/AlibException.h> @@ -19,19 +18,6 @@ #include "automaton/simplify/UnreachableStatesRemover.h" #include "regexp/simplify/RegExpOptimize.h" -void help( void ) { - std::cout << "atrim 0.01" << std::endl; - std::cout << "Removes unreachable and useless states from FSM, productive and unreachable nonterminals from CFG. Simplifies representation of RE" << std::endl; - std::cout << "Usage: atrim [-u] [-r] [-s] [-h]" << std::endl << std::endl; - std::cout << "If neither --useless nor --unreachable option is used, both useless and unreachable states (or symbols) are removed." << std::endl; - std::cout << std::endl; - std::cout << " -u, --useless \t Removes useless states (or symbols). (works with FSM or CFG)" << std::endl; - std::cout << " -r, --unreachable \t Removes unreachable states (or symbols). (works with FSM or CFG)" << std::endl; - std::cout << " -s, --simplify \t Simplifies representation. (works with RE only)" << std::endl; - std::cout << " -h, --help \t shows this." << std::endl; - std::cout << std::endl; -} - grammar::Grammar trimGrammar(const grammar::Grammar& g, bool del_unreachable, bool del_unproductive) { if( del_unreachable && del_unproductive ) return grammar::simplify::Trim::trim( g ); @@ -39,7 +25,7 @@ grammar::Grammar trimGrammar(const grammar::Grammar& g, bool del_unreachable, bo return grammar::simplify::UnreachableSymbolsRemover::remove( g ); if( del_unproductive ) return grammar::simplify::UnproductiveSymbolsRemover::remove( g ); - return g; + return grammar::simplify::Trim::trim( g ); } automaton::Automaton trimAutomaton(const automaton::Automaton& g, bool del_unreachable, bool del_useless) { @@ -49,7 +35,7 @@ automaton::Automaton trimAutomaton(const automaton::Automaton& g, bool del_unrea return automaton::simplify::UnreachableStatesRemover::remove( g ); if( del_useless ) return automaton::simplify::UselessStatesRemover::remove( g ); - return g; + return automaton::simplify::Trim::trim( g ); } regexp::RegExp optimizeRegExp(const regexp::RegExp& r) { @@ -57,56 +43,45 @@ regexp::RegExp optimizeRegExp(const regexp::RegExp& r) { } int main(int argc, char* argv[]) { - bool del_useless = false, del_unreachables = false; - - static struct option long_options[] = { - {"help", no_argument, NULL, 'h'}, - {"useless", no_argument, NULL, 'u'}, - {"unreachable", no_argument, NULL, 'r'}, - {0, 0, 0, 0} - }; - - int long_index = 0, opt = 0; - - while( ( opt = getopt_long( argc, argv, "hru", long_options, & long_index ) ) != -1 ) { - switch( opt ) { - case 'u': - del_useless = true; - break; - case 'r': - del_unreachables = true; - break; - - case 'v': - case 'h': - default: - help( ); - return 0; - } - } + try { + TCLAP::CmdLine cmd("Removes unreachable and useless states from FSM, productive and unreachable nonterminals from CFG. Simplifies representation of RE", ' ', "0.01"); - std::list<sax::Token> tokens; - if(optind == argc) { - sax::SaxParseInterface::parseStdin(tokens); - } else { - sax::SaxParseInterface::parseFile(argv[optind], tokens); - } + TCLAP::SwitchArg useless( "u", "useless", "Removes useless states (or symbols). (works with FSM or CFG)" ); + cmd.add( useless ); - if( ! del_useless && ! del_unreachables ) - del_useless = del_unreachables = true; + TCLAP::SwitchArg unreachable( "r", "unreachable", "Removes unreachable states (or symbols). (works with FSM or CFG)" ); + cmd.add( unreachable ); + + TCLAP::SwitchArg simplify( "s", "simplify", "Simplifies representation. (works with RE only)" ); + cmd.add( simplify ); + + TCLAP::UnlabeledValueArg<std::string> input( "input", "Input to trim", false, "-", "file"); + cmd.add( input ); + + cmd.parse(argc, argv); + + std::list<sax::Token> tokens; + if(input.isSet()) { + if(input.getValue() == "-") { + sax::SaxParseInterface::parseStdin(tokens); + } else { + sax::SaxParseInterface::parseFile(input.getValue(), tokens); + } + } else { + sax::SaxParseInterface::parseStdin(tokens); + } - try { if( alib::FromXMLParsers::automatonParser.first(tokens)) { automaton::Automaton automaton = alib::DataFactory::fromTokens<automaton::Automaton>(tokens); - automaton::Automaton res = trimAutomaton(automaton, del_unreachables, del_useless ); + automaton::Automaton res = trimAutomaton(automaton, unreachable.getValue(), useless.getValue() ); alib::DataFactory::toStdout( res ); return 0; } else if( alib::FromXMLParsers::grammarParser.first(tokens)) { grammar::Grammar grammar = alib::DataFactory::fromTokens<grammar::Grammar>(tokens); - grammar::Grammar res = trimGrammar(grammar, del_unreachables, del_useless ); + grammar::Grammar res = trimGrammar(grammar, unreachable.getValue(), useless.getValue() ); alib::DataFactory::toStdout( res ); return 0; @@ -126,6 +101,9 @@ int main(int argc, char* argv[]) { } catch( const exception::AlibException & e ) { alib::DataFactory::toStdout( e ); return 1; + } catch(const TCLAP::ArgException& exception) { + std::cout << exception.error() << std::endl; + return 2; } catch (...) { return 127; }