summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-06 16:52:51 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2015-02-06 16:52:51 +0100
commit7fb170a87a4551a048487361b7aaf29963dc7b99 (patch)
treeb2f532ec8e6aa54f475c0e48b3ef5d39b6ee3b6c /src/core
parent3ceb415e4f81b50b8e46351e9e586794ebf08644 (diff)
parentb211c02c53f3ed38c7d124d6a74f22ee17df7063 (diff)
Merge branch 'master' of somweyr.de:ousia
Conflicts: application/src/plugins/xml/XmlParser.cpp
Diffstat (limited to 'src/core')
-rw-r--r--src/core/parser/ParserStack.cpp49
-rw-r--r--src/core/parser/ParserStack.hpp28
-rw-r--r--src/core/parser/ParserState.cpp15
-rw-r--r--src/core/parser/ParserState.hpp27
4 files changed, 49 insertions, 70 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);
}
diff --git a/src/core/parser/ParserStack.hpp b/src/core/parser/ParserStack.hpp
index 8561d42..efc4e4a 100644
--- a/src/core/parser/ParserStack.hpp
+++ b/src/core/parser/ParserStack.hpp
@@ -86,9 +86,8 @@ struct HandlerData {
* @param parentState is the state of the parent command.
* @param location is the location at which the handler is created.
*/
- HandlerData(ParserContext &ctx, std::string name,
- const ParserState &state, const ParserState &parentState,
- const SourceLocation location)
+ HandlerData(ParserContext &ctx, std::string name, const ParserState &state,
+ const ParserState &parentState, const SourceLocation location)
: ctx(ctx),
name(std::move(name)),
state(state),
@@ -250,14 +249,23 @@ private:
std::stack<std::shared_ptr<Handler>> stack;
/**
- * Used internally to get all expected command names for the given state
- * (does not work if the current Handler instance allows arbitrary
- * children). This function is used to build error messages.
+ * Used internally to get all expected command names for the current state.
+ * This function is used to build error messages.
*
- * @param state is the state for which all expected command names should be
- * returned.
+ * @return a set of strings containing the names of the expected commands.
*/
- std::set<std::string> expectedCommands(const ParserState &state);
+ std::set<std::string> expectedCommands();
+
+ /**
+ * Returns the targetState for a command with the given name that can be
+ * reached from for the current state.
+ *
+ * @param name is the name of the requested command.
+ * @return nullptr if no target state was found, a pointer at the target
+ *state
+ * otherwise.
+ */
+ const ParserState *findTargetState(const std::string &name);
public:
/**
@@ -309,7 +317,7 @@ public:
* @param location is the location in the source file at which the command
* starts.
*/
- void start(std::string name, Variant::mapType &args,
+ void start(const std::string &name, Variant::mapType &args,
const SourceLocation &location = SourceLocation{});
/**
diff --git a/src/core/parser/ParserState.cpp b/src/core/parser/ParserState.cpp
index 9d3aa7e..f635d86 100644
--- a/src/core/parser/ParserState.cpp
+++ b/src/core/parser/ParserState.cpp
@@ -22,17 +22,15 @@ namespace ousia {
/* Class ParserState */
-ParserState::ParserState() : elementHandler(nullptr), childHandler(nullptr) {}
+ParserState::ParserState() : elementHandler(nullptr) {}
ParserState::ParserState(ParserStateSet parents, Arguments arguments,
RttiSet createdNodeTypes,
- HandlerConstructor elementHandler,
- HandlerConstructor childHandler)
+ HandlerConstructor elementHandler)
: parents(parents),
arguments(arguments),
createdNodeTypes(createdNodeTypes),
- elementHandler(elementHandler),
- childHandler(childHandler)
+ elementHandler(elementHandler)
{
}
@@ -86,13 +84,6 @@ ParserStateBuilder &ParserStateBuilder::elementHandler(
return *this;
}
-ParserStateBuilder &ParserStateBuilder::childHandler(
- HandlerConstructor childHandler)
-{
- state.childHandler = childHandler;
- return *this;
-}
-
const ParserState &ParserStateBuilder::build() const { return state; }
/* Class ParserStateDeductor */
diff --git a/src/core/parser/ParserState.hpp b/src/core/parser/ParserState.hpp
index 43b8035..6487fdd 100644
--- a/src/core/parser/ParserState.hpp
+++ b/src/core/parser/ParserState.hpp
@@ -79,13 +79,6 @@ struct ParserState {
HandlerConstructor elementHandler;
/**
- * Pointer at a function which creates a new concrete Handler instance for
- * all child elements for which no matching state is defined. May be nullptr
- * in which case no such elements are allowed.
- */
- HandlerConstructor childHandler;
-
- /**
* Default constructor, initializes the handlers with nullptr.
*/
ParserState();
@@ -104,15 +97,10 @@ struct ParserState {
* @param elementHandler is a pointer at a function which creates a new
* concrete Handler instance for the elements described by this state. May
* be nullptr in which case no handler instance is created.
- * @param childHandler is a pointer at a function which creates a new
- * concrete Handler instance for all child elements for which no matching
- * state is defined. May be nullptr in which case no such elements are
- * allowed.
*/
ParserState(ParserStateSet parents, Arguments arguments = Arguments{},
RttiSet createdNodeTypes = RttiSet{},
- HandlerConstructor elementHandler = nullptr,
- HandlerConstructor childHandler = nullptr);
+ HandlerConstructor elementHandler = nullptr);
/**
* Creates this ParserState from the given ParserStateBuilder instance.
@@ -209,19 +197,6 @@ public:
ParserStateBuilder &elementHandler(HandlerConstructor elementHandler);
/**
- * Sets the constructor for the child handler. The constructor creates a new
- * concrete Handler instance for all child elements for which no matching
- * state is defined. May be nullptr in which case no such elements are
- * allowed.
- *
- * @param childHandler is the HandlerConstructor that should point at the
- * constructor of the Handler instance for child elements.
- * @return a reference at this ParserStateBuilder instance for method
- * chaining.
- */
- ParserStateBuilder &childHandler(HandlerConstructor childHandler);
-
- /**
* Returns a reference at the internal ParserState instance that was built
* using the ParserStateBuilder.
*