Implemented multi-file input.
This commit is contained in:
parent
64190ba55a
commit
4228ca01dc
@ -16,7 +16,7 @@ int main(int argc, char **argv)
|
|||||||
description.add_options()
|
description.add_options()
|
||||||
("help,h", "Display this help message.")
|
("help,h", "Display this help message.")
|
||||||
("version,v", "Display version information.")
|
("version,v", "Display version information.")
|
||||||
("input,i", po::value<std::string>(), "Specify the SAS input file.")
|
("input,i", po::value<std::vector<std::string>>(), "Specify the SAS input file.")
|
||||||
("format,f", po::value<std::string>()->default_value("SAS"), "Specify the file format (SAS or PDDL).");
|
("format,f", po::value<std::string>()->default_value("SAS"), "Specify the file format (SAS or PDDL).");
|
||||||
|
|
||||||
po::positional_options_description positionalOptionsDescription;
|
po::positional_options_description positionalOptionsDescription;
|
||||||
@ -66,10 +66,19 @@ int main(int argc, char **argv)
|
|||||||
auto format = variablesMap["format"].as<std::string>();
|
auto format = variablesMap["format"].as<std::string>();
|
||||||
std::transform(format.begin(), format.end(), format.begin(), ::tolower);
|
std::transform(format.begin(), format.end(), format.begin(), ::tolower);
|
||||||
|
|
||||||
|
const auto &inputFiles = variablesMap["input"].as<std::vector<std::string>>();
|
||||||
|
|
||||||
if (format == "sas")
|
if (format == "sas")
|
||||||
{
|
{
|
||||||
|
if (inputFiles.size() > 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Error: Only one input file allowed for SAS translation" << std::endl;
|
||||||
|
printHelp();
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
const auto sasDescription = variablesMap.count("input")
|
const auto sasDescription = variablesMap.count("input")
|
||||||
? plasp::sas::Description::fromFile(variablesMap["input"].as<std::string>())
|
? plasp::sas::Description::fromFile(inputFiles.front())
|
||||||
: plasp::sas::Description::fromStream(std::cin);
|
: plasp::sas::Description::fromStream(std::cin);
|
||||||
const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription);
|
const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription);
|
||||||
sasTranslator.translate(std::cout);
|
sasTranslator.translate(std::cout);
|
||||||
@ -77,7 +86,7 @@ int main(int argc, char **argv)
|
|||||||
else if (format == "pddl")
|
else if (format == "pddl")
|
||||||
{
|
{
|
||||||
const auto pddlDescription = variablesMap.count("input")
|
const auto pddlDescription = variablesMap.count("input")
|
||||||
? plasp::pddl::Description::fromFile(variablesMap["input"].as<std::string>())
|
? plasp::pddl::Description::fromFiles(inputFiles)
|
||||||
: plasp::pddl::Description::fromStream(std::cin);
|
: plasp::pddl::Description::fromStream(std::cin);
|
||||||
//std::cout << pddlDescription << std::endl;
|
//std::cout << pddlDescription << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class Description
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Description fromStream(std::istream &istream);
|
static Description fromStream(std::istream &istream);
|
||||||
static Description fromFile(const boost::filesystem::path &path);
|
static Description fromFiles(const std::vector<std::string> &paths);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Domain &domain() const;
|
const Domain &domain() const;
|
||||||
|
@ -30,9 +30,11 @@ class Domain
|
|||||||
|
|
||||||
bool isDeclared() const;
|
bool isDeclared() const;
|
||||||
|
|
||||||
|
void setName(std::string name);
|
||||||
const std::string &name() const;
|
const std::string &name() const;
|
||||||
|
|
||||||
const Requirements &requirements() const;
|
const Requirements &requirements() const;
|
||||||
|
bool hasRequirement(Requirement::Type requirementType) const;
|
||||||
|
|
||||||
expressions::PrimitiveTypes &types();
|
expressions::PrimitiveTypes &types();
|
||||||
const expressions::PrimitiveTypes &types() const;
|
const expressions::PrimitiveTypes &types() const;
|
||||||
@ -52,7 +54,6 @@ class Domain
|
|||||||
void parseSection();
|
void parseSection();
|
||||||
|
|
||||||
void parseRequirementSection();
|
void parseRequirementSection();
|
||||||
bool hasRequirement(Requirement::Type requirementType) const;
|
|
||||||
void computeDerivedRequirements();
|
void computeDerivedRequirements();
|
||||||
|
|
||||||
void parseTypeSection();
|
void parseTypeSection();
|
||||||
|
@ -44,6 +44,8 @@ class Problem
|
|||||||
bool hasRequirement(Requirement::Type requirementType) const;
|
bool hasRequirement(Requirement::Type requirementType) const;
|
||||||
void computeDerivedRequirements();
|
void computeDerivedRequirements();
|
||||||
|
|
||||||
|
void parseDomainSection();
|
||||||
|
|
||||||
void parseObjectSection();
|
void parseObjectSection();
|
||||||
|
|
||||||
Context &m_context;
|
Context &m_context;
|
||||||
|
@ -21,6 +21,11 @@ class Parser
|
|||||||
public:
|
public:
|
||||||
explicit Parser(std::istream &istream);
|
explicit Parser(std::istream &istream);
|
||||||
|
|
||||||
|
void setFileName(std::string fileName);
|
||||||
|
const std::string &fileName() const;
|
||||||
|
|
||||||
|
void resetPosition();
|
||||||
|
|
||||||
size_t row() const;
|
size_t row() const;
|
||||||
size_t column() const;
|
size_t column() const;
|
||||||
|
|
||||||
@ -60,6 +65,7 @@ class Parser
|
|||||||
uint64_t parseIntegerBody();
|
uint64_t parseIntegerBody();
|
||||||
|
|
||||||
std::istream &m_istream;
|
std::istream &m_istream;
|
||||||
|
std::string m_fileName;
|
||||||
std::istreambuf_iterator<char> m_position;
|
std::istreambuf_iterator<char> m_position;
|
||||||
|
|
||||||
size_t m_row;
|
size_t m_row;
|
||||||
@ -67,7 +73,7 @@ class Parser
|
|||||||
|
|
||||||
bool m_isCaseSensitive;
|
bool m_isCaseSensitive;
|
||||||
|
|
||||||
bool m_endOfFile;
|
bool m_atEndOfFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -31,7 +31,7 @@ class ParserException: public std::exception
|
|||||||
}
|
}
|
||||||
|
|
||||||
explicit ParserException(const utils::Parser &parser, const std::string &message)
|
explicit ParserException(const utils::Parser &parser, const std::string &message)
|
||||||
: m_message{std::to_string(parser.row()) + ":" + std::to_string(parser.column()) + "\t" + message}
|
: m_message{parser.fileName() + ":" + std::to_string(parser.row()) + ":" + std::to_string(parser.column()) + " " + message}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class ParserWarning: public std::exception
|
|||||||
}
|
}
|
||||||
|
|
||||||
explicit ParserWarning(const utils::Parser &parser, const std::string &message)
|
explicit ParserWarning(const utils::Parser &parser, const std::string &message)
|
||||||
: m_message{std::to_string(parser.row()) + ":" + std::to_string(parser.column()) + "\t" + message}
|
: m_message{parser.fileName() + ":" + std::to_string(parser.row()) + ":" + std::to_string(parser.column()) + " " + message}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,9 @@ namespace pddl
|
|||||||
|
|
||||||
Description::Description(std::istream &istream)
|
Description::Description(std::istream &istream)
|
||||||
: m_parser(istream),
|
: m_parser(istream),
|
||||||
m_context(m_parser)
|
m_context(m_parser),
|
||||||
|
m_domain{std::make_unique<Domain>(Domain(m_context))},
|
||||||
|
m_problem{std::make_unique<Problem>(Problem(m_context, *m_domain))}
|
||||||
{
|
{
|
||||||
m_parser.setCaseSensitive(false);
|
m_parser.setCaseSensitive(false);
|
||||||
}
|
}
|
||||||
@ -31,19 +33,9 @@ Description Description::fromStream(std::istream &istream)
|
|||||||
{
|
{
|
||||||
Description description(istream);
|
Description description(istream);
|
||||||
|
|
||||||
description.m_domain = std::make_unique<Domain>(Domain(description.m_context));
|
description.m_parser.setFileName("std::cin");
|
||||||
description.m_problem = std::make_unique<Problem>(Problem(description.m_context, *description.m_domain));
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
description.m_context.parser.skipWhiteSpace();
|
|
||||||
|
|
||||||
if (description.m_context.parser.atEndOfFile())
|
|
||||||
break;
|
|
||||||
|
|
||||||
description.parseContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
description.parseContent();
|
||||||
description.checkConsistency();
|
description.checkConsistency();
|
||||||
|
|
||||||
return description;
|
return description;
|
||||||
@ -51,14 +43,36 @@ Description Description::fromStream(std::istream &istream)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Description Description::fromFile(const boost::filesystem::path &path)
|
Description Description::fromFiles(const std::vector<std::string> &paths)
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::is_regular_file(path))
|
BOOST_ASSERT(!paths.empty());
|
||||||
throw std::runtime_error("File does not exist: \"" + path.string() + "\"");
|
|
||||||
|
|
||||||
std::ifstream fileStream(path.string(), std::ios::in);
|
std::for_each(paths.cbegin(), paths.cend(),
|
||||||
|
[&](const auto &path)
|
||||||
|
{
|
||||||
|
if (!boost::filesystem::is_regular_file(path))
|
||||||
|
throw std::runtime_error("File does not exist: \"" + path + "\"");
|
||||||
|
});
|
||||||
|
|
||||||
return Description::fromStream(fileStream);
|
std::ifstream fileStream;
|
||||||
|
Description description(fileStream);
|
||||||
|
|
||||||
|
std::for_each(paths.cbegin(), paths.cend(),
|
||||||
|
[&](const auto &path)
|
||||||
|
{
|
||||||
|
fileStream.close();
|
||||||
|
fileStream.clear();
|
||||||
|
fileStream.open(path, std::ios::in);
|
||||||
|
|
||||||
|
description.m_parser.setFileName(path);
|
||||||
|
description.m_parser.resetPosition();
|
||||||
|
|
||||||
|
description.parseContent();
|
||||||
|
});
|
||||||
|
|
||||||
|
description.checkConsistency();
|
||||||
|
|
||||||
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -74,12 +88,18 @@ const Domain &Description::domain() const
|
|||||||
|
|
||||||
void Description::parseContent()
|
void Description::parseContent()
|
||||||
{
|
{
|
||||||
std::cout << "Parsing file content" << std::endl;
|
while (true)
|
||||||
|
{
|
||||||
|
m_context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
m_context.parser.expect<std::string>("(");
|
if (m_context.parser.atEndOfFile())
|
||||||
m_context.parser.expect<std::string>("define");
|
return;
|
||||||
parseSection();
|
|
||||||
m_context.parser.expect<std::string>(")");
|
m_context.parser.expect<std::string>("(");
|
||||||
|
m_context.parser.expect<std::string>("define");
|
||||||
|
parseSection();
|
||||||
|
m_context.parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -91,8 +111,6 @@ void Description::parseSection()
|
|||||||
|
|
||||||
const auto sectionIdentifier = m_context.parser.parse<std::string>();
|
const auto sectionIdentifier = m_context.parser.parse<std::string>();
|
||||||
|
|
||||||
std::cout << "Parsing section " << sectionIdentifier << std::endl;
|
|
||||||
|
|
||||||
if (sectionIdentifier == "domain")
|
if (sectionIdentifier == "domain")
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(m_domain);
|
BOOST_ASSERT(m_domain);
|
||||||
@ -119,6 +137,9 @@ void Description::parseSection()
|
|||||||
|
|
||||||
void Description::checkConsistency()
|
void Description::checkConsistency()
|
||||||
{
|
{
|
||||||
|
if (!m_domain->isDeclared())
|
||||||
|
throw ConsistencyException("No PDDL domain specified");
|
||||||
|
|
||||||
m_domain->checkConsistency();
|
m_domain->checkConsistency();
|
||||||
m_problem->checkConsistency();
|
m_problem->checkConsistency();
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,13 @@ Domain::Domain(Context &context)
|
|||||||
|
|
||||||
void Domain::readPDDL()
|
void Domain::readPDDL()
|
||||||
{
|
{
|
||||||
m_name = m_context.parser.parseIdentifier(isIdentifier);
|
const auto domainName = m_context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
if (m_name.empty())
|
||||||
|
m_name = domainName;
|
||||||
|
// If the domain has previously been referenced, check that the name matches
|
||||||
|
else if (m_name != domainName)
|
||||||
|
throw utils::ParserException(m_context.parser, "Domains do not match (\"" + domainName + "\" and \"" + m_name + "\")");
|
||||||
|
|
||||||
std::cout << "Parsing domain " << m_name << std::endl;
|
std::cout << "Parsing domain " << m_name << std::endl;
|
||||||
|
|
||||||
@ -62,6 +68,13 @@ bool Domain::isDeclared() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Domain::setName(std::string name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const std::string &Domain::name() const
|
const std::string &Domain::name() const
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
@ -334,11 +347,22 @@ void Domain::checkConsistency()
|
|||||||
// Verify that typing requirement is correctly declared if used
|
// Verify that typing requirement is correctly declared if used
|
||||||
if (!m_primitiveTypes.empty() && !hasRequirement(Requirement::Type::Typing))
|
if (!m_primitiveTypes.empty() && !hasRequirement(Requirement::Type::Typing))
|
||||||
{
|
{
|
||||||
throw ConsistencyException("Domain contains typing information but does not declare typing requirement");
|
m_context.logger.parserWarning(m_context.parser, "Domain contains typing information but does not declare typing requirement");
|
||||||
|
|
||||||
m_requirements.push_back(Requirement(Requirement::Type::Typing));
|
m_requirements.push_back(Requirement(Requirement::Type::Typing));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that all variables and constants have types
|
||||||
|
if (hasRequirement(Requirement::Type::Typing))
|
||||||
|
{
|
||||||
|
std::for_each(m_constants.cbegin(), m_constants.cend(),
|
||||||
|
[&](const auto &constant)
|
||||||
|
{
|
||||||
|
if (constant->type() == nullptr)
|
||||||
|
throw ConsistencyException("Constant \"" + constant->name() + "\" has no type");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Verify that all used types have been declared
|
// Verify that all used types have been declared
|
||||||
std::for_each(m_primitiveTypes.cbegin(), m_primitiveTypes.cend(),
|
std::for_each(m_primitiveTypes.cbegin(), m_primitiveTypes.cend(),
|
||||||
[&](const auto &type)
|
[&](const auto &type)
|
||||||
@ -366,7 +390,6 @@ void Domain::checkConsistency()
|
|||||||
throw ConsistencyException("Predicate \"" + predicate->name() + "\" used but never declared");
|
throw ConsistencyException("Predicate \"" + predicate->name() + "\" used but never declared");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Verify that all variables have types
|
|
||||||
// Verify that constants are unique
|
// Verify that constants are unique
|
||||||
// Verify that all primitive types are unique
|
// Verify that all primitive types are unique
|
||||||
// Check for case-sensitivity issues
|
// Check for case-sensitivity issues
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Domain.h>
|
||||||
#include <plasp/pddl/Identifier.h>
|
#include <plasp/pddl/Identifier.h>
|
||||||
#include <plasp/pddl/expressions/Constant.h>
|
#include <plasp/pddl/expressions/Constant.h>
|
||||||
#include <plasp/utils/IO.h>
|
#include <plasp/utils/IO.h>
|
||||||
@ -134,7 +135,7 @@ void Problem::parseSection()
|
|||||||
|
|
||||||
// TODO: check order of the sections
|
// TODO: check order of the sections
|
||||||
if (sectionIdentifier == "domain")
|
if (sectionIdentifier == "domain")
|
||||||
skipSection();
|
parseDomainSection();
|
||||||
else if (sectionIdentifier == "requirements")
|
else if (sectionIdentifier == "requirements")
|
||||||
parseRequirementSection();
|
parseRequirementSection();
|
||||||
else if (sectionIdentifier == "objects")
|
else if (sectionIdentifier == "objects")
|
||||||
@ -155,6 +156,23 @@ void Problem::parseSection()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::parseDomainSection()
|
||||||
|
{
|
||||||
|
m_context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
const auto domainName = m_context.parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
if (m_domain.isDeclared() && m_domain.name() != domainName)
|
||||||
|
throw utils::ParserException(m_context.parser, "Domains do not match (\"" + m_domain.name() + "\" and \"" + domainName + "\")");
|
||||||
|
|
||||||
|
if (!m_domain.isDeclared())
|
||||||
|
m_domain.setName(domainName);
|
||||||
|
|
||||||
|
m_context.parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Problem::parseRequirementSection()
|
void Problem::parseRequirementSection()
|
||||||
{
|
{
|
||||||
m_context.parser.skipWhiteSpace();
|
m_context.parser.skipWhiteSpace();
|
||||||
@ -238,7 +256,7 @@ void Problem::parseObjectSection()
|
|||||||
// Store constants
|
// Store constants
|
||||||
while (m_context.parser.currentCharacter() != ')')
|
while (m_context.parser.currentCharacter() != ')')
|
||||||
{
|
{
|
||||||
//expressions::Constant::parseTypedDeclaration(m_context);
|
expressions::Constant::parseTypedDeclaration(m_context, *this);
|
||||||
|
|
||||||
m_context.parser.skipWhiteSpace();
|
m_context.parser.skipWhiteSpace();
|
||||||
}
|
}
|
||||||
@ -250,6 +268,14 @@ void Problem::parseObjectSection()
|
|||||||
|
|
||||||
void Problem::checkConsistency()
|
void Problem::checkConsistency()
|
||||||
{
|
{
|
||||||
|
// Verify that all objects have types
|
||||||
|
if (hasRequirement(Requirement::Type::Typing) || m_domain.hasRequirement(Requirement::Type::Typing))
|
||||||
|
std::for_each(m_objects.cbegin(), m_objects.cend(),
|
||||||
|
[&](const auto &constant)
|
||||||
|
{
|
||||||
|
if (constant->type() == nullptr)
|
||||||
|
throw ConsistencyException("Object \"" + constant->name() + "\" has no type");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -61,11 +61,13 @@ void PrimitiveType::parseDeclaration(Context &context, Domain &domain)
|
|||||||
auto *type = match->get();
|
auto *type = match->get();
|
||||||
|
|
||||||
type->setDirty();
|
type->setDirty();
|
||||||
|
type->setDeclared();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
types.emplace_back(std::make_unique<PrimitiveType>(typeName));
|
types.emplace_back(std::make_unique<PrimitiveType>(typeName));
|
||||||
|
types.back()->setDeclared();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -77,11 +79,6 @@ void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain)
|
|||||||
// Parse and store type
|
// Parse and store type
|
||||||
parseDeclaration(context, domain);
|
parseDeclaration(context, domain);
|
||||||
|
|
||||||
auto *type = types.back().get();
|
|
||||||
|
|
||||||
// Flag type as correctly declared in the types section
|
|
||||||
type->setDeclared();
|
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
// Check for type inheritance
|
// Check for type inheritance
|
||||||
@ -129,12 +126,8 @@ PrimitiveType *PrimitiveType::parseAndFindOrCreate(Context &context, Domain &dom
|
|||||||
|
|
||||||
if (match == types.cend())
|
if (match == types.cend())
|
||||||
{
|
{
|
||||||
// Primitive type "object" is implicitly declared
|
// If necessary, insert new primitive type but don't declare it
|
||||||
if (typeName != "object")
|
|
||||||
context.logger.parserWarning(context.parser, "Primitive type \"" + typeName + "\" used but never declared");
|
|
||||||
|
|
||||||
types.emplace_back(std::make_unique<expressions::PrimitiveType>(typeName));
|
types.emplace_back(std::make_unique<expressions::PrimitiveType>(typeName));
|
||||||
types.back()->setDeclared();
|
|
||||||
|
|
||||||
return types.back().get();
|
return types.back().get();
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ void Logger::parserWarning(const Parser &parser, const std::string &text)
|
|||||||
if (m_isPedantic)
|
if (m_isPedantic)
|
||||||
throw ParserWarning(parser, text);
|
throw ParserWarning(parser, text);
|
||||||
|
|
||||||
std::cerr << "Warning: " << parser.row() << ":" << parser.column() << "\t" << text << std::endl;
|
std::cerr << "Warning: " << parser.fileName() << ":" << parser.row() << ":" << parser.column() << " " << text << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -27,14 +27,36 @@ Parser::Parser(std::istream &istream)
|
|||||||
m_row{1},
|
m_row{1},
|
||||||
m_column{1},
|
m_column{1},
|
||||||
m_isCaseSensitive{true},
|
m_isCaseSensitive{true},
|
||||||
m_endOfFile{false}
|
m_atEndOfFile{false}
|
||||||
{
|
{
|
||||||
std::setlocale(LC_NUMERIC, "C");
|
std::setlocale(LC_NUMERIC, "C");
|
||||||
|
|
||||||
// Don’t skip whitespace
|
// Don’t skip whitespace
|
||||||
istream.exceptions(std::istream::badbit);
|
istream.exceptions(std::istream::badbit);
|
||||||
|
}
|
||||||
|
|
||||||
checkStream();
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::setFileName(std::string fileName)
|
||||||
|
{
|
||||||
|
m_fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string &Parser::fileName() const
|
||||||
|
{
|
||||||
|
return m_fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Parser::resetPosition()
|
||||||
|
{
|
||||||
|
m_row = 1;
|
||||||
|
m_column = 1;
|
||||||
|
m_atEndOfFile = false;
|
||||||
|
m_position = std::istreambuf_iterator<char>(m_istream);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Reference in New Issue
Block a user