summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2019-12-22 16:21:29 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2019-12-22 16:23:51 +0000
commit8bf34e0c41e5801fabd34ff3a4510b730703f5f5 (patch)
treec8dd00015c773b07e7f0b64edc1d6b979d74b806
parentFix parse error state (diff)
downloadlibjsonpp-0.12.0.tar.bz2
libjsonpp-0.12.0.tar.xz
libjsonpp-0.12.0.zip
Refactor to support extensible lexerlibjsonpp-0.12.0
-rw-r--r--libjsonpp/Jamfile.jam3
-rw-r--r--libjsonpp/json.ll3
-rw-r--r--libjsonpp/jsonFlexLexer.cpp71
-rw-r--r--libjsonpp/jsonFlexLexer.h40
-rw-r--r--libjsonpp/jsonValueFlexLexer.cpp72
-rw-r--r--libjsonpp/jsonValueFlexLexer.h34
-rw-r--r--libjsonpp/jsonpp.cpp14
-rw-r--r--libjsonpp/jsonpp.h23
-rw-r--r--libjsonpp/parse.cpp9
-rw-r--r--libjsonpp/serialize.cpp3
10 files changed, 162 insertions, 110 deletions
diff --git a/libjsonpp/Jamfile.jam b/libjsonpp/Jamfile.jam
index c956b7b..7f607bd 100644
--- a/libjsonpp/Jamfile.jam
+++ b/libjsonpp/Jamfile.jam
@@ -17,7 +17,6 @@ lib jsonpp :
:
<include>.
<library>..//glibmm
- <define>yyFlexLexer=jsonBaseFlexLexer
: :
<include>.
;
@@ -58,5 +57,5 @@ run
testEncoding
;
-package.install install : <install-source-root>. : : jsonpp : [ glob *.h : jsonFlexLexer.h ] ;
+package.install install : <install-source-root>. : : jsonpp : [ glob *.h : jsonValueFlexLexer.h ] ;
diff --git a/libjsonpp/json.ll b/libjsonpp/json.ll
index 391556d..12e46a9 100644
--- a/libjsonpp/json.ll
+++ b/libjsonpp/json.ll
@@ -8,6 +8,7 @@
%option prefix="jsonBase"
%{
+#include <glibmm/ustring.h>
#include "jsonFlexLexer.h"
#pragma GCC diagnostic ignored "-Wsign-compare"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
@@ -86,7 +87,7 @@ text [^\\\"]*
yy_pop_state();
break;
case OBJECT_ITEM:
- name = encodeBuf();
+ PushKey(encodeBuf());
BEGIN(COLON);
break;
}
diff --git a/libjsonpp/jsonFlexLexer.cpp b/libjsonpp/jsonFlexLexer.cpp
index 0964c1c..df29d8f 100644
--- a/libjsonpp/jsonFlexLexer.cpp
+++ b/libjsonpp/jsonFlexLexer.cpp
@@ -1,87 +1,32 @@
-#include "jsonFlexLexer.h"
+#include "jsonValueFlexLexer.h"
#include <glibmm/convert.h>
namespace json {
- const std::string UTF8 { "utf-8" };
-
- jsonFlexLexer::jsonFlexLexer(std::istream & in, std::string enc, Value & v) :
+ jsonFlexLexer::jsonFlexLexer(std::istream & in, std::string enc) :
yyFlexLexer(&in, nullptr),
- encoding(enc != UTF8 ? std::move(enc) : std::string())
+ encoding(enc != utf8 ? std::move(enc) : std::string())
{
yy_push_state(0);
- acceptValues.push([&v](auto && value) {
- v = std::forward<Value>(value);
- return &v;
- });
}
std::string
jsonFlexLexer::encodeBuf() const
{
if (!encoding.empty()) {
- return Glib::convert(buf, UTF8, encoding);
+ return Glib::convert(buf, utf8, encoding);
}
return buf;
}
void
- jsonFlexLexer::BeginObject()
- {
- auto object = std::get_if<Object>(acceptValues.top()(Object()));
- acceptValues.push([object,this](auto && value) {
- return &object->emplace(std::move(name), std::forward<Value>(value)).first->second;
- });
- }
-
- void
- jsonFlexLexer::BeginArray()
- {
- auto array = std::get_if<Array>(acceptValues.top()(Array()));
- acceptValues.push([array](auto && value) {
- return &array->emplace_back(std::forward<Value>(value));
- });
- }
-
- void
- jsonFlexLexer::PushNull()
- {
- acceptValues.top()(Null());
- }
-
- void
- jsonFlexLexer::PushBoolean(bool value)
- {
- acceptValues.top()(value);
- }
-
- void
- jsonFlexLexer::PushNumber(double value)
- {
- acceptValues.top()(value);
- }
-
- void
- jsonFlexLexer::PushText(std::string && value)
- {
- acceptValues.top()(std::move(value));
- }
-
- void
- jsonFlexLexer::EndArray()
- {
- acceptValues.pop();
- }
-
- void
- jsonFlexLexer::EndObject()
+ jsonFlexLexer::LexerError(const char * msg)
{
- acceptValues.pop();
+ throw ParseError(msg, 0, 0);
}
- void
- jsonFlexLexer::LexerError(const char * msg)
+ ParseError::ParseError(const char * at, int l, int s) :
+ std::invalid_argument(Glib::ustring::compose("Parse error at or near %1 (line %2, state %3)", at, l, s))
{
- throw ParseError(msg, 0, 0);
}
}
diff --git a/libjsonpp/jsonFlexLexer.h b/libjsonpp/jsonFlexLexer.h
index 43770d5..bbd6b95 100644
--- a/libjsonpp/jsonFlexLexer.h
+++ b/libjsonpp/jsonFlexLexer.h
@@ -2,41 +2,45 @@
#define JSONFLEXLEXER_H
#include <string>
-#include "jsonpp.h"
-#include <stack>
-#include <functional>
+#include <stdexcept>
#ifndef FLEX_SCANNER
+#define yyFlexLexer jsonBaseFlexLexer
#include <FlexLexer.h>
#endif
namespace json {
+#pragma GCC visibility push(default)
+ class ParseError : public std::invalid_argument {
+ public:
+ ParseError(const char *, int, int);
+ };
+
class jsonFlexLexer : public yyFlexLexer {
public:
- jsonFlexLexer(std::istream &, std::string enc, Value & v);
+ jsonFlexLexer(std::istream &, std::string enc);
int yylex() override;
- void LexerError(const char * msg) override;
- void BeginObject();
- void BeginArray();
+ private:
+ virtual void BeginObject() = 0;
+ virtual void BeginArray() = 0;
- void PushBoolean(bool);
- void PushNumber(double);
- void PushNull();
- void PushText(std::string &&);
+ virtual void PushBoolean(bool) = 0;
+ virtual void PushNumber(double) = 0;
+ virtual void PushNull() = 0;
+ virtual void PushText(std::string &&) = 0;
+ virtual void PushKey(std::string &&) = 0;
- void EndArray();
- void EndObject();
+ virtual void EndArray() = 0;
+ virtual void EndObject() = 0;
- private:
+ void LexerError(const char * msg) override;
std::string encodeBuf() const;
- std::string buf, name;
+ std::string buf;
const std::string encoding;
-
- using AcceptValue = std::function<Value *(Value &&)>;
- std::stack<AcceptValue> acceptValues;
};
+#pragma GCC visibility pop
}
#endif
diff --git a/libjsonpp/jsonValueFlexLexer.cpp b/libjsonpp/jsonValueFlexLexer.cpp
new file mode 100644
index 0000000..5225c95
--- /dev/null
+++ b/libjsonpp/jsonValueFlexLexer.cpp
@@ -0,0 +1,72 @@
+#include "jsonValueFlexLexer.h"
+
+namespace json {
+ jsonValueFlexLexer::jsonValueFlexLexer(std::istream & in, std::string enc, Value & v) :
+ jsonFlexLexer(in, std::move(enc))
+ {
+ acceptValues.push([&v](auto && value) {
+ return &(v = std::forward<Value>(value));
+ });
+ }
+
+ void
+ jsonValueFlexLexer::BeginObject()
+ {
+ auto object = std::get_if<Object>(acceptValues.top()(Object()));
+ acceptValues.push([object,this](auto && value) {
+ return &object->emplace(std::move(name), std::forward<Value>(value)).first->second;
+ });
+ }
+
+ void
+ jsonValueFlexLexer::BeginArray()
+ {
+ auto array = std::get_if<Array>(acceptValues.top()(Array()));
+ acceptValues.push([array](auto && value) {
+ return &array->emplace_back(std::forward<Value>(value));
+ });
+ }
+
+ void
+ jsonValueFlexLexer::PushNull()
+ {
+ acceptValues.top()(Null());
+ }
+
+ void
+ jsonValueFlexLexer::PushBoolean(bool value)
+ {
+ acceptValues.top()(value);
+ }
+
+ void
+ jsonValueFlexLexer::PushNumber(double value)
+ {
+ acceptValues.top()(value);
+ }
+
+ void
+ jsonValueFlexLexer::PushText(std::string && value)
+ {
+ acceptValues.top()(std::forward<std::string>(value));
+ }
+
+ void
+ jsonValueFlexLexer::PushKey(std::string && value)
+ {
+ name = std::forward<std::string>(value);
+ }
+
+ void
+ jsonValueFlexLexer::EndArray()
+ {
+ acceptValues.pop();
+ }
+
+ void
+ jsonValueFlexLexer::EndObject()
+ {
+ acceptValues.pop();
+ }
+}
+
diff --git a/libjsonpp/jsonValueFlexLexer.h b/libjsonpp/jsonValueFlexLexer.h
new file mode 100644
index 0000000..82f3d62
--- /dev/null
+++ b/libjsonpp/jsonValueFlexLexer.h
@@ -0,0 +1,34 @@
+#ifndef JSONVALUEFLEXLEXER_H
+#define JSONVALUEFLEXLEXER_H
+
+#include "jsonFlexLexer.h"
+#include "jsonpp.h"
+#include <stack>
+#include <functional>
+
+namespace json {
+ class jsonValueFlexLexer : public jsonFlexLexer {
+ public:
+ jsonValueFlexLexer(std::istream &, std::string enc, Value & v);
+
+ void BeginObject() override;
+ void BeginArray() override;
+
+ void PushBoolean(bool) override;
+ void PushNumber(double) override;
+ void PushNull() override;
+ void PushText(std::string &&) override;
+ void PushKey(std::string &&) override;
+
+ void EndArray() override;
+ void EndObject() override;
+
+ private:
+ using AcceptValue = std::function<Value *(Value &&)>;
+ std::stack<AcceptValue> acceptValues;
+ std::string name;
+ };
+}
+
+#endif
+
diff --git a/libjsonpp/jsonpp.cpp b/libjsonpp/jsonpp.cpp
new file mode 100644
index 0000000..db2ac63
--- /dev/null
+++ b/libjsonpp/jsonpp.cpp
@@ -0,0 +1,14 @@
+#include "jsonpp.h"
+
+namespace json {
+ const std::string null("null");
+ const std::string utf8("utf-8");
+
+ static_assert(std::is_move_constructible<Value>::value);
+ static_assert(std::is_nothrow_move_constructible<Object>::value);
+ static_assert(std::is_nothrow_move_constructible<Array>::value);
+ static_assert(std::is_move_assignable<Value>::value);
+ static_assert(std::is_nothrow_move_assignable<Object>::value);
+ static_assert(std::is_nothrow_move_assignable<Array>::value);
+}
+
diff --git a/libjsonpp/jsonpp.h b/libjsonpp/jsonpp.h
index 67afb36..ac45acd 100644
--- a/libjsonpp/jsonpp.h
+++ b/libjsonpp/jsonpp.h
@@ -1,22 +1,20 @@
-#ifndef JSON_H
-#define JSON_H
+#ifndef JSONPP_H
+#define JSONPP_H
#include <glibmm/ustring.h>
#include <variant>
#include <map>
#include <vector>
-#include <stdexcept>
+#include "jsonFlexLexer.h"
-#pragma GCC visibility push(default)
namespace json {
- class ParseError : public std::invalid_argument {
- public:
- ParseError(const char *, int, int);
- };
+ extern const std::string utf8;
+ extern const std::string null;
typedef Glib::ustring String;
typedef double Number;
typedef bool Boolean;
+#pragma GCC visibility push(default)
class Null { };
class Object;
class Array;
@@ -32,21 +30,14 @@ namespace json {
using A::A;
};
- static_assert(std::is_move_constructible<Value>::value);
- static_assert(std::is_nothrow_move_constructible<Object>::value);
- static_assert(std::is_nothrow_move_constructible<Array>::value);
- static_assert(std::is_move_assignable<Value>::value);
- static_assert(std::is_nothrow_move_assignable<Object>::value);
- static_assert(std::is_nothrow_move_assignable<Array>::value);
-
Value parseValue(std::istream &);
Value parseValue(std::istream &, const std::string & encoding);
Value parseValue(const Glib::ustring & s);
Value parseValue(Glib::ustring::const_iterator & s);
void serializeValue(const Value &, std::ostream & s, const std::string & encoding);
-}
#pragma GCC visibility pop
+}
#endif
diff --git a/libjsonpp/parse.cpp b/libjsonpp/parse.cpp
index 9c9a013..ec6448b 100644
--- a/libjsonpp/parse.cpp
+++ b/libjsonpp/parse.cpp
@@ -1,19 +1,14 @@
#include "jsonpp.h"
-#include "jsonFlexLexer.h"
+#include "jsonValueFlexLexer.h"
namespace json {
- ParseError::ParseError(const char * at, int l, int s) :
- std::invalid_argument(Glib::ustring::compose("Parse error at or near %1 (line %2, state %3)", at, l, s))
- {
- }
-
Value parseValue(std::istream & s) {
return parseValue(s, std::string());
}
Value parseValue(std::istream & s, const std::string & enc) {
Value v;
- jsonFlexLexer jfl(s, enc, v);
+ jsonValueFlexLexer jfl(s, enc, v);
while (jfl.yylex()) {}
return v;
}
diff --git a/libjsonpp/serialize.cpp b/libjsonpp/serialize.cpp
index 055d36f..cb3d203 100644
--- a/libjsonpp/serialize.cpp
+++ b/libjsonpp/serialize.cpp
@@ -4,9 +4,6 @@
#include <iomanip>
namespace json {
- const std::string null("null");
- const std::string utf8("utf-8");
-
class JsonSerialize {
public:
JsonSerialize(std::ostream & out, const std::string & encoding) :