summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/parser/stack/DocumentHandler.cpp18
-rw-r--r--src/core/parser/stack/DocumentHandler.hpp4
-rw-r--r--src/core/parser/stack/Handler.hpp3
-rw-r--r--src/core/parser/stack/Stack.cpp123
-rw-r--r--src/core/parser/stack/Stack.hpp14
5 files changed, 106 insertions, 56 deletions
diff --git a/src/core/parser/stack/DocumentHandler.cpp b/src/core/parser/stack/DocumentHandler.cpp
index d44176a..714ab1b 100644
--- a/src/core/parser/stack/DocumentHandler.cpp
+++ b/src/core/parser/stack/DocumentHandler.cpp
@@ -246,8 +246,6 @@ bool DocumentChildHandler::start(Variant::mapType &args)
parent->getDescriptor()->getFieldDescriptorIndex();
}
// create the entity for the new element at last.
- // TODO: REMOVE
- strct_name = strct->getName();
entity = parent->createChildStructuredEntity(strct, lastFieldIdx,
args, nameAttr);
}
@@ -373,15 +371,8 @@ bool DocumentChildHandler::convertData(Handle<FieldDescriptor> field,
return valid && scope().resolveValue(data, type, logger);
}
-bool DocumentChildHandler::data(TokenizedData &data)
+bool DocumentChildHandler::data()
{
- // TODO: Handle this correctly
- Variant text = data.text(WhitespaceMode::TRIM);
- if (text == nullptr) {
- // For now, except "no data" as success
- return true;
- }
-
// We're past the region in which explicit fields can be defined in the
// parent structure element
scope().setFlag(ParserFlag::POST_EXPLICIT_FIELDS, true);
@@ -401,6 +392,7 @@ bool DocumentChildHandler::data(TokenizedData &data)
// If it is a primitive field directly, try to parse the content.
if (field->isPrimitive()) {
// Add it as primitive content.
+ Variant text = readData();
if (!convertData(field, text, logger())) {
return false;
}
@@ -419,6 +411,10 @@ bool DocumentChildHandler::data(TokenizedData &data)
for (auto primitiveField : defaultFields) {
// Then try to parse the content using the type specification.
forks.emplace_back(logger().fork());
+
+ // TODO: Actually the data has to be read after the path has been
+ // created (as createPath may push more tokens onto the stack)
+ Variant text = readData();
if (!convertData(primitiveField, text, forks.back())) {
continue;
}
@@ -428,7 +424,6 @@ bool DocumentChildHandler::data(TokenizedData &data)
// Construct the necessary path
NodeVector<Node> path = field->pathTo(primitiveField, logger());
- // TODO: Create methods with indices instead of names.
createPath(fieldIdx, path, parent);
// Then create the primitive element
@@ -439,6 +434,7 @@ bool DocumentChildHandler::data(TokenizedData &data)
// No field was found that might take the data -- dump the error messages
// from the loggers -- or, if there were no primitive fields, clearly state
// this fact
+ Variant text = readData();
if (defaultFields.empty()) {
logger().error("Got data, but structure \"" + name() +
"\" does not have any primitive field",
diff --git a/src/core/parser/stack/DocumentHandler.hpp b/src/core/parser/stack/DocumentHandler.hpp
index dda7d8b..c51c188 100644
--- a/src/core/parser/stack/DocumentHandler.hpp
+++ b/src/core/parser/stack/DocumentHandler.hpp
@@ -93,8 +93,6 @@ public:
class DocumentChildHandler : public Handler {
private:
bool isExplicitField = false;
- //TODO: REMOVE
- std::string strct_name;
/**
* Code shared by both the start(), fieldStart() and the data() method.
@@ -167,7 +165,7 @@ public:
bool start(Variant::mapType &args) override;
void end() override;
- bool data(TokenizedData &data) override;
+ bool data() override;
bool fieldStart(bool &isDefault, size_t fieldIdx) override;
diff --git a/src/core/parser/stack/Handler.hpp b/src/core/parser/stack/Handler.hpp
index 848d395..377a214 100644
--- a/src/core/parser/stack/Handler.hpp
+++ b/src/core/parser/stack/Handler.hpp
@@ -24,6 +24,7 @@
#include <core/common/Location.hpp>
#include <core/common/Variant.hpp>
#include <core/common/Whitespace.hpp>
+#include <core/common/Token.hpp>
namespace ousia {
@@ -37,7 +38,7 @@ class Variant;
namespace parser_stack {
// More forward declarations
-class Callbacks;
+class HandlerCallbacks;
class State;
/**
diff --git a/src/core/parser/stack/Stack.cpp b/src/core/parser/stack/Stack.cpp
index 292e7e2..ff03a6b 100644
--- a/src/core/parser/stack/Stack.cpp
+++ b/src/core/parser/stack/Stack.cpp
@@ -210,7 +210,6 @@ static LoggableException buildInvalidCommandException(
/* Class StackImpl */
class StackImpl {
-
private:
/**
* Reference at the parser context.
@@ -231,7 +230,7 @@ private:
/**
* Return the reference in the Logger instance stored within the context.
*/
- Logger &logger();
+ Logger &logger() {return ctx.getLogger();}
/**
* Used internally to get all expected command names for the current state.
@@ -311,12 +310,28 @@ private:
* @return true if all handlers on the stack are valid.
*/
bool handlersValid();
-};
+public:
+ StackImpl(ParserContext &ctx,
+ const std::multimap<std::string, const State *> &states);
+
+ ~StackImpl();
-/* Class Stack */
+ const State &currentState() const;
+ std::string currentCommandName() const;
-Stack::Stack(ParserContext &ctx,
+ void commandStart(const Variant &name, const Variant::mapType &args,
+ bool range);
+ void annotationStart(const Variant &className, const Variant &args,
+ bool range);
+ void annotationEnd(const Variant &className, const Variant &elementName);
+ void rangeEnd();
+ void fieldStart(bool isDefault);
+ void fieldEnd();
+ void data(const TokenizedData &data);
+};
+
+StackImpl::StackImpl(ParserContext &ctx,
const std::multimap<std::string, const State *> &states)
: ctx(ctx), states(states)
{
@@ -327,7 +342,7 @@ Stack::Stack(ParserContext &ctx,
}
}
-Stack::~Stack()
+StackImpl::~StackImpl()
{
while (!stack.empty()) {
// Fetch the topmost stack element
@@ -351,7 +366,7 @@ Stack::~Stack()
}
}
-void Stack::deduceState()
+void StackImpl::deduceState()
{
// Assemble all states
std::vector<const State *> states;
@@ -384,7 +399,7 @@ void Stack::deduceState()
info.fieldStart(true, false, true);
}
-std::set<std::string> Stack::expectedCommands()
+std::set<std::string> StackImpl::expectedCommands()
{
const State *currentState = &(this->currentState());
std::set<std::string> res;
@@ -396,17 +411,17 @@ std::set<std::string> Stack::expectedCommands()
return res;
}
-const State &Stack::currentState()
+const State &StackImpl::currentState()
{
return stack.empty() ? States::None : stack.back().handler->getState();
}
-std::string Stack::currentCommandName()
+std::string StackImpl::currentCommandName()
{
return stack.empty() ? std::string{} : stack.back().handler->getName();
}
-const State *Stack::findTargetState(const std::string &name)
+const State *StackImpl::findTargetState(const std::string &name)
{
const State *currentState = &(this->currentState());
auto range = states.equal_range(name);
@@ -420,7 +435,7 @@ const State *Stack::findTargetState(const std::string &name)
return nullptr;
}
-const State *Stack::findTargetStateOrWildcard(const std::string &name)
+const State *StackImpl::findTargetStateOrWildcard(const std::string &name)
{
// Try to find the target state with the given name, if none is found, try
// find a matching "*" state.
@@ -431,16 +446,16 @@ const State *Stack::findTargetStateOrWildcard(const std::string &name)
return targetState;
}
-HandlerInfo &Stack::currentInfo()
+HandlerInfo &StackImpl::currentInfo()
{
return stack.empty() ? EmptyHandlerInfo : stack.back();
}
-HandlerInfo &Stack::lastInfo()
+HandlerInfo &StackImpl::lastInfo()
{
return stack.size() < 2U ? EmptyHandlerInfo : stack[stack.size() - 2];
}
-void Stack::endCurrentHandler()
+void StackImpl::endCurrentHandler()
{
if (!stack.empty()) {
// Fetch the handler info for the current top-level element
@@ -467,7 +482,7 @@ void Stack::endCurrentHandler()
}
}
-void Stack::endOverdueHandlers()
+void StackImpl::endOverdueHandlers()
{
if (!stack.empty()) {
// Fetch the handler info for the current top-level element
@@ -483,7 +498,7 @@ void Stack::endOverdueHandlers()
}
}
-bool Stack::ensureHandlerIsInField()
+bool StackImpl::ensureHandlerIsInField()
{
// If the current handler is not in a field (and actually has a handler)
// try to start a default field
@@ -507,7 +522,7 @@ bool Stack::ensureHandlerIsInField()
return true;
}
-bool Stack::handlersValid()
+bool StackImpl::handlersValid()
{
for (auto it = stack.crbegin(); it != stack.crend(); it++) {
if (!it->valid) {
@@ -517,9 +532,7 @@ bool Stack::handlersValid()
return true;
}
-Logger &Stack::logger() { return ctx.getLogger(); }
-
-void Stack::command(const Variant &name, const Variant::mapType &args)
+void StackImpl::commandStart(const Variant &name, const Variant::mapType &args)
{
// End handlers that already had a default field and are currently not
// active.
@@ -611,7 +624,22 @@ void Stack::command(const Variant &name, const Variant::mapType &args)
}
}
-void Stack::data(TokenizedData data)
+void StackImpl::annotationStart(const Variant &className, const Variant &args)
+{
+ // TODO
+}
+
+void StackImpl::annotationEnd(const Variant &className, const Variant &elementName)
+{
+ // TODO
+}
+
+void StackImpl::rangeEnd()
+{
+ // TODO
+}
+
+void StackImpl::data(TokenizedData data)
{
// TODO: Rewrite this function for token handling
// TODO: This loop needs to be refactored out
@@ -626,7 +654,8 @@ void Stack::data(TokenizedData data)
// make sure the data actually is data
if (stack.empty()) {
if (hasNonWhitespaceText) {
- throw LoggableException("No command here to receive data.", data);
+ throw LoggableException("No command here to receive data.",
+ data);
}
return;
}
@@ -699,7 +728,7 @@ void Stack::data(TokenizedData data)
}
}
-void Stack::data(const Variant &stringData)
+void StackImpl::data(const Variant &stringData)
{
// Fetch the SourceLocation of the given stringData variant
SourceLocation loc = stringData.getLocation();
@@ -712,7 +741,7 @@ void Stack::data(const Variant &stringData)
data(tokenizedData);
}
-void Stack::fieldStart(bool isDefault)
+void StackImpl::fieldStart(bool isDefault)
{
// Make sure the current handler stack is not empty
if (stack.empty()) {
@@ -764,7 +793,7 @@ void Stack::fieldStart(bool isDefault)
info.fieldStart(defaultField, false, valid);
}
-void Stack::fieldEnd()
+void StackImpl::fieldEnd()
{
// Unroll the stack until the next explicitly open field
while (!stack.empty()) {
@@ -799,14 +828,50 @@ void Stack::fieldEnd()
info.fieldEnd();
}
-void Stack::annotationStart(const Variant &className, const Variant &args)
+/* Class Stack */
+
+Stack::Stack(ParserContext &ctx,
+ const std::multimap<std::string, const State *> &states)
+ : impl(new StackImpl(ctx, states))
+{
+}
+
+Stack::~Stack()
{
- // TODO
+ // Do nothing here, stub needed because StackImpl is incomplete in hpp
+}
+
+const State &Stack::currentState() const { return impl->currentState(); }
+
+std::string Stack::currentCommandName() const
+{
+ return impl->currentCommandName();
+}
+
+void Stack::commandStart(const Variant &name, const Variant::mapType &args,
+ bool range)
+{
+ impl->commandStart(name, args, range);
+}
+
+void Stack::annotationStart(const Variant &className, const Variant &args,
+ bool range)
+{
+ impl->annotationStart(className, args, range);
}
void Stack::annotationEnd(const Variant &className, const Variant &elementName)
{
- // TODO
+ impl->annotationEnd(className, elementName);
}
+
+void Stack::rangeEnd() { impl->rangeEnd(); }
+
+void Stack::fieldStart(bool isDefault) { impl->fieldStart(isDefault); }
+
+void Stack::fieldEnd() { impl->fieldEnd(); }
+
+void Stack::data(const TokenizedData &data) { impl->data(data); }
+};
}
}
diff --git a/src/core/parser/stack/Stack.hpp b/src/core/parser/stack/Stack.hpp
index e1173d0..1d87b9c 100644
--- a/src/core/parser/stack/Stack.hpp
+++ b/src/core/parser/stack/Stack.hpp
@@ -81,7 +81,7 @@ public:
* @return the state of the currently active Handler instance or
* States::None if no handler is on the stack.
*/
- const State &currentState();
+ const State &currentState() const;
/**
* Returns the command name that is currently being handled.
@@ -89,7 +89,7 @@ public:
* @return the name of the command currently being handled by the active
* Handler instance or an empty string if no handler is currently active.
*/
- std::string currentCommandName();
+ std::string currentCommandName() const;
/**
* Function that should be called whenever a new command is reached.
@@ -154,16 +154,6 @@ public:
* that should be read.
*/
void data(const TokenizedData &data);
-
- /**
- * Function that shuold be called whenever character data is found in the
- * input stream. The given string variant is converted into a TokenizedData
- * instance internally.
- *
- * @param stringData is a string variant containing the data that has been
- * found.
- */
- void data(const Variant &stringData);
};
}
}