parse tree construction
This commit is contained in:
parent
2f287d046d
commit
5bdc6eba93
|
@ -1,3 +1,9 @@
|
||||||
[submodule "vendor/GCDWebServer"]
|
[submodule "vendor/GCDWebServer"]
|
||||||
path = vendor/GCDWebServer
|
path = vendor/GCDWebServer
|
||||||
url = https://github.com/swisspol/GCDWebServer.git
|
url = https://github.com/swisspol/GCDWebServer.git
|
||||||
|
[submodule "PEGTL"]
|
||||||
|
path = PEGTL
|
||||||
|
url = https://github.com/ColinH/PEGTL.git
|
||||||
|
[submodule "vendor/PEGTL"]
|
||||||
|
path = vendor/PEGTL
|
||||||
|
url = https://github.com/ColinH/PEGTL.git
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
0270BC861B7D020100010E03 /* schemas.js in Resources */ = {isa = PBXBuildFile; fileRef = 0270BC7F1B7D020100010E03 /* schemas.js */; };
|
0270BC861B7D020100010E03 /* schemas.js in Resources */ = {isa = PBXBuildFile; fileRef = 0270BC7F1B7D020100010E03 /* schemas.js */; };
|
||||||
0270BC871B7D023200010E03 /* RealmJS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02B58CB11AE99CEC009B348C /* RealmJS.framework */; };
|
0270BC871B7D023200010E03 /* RealmJS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02B58CB11AE99CEC009B348C /* RealmJS.framework */; };
|
||||||
0270BCD11B7D067300010E03 /* RealmReact.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BCD01B7D067300010E03 /* RealmReact.mm */; };
|
0270BCD11B7D067300010E03 /* RealmReact.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BCD01B7D067300010E03 /* RealmReact.mm */; };
|
||||||
|
02786E331BF1065100937061 /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02786E311BF1065000937061 /* parser.cpp */; };
|
||||||
|
02786E341BF1065100937061 /* parser.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 02786E321BF1065000937061 /* parser.hpp */; };
|
||||||
0291DBD21BD994F700E3852C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02B58CCD1AE99D4D009B348C /* JavaScriptCore.framework */; };
|
0291DBD21BD994F700E3852C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02B58CCD1AE99D4D009B348C /* JavaScriptCore.framework */; };
|
||||||
029445931BDEDF40006D1617 /* transact_log_handler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 029445911BDEDF40006D1617 /* transact_log_handler.cpp */; };
|
029445931BDEDF40006D1617 /* transact_log_handler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 029445911BDEDF40006D1617 /* transact_log_handler.cpp */; };
|
||||||
029445941BDEDF40006D1617 /* transact_log_handler.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 029445921BDEDF40006D1617 /* transact_log_handler.hpp */; };
|
029445941BDEDF40006D1617 /* transact_log_handler.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 029445921BDEDF40006D1617 /* transact_log_handler.hpp */; };
|
||||||
|
@ -200,6 +202,8 @@
|
||||||
0270BC7F1B7D020100010E03 /* schemas.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = schemas.js; path = tests/schemas.js; sourceTree = SOURCE_ROOT; };
|
0270BC7F1B7D020100010E03 /* schemas.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = schemas.js; path = tests/schemas.js; sourceTree = SOURCE_ROOT; };
|
||||||
0270BCCF1B7D067300010E03 /* RealmReact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RealmReact.h; path = ReactNative/RealmReact.h; sourceTree = "<group>"; };
|
0270BCCF1B7D067300010E03 /* RealmReact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RealmReact.h; path = ReactNative/RealmReact.h; sourceTree = "<group>"; };
|
||||||
0270BCD01B7D067300010E03 /* RealmReact.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RealmReact.mm; path = ReactNative/RealmReact.mm; sourceTree = "<group>"; };
|
0270BCD01B7D067300010E03 /* RealmReact.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RealmReact.mm; path = ReactNative/RealmReact.mm; sourceTree = "<group>"; };
|
||||||
|
02786E311BF1065000937061 /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = parser.cpp; path = "src/object-store/parser/parser.cpp"; sourceTree = "<group>"; };
|
||||||
|
02786E321BF1065000937061 /* parser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = parser.hpp; path = "src/object-store/parser/parser.hpp"; sourceTree = "<group>"; };
|
||||||
029445911BDEDF40006D1617 /* transact_log_handler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = transact_log_handler.cpp; path = "src/object-store/impl/transact_log_handler.cpp"; sourceTree = "<group>"; };
|
029445911BDEDF40006D1617 /* transact_log_handler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = transact_log_handler.cpp; path = "src/object-store/impl/transact_log_handler.cpp"; sourceTree = "<group>"; };
|
||||||
029445921BDEDF40006D1617 /* transact_log_handler.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = transact_log_handler.hpp; path = "src/object-store/impl/transact_log_handler.hpp"; sourceTree = "<group>"; };
|
029445921BDEDF40006D1617 /* transact_log_handler.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = transact_log_handler.hpp; path = "src/object-store/impl/transact_log_handler.hpp"; sourceTree = "<group>"; };
|
||||||
029445951BDEDF46006D1617 /* external_commit_helper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = external_commit_helper.cpp; path = "src/object-store/impl/apple/external_commit_helper.cpp"; sourceTree = "<group>"; };
|
029445951BDEDF46006D1617 /* external_commit_helper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = external_commit_helper.cpp; path = "src/object-store/impl/apple/external_commit_helper.cpp"; sourceTree = "<group>"; };
|
||||||
|
@ -279,6 +283,8 @@
|
||||||
029445921BDEDF40006D1617 /* transact_log_handler.hpp */,
|
029445921BDEDF40006D1617 /* transact_log_handler.hpp */,
|
||||||
029445951BDEDF46006D1617 /* external_commit_helper.cpp */,
|
029445951BDEDF46006D1617 /* external_commit_helper.cpp */,
|
||||||
029445961BDEDF46006D1617 /* external_commit_helper.hpp */,
|
029445961BDEDF46006D1617 /* external_commit_helper.hpp */,
|
||||||
|
02786E311BF1065000937061 /* parser.cpp */,
|
||||||
|
02786E321BF1065000937061 /* parser.hpp */,
|
||||||
0270BC3E1B7CFC0D00010E03 /* RealmJS.h */,
|
0270BC3E1B7CFC0D00010E03 /* RealmJS.h */,
|
||||||
0270BC3F1B7CFC0D00010E03 /* RealmJS.mm */,
|
0270BC3F1B7CFC0D00010E03 /* RealmJS.mm */,
|
||||||
02258FB11BC6E2D00075F13A /* RealmRPC.hpp */,
|
02258FB11BC6E2D00075F13A /* RealmRPC.hpp */,
|
||||||
|
@ -414,6 +420,7 @@
|
||||||
0270BC501B7CFC0D00010E03 /* RJSObject.hpp in Headers */,
|
0270BC501B7CFC0D00010E03 /* RJSObject.hpp in Headers */,
|
||||||
02601F0E1BA0F3A7007C91FF /* schema.hpp in Headers */,
|
02601F0E1BA0F3A7007C91FF /* schema.hpp in Headers */,
|
||||||
0270BC6C1B7CFC1C00010E03 /* object_store.hpp in Headers */,
|
0270BC6C1B7CFC1C00010E03 /* object_store.hpp in Headers */,
|
||||||
|
02786E341BF1065100937061 /* parser.hpp in Headers */,
|
||||||
0270BC681B7CFC1C00010E03 /* object_accessor.hpp in Headers */,
|
0270BC681B7CFC1C00010E03 /* object_accessor.hpp in Headers */,
|
||||||
F6BB7DF21BF681BC00D0A69E /* base64.hpp in Headers */,
|
F6BB7DF21BF681BC00D0A69E /* base64.hpp in Headers */,
|
||||||
029445941BDEDF40006D1617 /* transact_log_handler.hpp in Headers */,
|
029445941BDEDF40006D1617 /* transact_log_handler.hpp in Headers */,
|
||||||
|
@ -656,6 +663,7 @@
|
||||||
0270BC691B7CFC1C00010E03 /* object_schema.cpp in Sources */,
|
0270BC691B7CFC1C00010E03 /* object_schema.cpp in Sources */,
|
||||||
02601F0D1BA0F3A7007C91FF /* schema.cpp in Sources */,
|
02601F0D1BA0F3A7007C91FF /* schema.cpp in Sources */,
|
||||||
0270BC6E1B7CFC1C00010E03 /* results.cpp in Sources */,
|
0270BC6E1B7CFC1C00010E03 /* results.cpp in Sources */,
|
||||||
|
02786E331BF1065100937061 /* parser.cpp in Sources */,
|
||||||
0270BC511B7CFC0D00010E03 /* RJSObject.mm in Sources */,
|
0270BC511B7CFC0D00010E03 /* RJSObject.mm in Sources */,
|
||||||
0270BC4D1B7CFC0D00010E03 /* RealmJS.mm in Sources */,
|
0270BC4D1B7CFC0D00010E03 /* RealmJS.mm in Sources */,
|
||||||
02601F081BA0F0CD007C91FF /* index_set.cpp in Sources */,
|
02601F081BA0F0CD007C91FF /* index_set.cpp in Sources */,
|
||||||
|
@ -936,7 +944,7 @@
|
||||||
HEADER_SEARCH_PATHS = (
|
HEADER_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
"$(SRCROOT)/vendor",
|
"$(SRCROOT)/vendor/PEGTL",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = src/Info.plist;
|
INFOPLIST_FILE = src/Info.plist;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
|
@ -970,7 +978,7 @@
|
||||||
HEADER_SEARCH_PATHS = (
|
HEADER_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
"$(SRCROOT)/vendor",
|
"$(SRCROOT)/vendor/PEGTL",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = src/Info.plist;
|
INFOPLIST_FILE = src/Info.plist;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
|
@ -1106,7 +1114,7 @@
|
||||||
HEADER_SEARCH_PATHS = (
|
HEADER_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
"$(SRCROOT)/vendor",
|
"$(SRCROOT)/vendor/PEGTL",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = src/Info.plist;
|
INFOPLIST_FILE = src/Info.plist;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "parser.hpp"
|
||||||
|
|
||||||
|
int main( int argc, char ** argv )
|
||||||
|
{
|
||||||
|
realm::parser::parse(argv[1]);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,23 @@
|
||||||
#include <string>
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright 2015 Realm Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "parser.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <pegtl.hh>
|
#include <pegtl.hh>
|
||||||
|
@ -7,126 +26,217 @@
|
||||||
|
|
||||||
using namespace pegtl;
|
using namespace pegtl;
|
||||||
|
|
||||||
namespace query
|
namespace realm {
|
||||||
|
namespace parser {
|
||||||
|
|
||||||
|
// strings
|
||||||
|
struct unicode : list< seq< one< 'u' >, rep< 4, must< xdigit > > >, one< '\\' > > {};
|
||||||
|
struct escaped_char : one< '"', '\\', '/', 'b', 'f', 'n', 'r', 't' > {};
|
||||||
|
struct escaped : sor< escaped_char, unicode > {};
|
||||||
|
struct unescaped : utf8::range< 0x20, 0x10FFFF > {};
|
||||||
|
struct char_ : if_then_else< one< '\\' >, must< escaped >, unescaped > {};
|
||||||
|
|
||||||
|
struct string_content : until< at< one< '"' > >, must< char_ > > {};
|
||||||
|
struct string : seq< one< '"' >, must< string_content >, any >
|
||||||
{
|
{
|
||||||
// strings
|
using content = string_content;
|
||||||
struct unicode : list< seq< one< 'u' >, rep< 4, must< xdigit > > >, one< '\\' > > {};
|
};
|
||||||
struct escaped_char : one< '"', '\\', '/', 'b', 'f', 'n', 'r', 't' > {};
|
|
||||||
struct escaped : sor< escaped_char, unicode > {};
|
|
||||||
struct unescaped : utf8::range< 0x20, 0x10FFFF > {};
|
|
||||||
struct char_ : if_then_else< one< '\\' >, must< escaped >, unescaped > {};
|
|
||||||
|
|
||||||
struct string_content : until< at< one< '"' > >, must< char_ > > {};
|
// numbers
|
||||||
struct string : seq< one< '"' >, must< string_content >, any >
|
struct minus : opt< one< '-' > > {};
|
||||||
{
|
struct dot : one< '.' > {};
|
||||||
using content = string_content;
|
|
||||||
};
|
|
||||||
|
|
||||||
// numbers
|
struct float_num : sor<
|
||||||
struct minus : opt< one< '-' > > {};
|
seq< plus< digit >, dot, star< digit > >,
|
||||||
struct dot : one< '.' > {};
|
seq< star< digit >, dot, plus< digit > >
|
||||||
|
> {};
|
||||||
|
struct hex_num : seq< one< '0' >, one< 'x', 'X' >, plus< xdigit > > {};
|
||||||
|
struct int_num : plus< digit > {};
|
||||||
|
|
||||||
struct float_num : sor<
|
struct number : seq< minus, sor< float_num, hex_num, int_num > > {};
|
||||||
seq< plus< digit >, dot, star< digit > >,
|
|
||||||
seq< star< digit >, dot, plus< digit > >
|
|
||||||
> {};
|
|
||||||
struct hex_num : seq< one< '0' >, one< 'x', 'X' >, plus< xdigit > > {};
|
|
||||||
struct int_num : plus< digit > {};
|
|
||||||
|
|
||||||
struct number : seq< minus, sor< float_num, hex_num, int_num > > {};
|
// key paths
|
||||||
|
struct key_path : list< seq< sor< alpha, one< '_' > >, star< sor< alnum, one< '_', '-' > > > >, one< '.' > > {};
|
||||||
|
|
||||||
// key paths
|
// expressions and operators
|
||||||
struct key_path : list< seq< sor< alpha, one< '_' > >, star< sor< alnum, one< '_', '-' > > > >, one< '.' > > {};
|
struct expr : sor< string, key_path, number > {};
|
||||||
|
|
||||||
// expressions and operators
|
struct eq : sor< two< '=' >, one< '=' > > {};
|
||||||
struct expr : sor< string, key_path, number > {};
|
struct noteq : pegtl::string< '!', '=' > {};
|
||||||
struct oper : sor<
|
struct lteq : pegtl::string< '<', '=' > {};
|
||||||
two< '=' >,
|
struct lt : one< '<' > {};
|
||||||
one< '=' >,
|
struct gteq : pegtl::string< '>', '=' > {};
|
||||||
pegtl::string< '!', '=' >,
|
struct gt : one< '<' > {};
|
||||||
pegtl::string< '<', '=' >,
|
struct begins : istring< 'b', 'e', 'g', 'i', 'n', 's', 'w', 'i', 't', 'h' > {};
|
||||||
one< '<' >,
|
struct ends : istring< 'e', 'n', 'd', 's', 'w', 'i', 't', 'h' > {};
|
||||||
pegtl::string< '>', '=' >,
|
struct contains : istring< 'c', 'o', 'n', 't', 'a', 'i', 'n', 's' > {};
|
||||||
one< '>' >
|
struct oper : sor< eq, noteq, lteq, lt, gteq, gt, begins, ends, contains > {};
|
||||||
> {};
|
|
||||||
|
|
||||||
// predicates
|
// predicates
|
||||||
struct comparison_pred : seq< expr, pad< oper, blank >, expr > {};
|
struct comparison_pred : seq< expr, pad< oper, blank >, expr > {};
|
||||||
|
|
||||||
struct pred;
|
struct pred;
|
||||||
struct group_pred : if_must< one< '(' >, pad< pred, blank >, one< ')' > > {};
|
struct group_pred : if_must< one< '(' >, pad< pred, blank >, one< ')' > > {};
|
||||||
|
|
||||||
struct single_pred : pad< sor< group_pred, comparison_pred >, blank > {};
|
struct not_pre : sor< seq< one< '!' >, star< blank > >, seq< istring< 'N', 'O', 'T' >, plus< blank > > > {};
|
||||||
struct not_pre : sor< seq< one< '!' >, star< blank > >, seq< istring< 'N', 'O', 'T' >, plus< blank > > > {};
|
struct atom_pred : seq< opt< not_pre >, pad< sor< group_pred, comparison_pred >, blank > > {};
|
||||||
struct atom_pred : seq< opt< not_pre >, single_pred > {};
|
|
||||||
|
|
||||||
struct and_op : sor< two< '&' >, istring< 'A', 'N', 'D' > > {};
|
struct and_op : sor< two< '&' >, istring< 'A', 'N', 'D' > > {};
|
||||||
struct or_op : sor< two< '|' >, istring< 'O', 'R' > > {};
|
struct or_op : sor< two< '|' >, istring< 'O', 'R' > > {};
|
||||||
|
|
||||||
struct or_ext : seq< pad< or_op, blank >, pred > {};
|
struct or_ext : seq< pad< or_op, blank >, pred > {};
|
||||||
struct and_ext : seq< pad< and_op, blank >, pred > {};
|
struct and_ext : seq< pad< and_op, blank >, pred > {};
|
||||||
struct and_pred : seq< atom_pred, star< and_ext > > {};
|
struct and_pred : seq< atom_pred, star< and_ext > > {};
|
||||||
|
|
||||||
struct pred : seq< and_pred, star< or_ext > > {};
|
struct pred : seq< and_pred, star< or_ext > > {};
|
||||||
|
|
||||||
// rules
|
// state
|
||||||
template< typename Rule >
|
struct ParserState
|
||||||
struct action : nothing< Rule > {};
|
|
||||||
template<> struct action< and_ext >
|
|
||||||
{
|
|
||||||
static void apply( const input & in, std::string & string_value )
|
|
||||||
{
|
|
||||||
std::cout << "<and>" << in.string() << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct action< or_ext >
|
|
||||||
{
|
|
||||||
static void apply( const input & in, std::string & string_value )
|
|
||||||
{
|
|
||||||
std::cout << "<or>" << in.string() << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct action< comparison_pred >
|
|
||||||
{
|
|
||||||
static void apply( const input & in, std::string & string_value )
|
|
||||||
{
|
|
||||||
std::cout << in.string() << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct action< one< '(' > >
|
|
||||||
{
|
|
||||||
static void apply( const input & in, std::string & string_value )
|
|
||||||
{
|
|
||||||
std::cout << "<begin_group>" << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct action< group_pred >
|
|
||||||
{
|
|
||||||
static void apply( const input & in, std::string & string_value )
|
|
||||||
{
|
|
||||||
std::cout << "<end_group>" << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<> struct action< not_pre >
|
|
||||||
{
|
|
||||||
static void apply( const input & in, std::string & string_value )
|
|
||||||
{
|
|
||||||
std::cout << "<not>" << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
int main( int argc, char ** argv )
|
|
||||||
{
|
{
|
||||||
if ( argc > 1 ) {
|
std::vector<Predicate *> predicate_stack;
|
||||||
std::string intstring;
|
Predicate *current() { return predicate_stack.back(); }
|
||||||
analyze< query::pred >();
|
|
||||||
parse< must< query::pred, eof >, query::action >( 1, argv, intstring);
|
void addExpression(Expression exp)
|
||||||
|
{
|
||||||
|
if (current()->type == Predicate::Type::Comparison) {
|
||||||
|
current()->sub_expressions.emplace_back(std::move(exp));
|
||||||
|
predicate_stack.pop_back();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Predicate p;
|
||||||
|
p.type = Predicate::Type::Comparison;
|
||||||
|
p.sub_expressions.emplace_back(std::move(exp));
|
||||||
|
current()->sub_predicates.emplace_back(std::move(p));
|
||||||
|
predicate_stack.push_back(¤t()->sub_predicates.back());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// rules
|
||||||
|
template< typename Rule >
|
||||||
|
struct action : nothing< Rule > {};
|
||||||
|
|
||||||
|
template<> struct action< and_ext >
|
||||||
|
{
|
||||||
|
static void apply( const input & in, ParserState & state )
|
||||||
|
{
|
||||||
|
std::cout << "<and>" << in.string() << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct action< or_ext >
|
||||||
|
{
|
||||||
|
static void apply( const input & in, ParserState & state )
|
||||||
|
{
|
||||||
|
std::cout << "<or>" << in.string() << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct action< string >
|
||||||
|
{
|
||||||
|
static void apply( const input & in, ParserState & state )
|
||||||
|
{
|
||||||
|
std::cout << in.string() << std::endl;
|
||||||
|
|
||||||
|
Expression exp;
|
||||||
|
exp.type = Expression::Type::String;
|
||||||
|
exp.s = in.string();
|
||||||
|
|
||||||
|
state.addExpression(exp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct action< key_path >
|
||||||
|
{
|
||||||
|
static void apply( const input & in, ParserState & state )
|
||||||
|
{
|
||||||
|
std::cout << in.string() << std::endl;
|
||||||
|
|
||||||
|
Expression exp;
|
||||||
|
exp.type = Expression::Type::KeyPath;
|
||||||
|
exp.s = in.string();
|
||||||
|
|
||||||
|
state.addExpression(std::move(exp));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct action< number >
|
||||||
|
{
|
||||||
|
static void apply( const input & in, ParserState & state )
|
||||||
|
{
|
||||||
|
std::cout << in.string() << std::endl;
|
||||||
|
|
||||||
|
Expression exp;
|
||||||
|
exp.type = Expression::Type::Number;
|
||||||
|
exp.s = in.string();
|
||||||
|
|
||||||
|
state.addExpression(std::move(exp));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define OPERATOR_ACTION(rule, oper) \
|
||||||
|
template<> struct action< rule > { \
|
||||||
|
static void apply( const input & in, ParserState & state ) { \
|
||||||
|
std::cout << in.string() << std::endl; \
|
||||||
|
state.current()->op = oper; }};
|
||||||
|
|
||||||
|
OPERATOR_ACTION(eq, Predicate::Operator::Equal)
|
||||||
|
OPERATOR_ACTION(noteq, Predicate::Operator::NotEqual)
|
||||||
|
OPERATOR_ACTION(gteq, Predicate::Operator::GreaterThanOrEqual)
|
||||||
|
OPERATOR_ACTION(gt, Predicate::Operator::GreaterThan)
|
||||||
|
OPERATOR_ACTION(lteq, Predicate::Operator::LessThanOrEqual)
|
||||||
|
OPERATOR_ACTION(lt, Predicate::Operator::LessThan)
|
||||||
|
OPERATOR_ACTION(begins, Predicate::Operator::BeginsWith)
|
||||||
|
OPERATOR_ACTION(ends, Predicate::Operator::EndsWith)
|
||||||
|
OPERATOR_ACTION(contains, Predicate::Operator::Contains)
|
||||||
|
|
||||||
|
|
||||||
|
template<> struct action< one< '(' > >
|
||||||
|
{
|
||||||
|
static void apply( const input & in, ParserState & state )
|
||||||
|
{
|
||||||
|
std::cout << "<begin_group>" << std::endl;
|
||||||
|
|
||||||
|
Predicate group;
|
||||||
|
group.type = Predicate::Type::And;
|
||||||
|
state.current()->sub_predicates.emplace_back(std::move(group));
|
||||||
|
state.predicate_stack.push_back(&state.current()->sub_predicates.back());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct action< group_pred >
|
||||||
|
{
|
||||||
|
static void apply( const input & in, ParserState & state )
|
||||||
|
{
|
||||||
|
std::cout << "<end_group>" << std::endl;
|
||||||
|
|
||||||
|
state.predicate_stack.pop_back();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct action< not_pre >
|
||||||
|
{
|
||||||
|
static void apply( const input & in, ParserState & state )
|
||||||
|
{
|
||||||
|
std::cout << "<not>" << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Predicate parse(const std::string &query)
|
||||||
|
{
|
||||||
|
analyze< pred >();
|
||||||
|
const std::string source = "user query";
|
||||||
|
|
||||||
|
Predicate out_predicate;
|
||||||
|
out_predicate.type = Predicate::Type::And;
|
||||||
|
|
||||||
|
ParserState state;
|
||||||
|
state.predicate_stack.push_back(&out_predicate);
|
||||||
|
|
||||||
|
pegtl::parse< must< pred, eof >, action >(query, source, state);
|
||||||
|
return out_predicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright 2015 Realm Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef REALM_EXTERNAL_COMMIT_HELPER_HPP
|
||||||
|
#define REALM_EXTERNAL_COMMIT_HELPER_HPP
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace realm {
|
||||||
|
namespace parser {
|
||||||
|
struct Expression
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
Number,
|
||||||
|
String,
|
||||||
|
KeyPath,
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
|
||||||
|
std::string s;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Predicate
|
||||||
|
{
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Comparison,
|
||||||
|
Or,
|
||||||
|
And,
|
||||||
|
True,
|
||||||
|
False,
|
||||||
|
};
|
||||||
|
Type type = Type::None;
|
||||||
|
|
||||||
|
// for comparison
|
||||||
|
enum class Operator
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Equal,
|
||||||
|
NotEqual,
|
||||||
|
LessThan,
|
||||||
|
LessThanOrEqual,
|
||||||
|
GreaterThan,
|
||||||
|
GreaterThanOrEqual,
|
||||||
|
BeginsWith,
|
||||||
|
EndsWith,
|
||||||
|
Contains,
|
||||||
|
};
|
||||||
|
Operator op = Operator::None;
|
||||||
|
std::vector<Expression> sub_expressions;
|
||||||
|
|
||||||
|
// for compounds
|
||||||
|
std::vector<Predicate> sub_predicates;
|
||||||
|
};
|
||||||
|
|
||||||
|
Predicate parse(const std::string &query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // REALM_EXTERNAL_COMMIT_HELPER_HPP
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 498cb70f5b60b9d87d7f4864104155339daf561b
|
Loading…
Reference in New Issue