summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-02-03 15:22:25 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-02-03 15:22:25 +0100
commit3d1acdea884ce748be20c1fafb8ec15510235f57 (patch)
treed4d6eb9c7e11bffe7e55e788b4414a1138334ad9 /src/core
parent75513b55ad721990ae53f9c2c2638c4bb5ef000a (diff)
Implemented storing SourceLocation of parsed Variants
Diffstat (limited to 'src/core')
-rw-r--r--src/core/common/VariantReader.cpp81
-rw-r--r--src/core/common/VariantReader.hpp9
2 files changed, 65 insertions, 25 deletions
diff --git a/src/core/common/VariantReader.cpp b/src/core/common/VariantReader.cpp
index 7403b4a..ef71740 100644
--- a/src/core/common/VariantReader.cpp
+++ b/src/core/common/VariantReader.cpp
@@ -674,6 +674,12 @@ std::pair<bool, Variant> VariantReader::parseGeneric(
char c;
bool hadError = false;
+ // Skip all peeked characters
+ reader.consumePeek();
+
+ // Read the start offset
+ const SourceOffset start = reader.getOffset();
+
// Parse generic tokens until the end of the stream or the delimiter is
// reached
while (reader.peek(c) && !delims.count(c)) {
@@ -694,7 +700,9 @@ std::pair<bool, Variant> VariantReader::parseGeneric(
if (arr.size() == 1) {
return std::make_pair(!hadError, arr[0]);
} else {
- return std::make_pair(!hadError, Variant{arr});
+ Variant res{arr};
+ res.setLocation({reader.getSourceId(), start, reader.getOffset()});
+ return std::make_pair(!hadError, res);
}
}
@@ -712,10 +720,15 @@ std::pair<bool, Variant> VariantReader::parseGenericToken(
}
reader.resetPeek();
+ // Fetch the start offset
+ const SourceOffset start = reader.getOffset();
+
// Parse a string if a quote is reached
if (c == '"' || c == '\'') {
auto res = parseString(reader, logger);
- return std::make_pair(res.first, res.second.c_str());
+ Variant v = Variant::fromString(res.second);
+ v.setLocation({reader.getSourceId(), start, reader.getOffset()});
+ return std::make_pair(res.first, v);
}
// Try to parse everything that looks like a number as number
@@ -727,12 +740,15 @@ std::pair<bool, Variant> VariantReader::parseGenericToken(
if (n.parse(readerFork, loggerFork, delims)) {
readerFork.commit();
loggerFork.commit();
+
+ Variant v;
if (n.isInt()) {
- return std::make_pair(
- true, Variant{static_cast<Variant::intType>(n.intValue())});
+ v = Variant{static_cast<Variant::intType>(n.intValue())};
} else {
- return std::make_pair(true, n.doubleValue());
+ v = Variant{n.doubleValue()};
}
+ v.setLocation({reader.getSourceId(), start, reader.getOffset()});
+ return std::make_pair(true, v);
}
reader.resetPeek();
}
@@ -745,14 +761,19 @@ std::pair<bool, Variant> VariantReader::parseGenericToken(
if (res.first) {
readerFork.commit();
loggerFork.commit();
- return std::make_pair(true, Variant{res.second});
+ Variant v{res.second};
+ v.setLocation({reader.getSourceId(), start, reader.getOffset()});
+ return std::make_pair(true, v);
}
reader.resetPeek();
}
// Try to parse an object
if (c == '[') {
- return parseComplex(reader, logger, 0, ComplexMode::BOTH);
+ auto res = parseComplex(reader, logger, 0, ComplexMode::BOTH);
+ res.second.setLocation(
+ {reader.getSourceId(), start, reader.getOffset()});
+ return res;
}
// Otherwise parse a single token
@@ -764,41 +785,55 @@ std::pair<bool, Variant> VariantReader::parseGenericToken(
}
// Handling for special primitive values
+ bool isSpecial = false;
+ Variant v;
if (res.first) {
if (res.second == "true") {
- return std::make_pair(true, Variant{true});
- }
- if (res.second == "false") {
- return std::make_pair(true, Variant{false});
- }
- if (res.second == "null") {
- return std::make_pair(true, Variant{nullptr});
+ v = Variant{true};
+ isSpecial = true;
+ } else if (res.second == "false") {
+ v = Variant{false};
+ isSpecial = true;
+ } else if (res.second == "null") {
+ v = Variant{nullptr};
+ isSpecial = true;
}
}
// Check whether the parsed string is a valid identifier -- if yes, flag it
// as "magic" string
- if (Utils::isIdentifier(res.second)) {
- Variant v;
- v.setMagic(res.second.c_str());
- return std::make_pair(res.first, v);
- } else {
- return std::make_pair(res.first, Variant::fromString(res.second));
+ if (!isSpecial) {
+ if (Utils::isIdentifier(res.second)) {
+ v.setMagic(res.second.c_str());
+ } else {
+ v = Variant::fromString(res.second);
+ }
}
+ v.setLocation({reader.getSourceId(), start, reader.getOffset()});
+ return std::make_pair(res.first, v);
}
std::pair<bool, Variant> VariantReader::parseGenericString(
- const std::string &str, Logger &logger)
+ const std::string &str, Logger &logger, SourceId sourceId, size_t offs)
{
- CharReader reader{str};
+ CharReader reader{str, sourceId, offs};
LoggerFork loggerFork = logger.fork();
+
+ // Try to parse a single token
std::pair<bool, Variant> res =
parseGenericToken(reader, loggerFork, std::unordered_set<char>{}, true);
+
+ // If the string was actually consisted of a single token, return that token
if (reader.atEnd()) {
loggerFork.commit();
return res;
}
- return std::make_pair(true, Variant::fromString(str));
+
+ // Otherwise return the given string as a string, set the location of the
+ // string correctly
+ Variant v = Variant::fromString(str);
+ v.setLocation({sourceId, offs, offs + str.size()});
+ return std::make_pair(true, v);
}
}
diff --git a/src/core/common/VariantReader.hpp b/src/core/common/VariantReader.hpp
index d939415..7f00251 100644
--- a/src/core/common/VariantReader.hpp
+++ b/src/core/common/VariantReader.hpp
@@ -277,6 +277,10 @@ public:
* @param str is the string from which the value should be read.
* @param logger is the logger instance to which errors or warnings will be
* written.
+ * @param sourceId is an optional descriptor of the source file from which
+ * the element is being read.
+ * @param offs is the by offset in the source file at which the string
+ * starts.
* @return a pair indicating whether the operation was successful and the
* extracted variant value. Note that the variant value most times contains
* some meaningful data that can be worked with even if the operation was
@@ -285,8 +289,9 @@ public:
* variant.) Information on why the operation has failed is passed to the
* logger.
*/
- static std::pair<bool, Variant> parseGenericString(const std::string &str,
- Logger &logger);
+ static std::pair<bool, Variant> parseGenericString(
+ const std::string &str, Logger &logger,
+ SourceId sourceId = InvalidSourceId, size_t offs = 0);
};
}