summaryrefslogtreecommitdiff
path: root/src/core/parser/ParserStack.cpp
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-02-06 16:40:42 +0100
committerAndreas Stöckel <andreas@somweyr.de>2015-02-06 16:40:42 +0100
commitb211c02c53f3ed38c7d124d6a74f22ee17df7063 (patch)
tree0fcea811a809f45cdf72d1c12fa00899c431a9be /src/core/parser/ParserStack.cpp
parentae6ce2bc21cedf56f9fb445c3f1f7bc62b78de5f (diff)
Removed childHandler, added "*" notation
Diffstat (limited to 'src/core/parser/ParserStack.cpp')
-rw-r--r--src/core/parser/ParserStack.cpp49
1 files changed, 27 insertions, 22 deletions
diff --git a/src/core/parser/ParserStack.cpp b/src/core/parser/ParserStack.cpp
index 50a97c9..0ab7a8e 100644
--- a/src/core/parser/ParserStack.cpp
+++ b/src/core/parser/ParserStack.cpp
@@ -113,11 +113,12 @@ bool ParserStack::deduceState()
return true;
}
-std::set<std::string> ParserStack::expectedCommands(const ParserState &state)
+std::set<std::string> ParserStack::expectedCommands()
{
+ const ParserState *currentState = &(this->currentState());
std::set<std::string> res;
for (const auto &v : states) {
- if (v.second->parents.count(&state)) {
+ if (v.second->parents.count(currentState)) {
res.insert(v.first);
}
}
@@ -134,42 +135,46 @@ std::string ParserStack::currentCommandName()
return stack.empty() ? std::string{} : stack.top()->name();
}
-void ParserStack::start(std::string name, Variant::mapType &args,
- const SourceLocation &location)
+const ParserState *ParserStack::findTargetState(const std::string &name)
{
- // Fetch the current handler and the current state
- ParserState const *currentState = &(this->currentState());
-
- // Fetch the correct Handler descriptor for this
- ParserState const *targetState = nullptr;
- HandlerConstructor ctor = nullptr;
+ const ParserState *currentState = &(this->currentState());
auto range = states.equal_range(name);
for (auto it = range.first; it != range.second; it++) {
const ParserStateSet &parents = it->second->parents;
if (parents.count(currentState) || parents.count(&ParserStates::All)) {
- targetState = it->second;
- ctor = targetState->elementHandler ? targetState->elementHandler
- : DefaultHandler::create;
- break;
+ return it->second;
}
}
- // Try to use the child handler if one was given
- if (!targetState && currentState->childHandler) {
- targetState = currentState;
- ctor = targetState->childHandler;
+ return nullptr;
+}
+
+void ParserStack::start(const std::string &name, Variant::mapType &args,
+ const SourceLocation &location)
+{
+ ParserState const *targetState = findTargetState(name);
+ if (!Utils::isIdentifier(name)) {
+ throw LoggableException(std::string("Invalid identifier \"") + name +
+ std::string("\""));
}
- // No descriptor found, throw an exception.
- if (!targetState || !ctor) {
- throw InvalidCommand(name, expectedCommands(*currentState));
+ if (targetState == nullptr) {
+ targetState = findTargetState("*");
}
+ if (targetState == nullptr) {
+ throw InvalidCommand(name, expectedCommands());
+ }
+
+ // Fetch the associated constructor
+ HandlerConstructor ctor = targetState->elementHandler
+ ? targetState->elementHandler
+ : DefaultHandler::create;
// Canonicalize the arguments, allow additional arguments
targetState->arguments.validateMap(args, ctx.getLogger(), true);
// Instantiate the handler and call its start function
- Handler *handler = ctor({ctx, name, *targetState, *currentState, location});
+ Handler *handler = ctor({ctx, name, *targetState, currentState(), location});
handler->start(args);
stack.emplace(handler);
}