Parsodus/src/inputparser.cpp

62 lines
1.7 KiB
C++

#include "ParsodusLexer.h"
#include "Parsodus/inputparser.h"
#include "Parsodus/parser.h"
#include "Parsodus/util/parserType.h"
#include "Lexesis/inputparser.h"
#include <set>
#include <fstream>
#include <iostream>
namespace {
std::set<std::string> getTerminals(std::string file) {
std::fstream f(file);
return lxs::input::InputParser::getTokens(f);
}
}
namespace pds {
InputParserException::InputParserException(std::string what): m_what(what) {}
const char* InputParserException::what() const throw() {
return m_what.c_str();
}
Config InputParser::parseInput(std::istream& is) {
ParsodusLexer lex(is);
Parser parser(lex);
Config cnf = *parser.parse();
if (!cnf.lexesisFile.empty()) {
auto terminals = getTerminals(cnf.lexesisFile);
for(auto& terminal : terminals)
cnf.grammar.terminals.insert(terminal);
}
for(auto& rule : cnf.grammar.rules) {
for(auto& tail_piece : rule->tail) {
if (cnf.grammar.terminals.find(tail_piece) == cnf.grammar.terminals.end() &&
cnf.grammar.variables.find(tail_piece) == cnf.grammar.variables.end())
throw InputParserException("Found '" + tail_piece + "' in rule body while this isn't a variable or terminal");
}
}
bool found_token;
for(auto& term : cnf.grammar.terminals) {
found_token = false;
for(auto& rule : cnf.grammar.rules) {
for(auto& tail_value : rule->tail) {
if (tail_value == term) {
found_token = true;
break;
}
}
if (found_token) break;
}
if (!found_token)
std::cout << "Warning: Terminal '" << term << "' is not been used." << std::endl;
}
return cnf;
}
}