Skip to content
Snippets Groups Projects
main.cpp 4.74 KiB
Newer Older
#include <cstdlib>

#include <libwccl/values/strset.h>
#include <libwccl/parser/Parser.h>
#include <libcorpus2/tagsetmanager.h>

#include <boost/bind.hpp>
#include <boost/program_options.hpp>

#include <antlr/MismatchedTokenException.hpp>
// ----------------------------------------------------------------------------

#ifdef HAVE_LIBEDIT

/**
 * @desc A simple command line tester for testing operators
 */


namespace {
	const char* _prompt = "Enter any operator expression: ";
}

void std_read_loop(boost::function<bool (const std::string&)>& line_cb)
{
	while (std::cin.good()) {
		std::cout << _prompt << std::flush;
		std::string s;
		getline(std::cin, s);
		if (line_cb(s)) {
			return;
		}
	}
}

int clear_screen()
{
#ifdef _WINDOWS
	return std::system("cls");
#else
	return std::system("clear");
#endif
}

#ifdef HAVE_LIBEDIT
const char* query_prompt(EditLine*) {
	return _prompt;
}

void libedit_read_loop(boost::function<bool (const std::string&)>& line_cb)
{
	EditLine *el = el_init("wccl-parser", stdin, stdout, stderr);
	el_set(el, EL_PROMPT, &query_prompt);
	el_set(el, EL_EDITOR, "emacs");
	History* myhistory = history_init();
	if (myhistory == NULL) {
		std::cerr << "EditLine history init error\n";
		el_end(el);
		std_read_loop(line_cb);
		return;
	}
	HistEvent ev;
	history(myhistory, &ev, H_SETSIZE, 1024);
	el_set(el, EL_HIST, history, myhistory);

	bool more = true;
	while (more) {
		int count;
		const char *line = el_gets(el, &count); // line gets a trailing \n
		if (line == NULL || line[0] == 0) {
			more = false;
		} else {
			std::string s(line, strlen(line) - 1);
			if (line_cb(s)) {
				more = false;
			} else {
				history(myhistory, &ev, H_ENTER, line);
			}
		}
	}

	history_end(myhistory);
	el_end(el);
}
#endif

bool process_line(const std::string& line, Parser& parser)
{
	if (line.empty() || line == "exit" || line == "quit") {
		return true;
	} else if (line == "clear" || line == "cls") {
		if (clear_screen()) {}
		return false;
	}

	boost::shared_ptr<const Wccl::Value> retVal;
	boost::shared_ptr<ANTLRParserResultBase> retOp;
	boost::shared_ptr<Corpus2::Sentence> sentence;
	sentence.reset(new Corpus2::Sentence);
	Wccl::SentenceContext sc(sentence);

	try {
		retOp = parser.parseAnyOperator(line);
		if (retOp) {
			Wccl::FunExecContext cx(sc, retOp->variables);
			retVal = retOp->get_op_base()->apply_internal(cx);
			if (retVal) {
				std::cerr << "Parsed expression: "
					<< retVal->to_string(parser.tagset())
					<< std::endl;
			} else {
				std::cerr << "Problem while parsing -- "
					<< "retVal is NULL!" << std::endl;
			}
		} else {
			std::cerr << "Problem while parsing -- "
				<< "parser returned NULL!" << std::endl;
		}
	} catch (antlr::MismatchedTokenException &e) {
		std::cerr << e.getMessage() << std::endl;
	} catch (Wccl::InvalidVariableName &e) {
		std::cerr << "Wccl::InvalidVariableName " << e.info() << std::endl;
	} catch (Wccl::VariableTypeMismatch &e) {
		std::cerr << "Wccl::VariableTypeMismatch " << e.info() << std::endl;
	} catch (Wccl::WcclError& e) {
		std::cerr << "Wccl::WcclError " << e.info() << std::endl;
	} catch (PwrNlp::PwrNlpError& e) {
		std::cerr << "PwrNlp::PwrNlpError " << e.info() << std::endl;
	} catch (antlr::ANTLRException& e) {
		std::cerr << "Antlr error " << e.getMessage() << std::endl;
	}
	return false;
}

int main(int argc, char** argv)
	std::string tagset_load = "kipi";
	bool quiet = false;
	using boost::program_options::value;

	boost::program_options::options_description desc("Allowed options");
	desc.add_options()
			("tagset,t", value(&tagset_load),
			 "Tagset to use\n")
			("query,Q", value(&query),
			 "Query to run (disables interactive mode)\n")
			("quiet,q", value(&quiet)->zero_tokens(),
			 "Suppress messages\n")
			("help,h", "Show help")
			;
	boost::program_options::variables_map vm;
	boost::program_options::positional_options_description p;

	try {
		boost::program_options::store(
			boost::program_options::command_line_parser(argc, argv)
			.options(desc).positional(p).run(), vm);
	} catch (boost::program_options::error& e) {
		std::cerr << e.what() << std::endl;
		return 2;
	}
	boost::program_options::notify(vm);

	if (vm.count("help")) {
		std::cout << desc << "\n";
		return 1;
	}

	try {
		Corpus2::get_named_tagset(tagset_load);
	} catch (Corpus2::FileNotFound& e) {
		std::cerr << e.info() << std::endl;
		return 2;
	}
	const Corpus2::Tagset& tagset = Corpus2::get_named_tagset(tagset_load);
	if (!query.empty()) {
		process_line(query, parser);
		return 0;
	}

	if (clear_screen()) {
		//
	}

	boost::function<bool (const std::string&)> f;
	f = boost::bind(&process_line, _1, boost::ref(parser));
#ifdef HAVE_LIBEDIT
	libedit_read_loop(f);
#else
	std_read_loop(f);
#endif

	return 0;
}