Added start at C++ bindings
This commit is contained in:
parent
61f79252a5
commit
bda2fb4741
5 changed files with 239 additions and 0 deletions
9
src/bindings/cpp/SConscript
Normal file
9
src/bindings/cpp/SConscript
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
# -*- python -*-
|
||||||
|
Import("env libhammer_shared")
|
||||||
|
|
||||||
|
cppenv = env.Clone()
|
||||||
|
cppenv.Append(INCPATH=["."])
|
||||||
|
|
||||||
|
|
||||||
|
libhammerxx = env.SharedLibrary("hammer++", libhammer_shared + ["hammer.cpp"])
|
||||||
|
|
||||||
23
src/bindings/cpp/cpp_tests.cpp
Normal file
23
src/bindings/cpp/cpp_tests.cpp
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <hammer/hammer.hpp>
|
||||||
|
#include <hammer/hammer_test.hpp>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
using namespace ::hammer;
|
||||||
|
TEST(ParserTypes, Token) {
|
||||||
|
Parser p = Token("95\xA2");
|
||||||
|
EXPECT_TRUE(ParsesTo(p, "95\xA2", "<39.35.a2>"));
|
||||||
|
EXPECT_TRUE(ParseFails(p, "95"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParserTypes, Ch) {
|
||||||
|
Parser p = Ch(0xA2);
|
||||||
|
EXPECT_TRUE(ParsesTo(p, "\xA2", "u0xa2"));
|
||||||
|
EXPECT_TRUE(ParseFails(p, "\xA3"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
1
src/bindings/cpp/hammer/hammer.cpp
Normal file
1
src/bindings/cpp/hammer/hammer.cpp
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
160
src/bindings/cpp/hammer/hammer.hpp
Normal file
160
src/bindings/cpp/hammer/hammer.hpp
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
#ifndef HAMMER_HAMMER__HPP
|
||||||
|
#define HAMMER_HAMMER__HPP
|
||||||
|
|
||||||
|
#include <hammer/hammer.h>
|
||||||
|
#include <string>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace hammer {
|
||||||
|
class Parser {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ParsedToken {
|
||||||
|
// This object can suddenly become invalid if the underlying parse
|
||||||
|
// tree is destroyed.
|
||||||
|
|
||||||
|
// This object should serve as a very thin wrapper around an HParsedToken*.
|
||||||
|
// In particular sizeof(ParsedToken) should== sizeof(HParsedToken*)
|
||||||
|
// This means that we only get one member variable and no virtual functions.
|
||||||
|
protected:
|
||||||
|
HParsedToken *token;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ParsedToken(HParsedToken *inner) : token(inner) {}
|
||||||
|
ParsedToken(const ParsedToken &other) : token(other.token) {}
|
||||||
|
|
||||||
|
inline TokenType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* getUser() {
|
||||||
|
return token->user;
|
||||||
|
}
|
||||||
|
// TODO: add accessors.
|
||||||
|
|
||||||
|
|
||||||
|
std::string asUnambiguous() {
|
||||||
|
char* buf = h_write_result_unamb(token);
|
||||||
|
std::string s = std::string(buf);
|
||||||
|
free(buf);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ParseResult {
|
||||||
|
protected:
|
||||||
|
HParseResult *_result;
|
||||||
|
public:
|
||||||
|
|
||||||
|
ParsedToken getAST() {
|
||||||
|
return ParsedToken(_result);
|
||||||
|
}
|
||||||
|
inline string asUnambiguous() {
|
||||||
|
return getAST().asUnambiguous();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator bool() {
|
||||||
|
return _result != NULL;
|
||||||
|
}
|
||||||
|
bool operator !() {
|
||||||
|
return _result == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ParseResult() {
|
||||||
|
h_parse_result_free(_result);
|
||||||
|
_result = NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Parser token(const std::string &str) {
|
||||||
|
std::string *str_clone = new std::string(str);
|
||||||
|
return Parser(h_token(str_clone->data(), str.
|
||||||
|
}
|
||||||
|
Parser token(const uint8_t *buf, size_t len);
|
||||||
|
|
||||||
|
Parser ch(char ch);
|
||||||
|
|
||||||
|
Parser ch_range(uint8_t lower, uint8_t upper);
|
||||||
|
|
||||||
|
Parser int64();
|
||||||
|
Parser int32();
|
||||||
|
Parser int16();
|
||||||
|
Parser int8();
|
||||||
|
|
||||||
|
Parser uint64();
|
||||||
|
Parser uint32();
|
||||||
|
Parser uint16();
|
||||||
|
Parser uint8();
|
||||||
|
|
||||||
|
Parser int_range(Parser p, int64_t lower, int64_t upper);
|
||||||
|
|
||||||
|
Parser bits(size_t len, bool sign);
|
||||||
|
|
||||||
|
Parser whitespace(Parser p);
|
||||||
|
|
||||||
|
Parser left(Parser p, Parser q);
|
||||||
|
|
||||||
|
Parser right(Parser p, Parser q);
|
||||||
|
|
||||||
|
Parser middle(Parser p, Parser q, Parser r);
|
||||||
|
|
||||||
|
// TODO: Define Action
|
||||||
|
//Parser action(Parser p, Action a);
|
||||||
|
|
||||||
|
Parser in(string charset);
|
||||||
|
Parser in(const uint8_t *charset, size_t length);
|
||||||
|
Parser in(std::set<uint8_t> charset);
|
||||||
|
|
||||||
|
Parser not_in(string charset);
|
||||||
|
Parser not_in(const uint8_t *charset, size_t length);
|
||||||
|
Parser not_in(std::set<uint8_t> charset);
|
||||||
|
|
||||||
|
Parser end();
|
||||||
|
|
||||||
|
Parser nothing();
|
||||||
|
|
||||||
|
// TODO: figure out varargs
|
||||||
|
//Parser sequence();
|
||||||
|
//
|
||||||
|
//Parser choice();
|
||||||
|
|
||||||
|
Parser butnot(Parser p1, Parser p2);
|
||||||
|
|
||||||
|
Parser difference(Parser p1, Parser p2);
|
||||||
|
|
||||||
|
Parser xor_(Parser p1, Parser p2);
|
||||||
|
|
||||||
|
Parser many(Parser p);
|
||||||
|
|
||||||
|
Parser many1(Parser p);
|
||||||
|
|
||||||
|
Parser repeat_n(Parser p, size_t n);
|
||||||
|
|
||||||
|
Parser optional(Parser p);
|
||||||
|
|
||||||
|
Parser ignore(Parser p);
|
||||||
|
|
||||||
|
Parser sepBy(Parser p, Parser sep);
|
||||||
|
|
||||||
|
Parser sepBy1(Parser p, Parser sep);
|
||||||
|
|
||||||
|
Parser epsilon();
|
||||||
|
|
||||||
|
Parser length_value(Parser length, Parser value);
|
||||||
|
|
||||||
|
// Was attr_bool in the old C bindings.
|
||||||
|
// TODO: Figure out closure
|
||||||
|
//Parser validate(Parser p, Predicate pred);
|
||||||
|
|
||||||
|
Parser and_(Parser p);
|
||||||
|
|
||||||
|
Parser not_(Parser p);
|
||||||
|
|
||||||
|
IndirectParser indirect();
|
||||||
|
static inline void bind_indirect(IndirectParser &indirect, Parser p) {
|
||||||
|
indirect.bind(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
46
src/bindings/cpp/hammer/hammer_test.hpp
Normal file
46
src/bindings/cpp/hammer/hammer_test.hpp
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef HAMMER_HAMMER_TEST__HPP
|
||||||
|
#define HAMMER_HAMMER_TEST__HPP
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <hammer/hammer.hpp>
|
||||||
|
|
||||||
|
static ::testing::AssertionResult ParseFails(hammer::Parser parser,
|
||||||
|
const string &input) {
|
||||||
|
hammer::ParseResult result = parser.Parse(input);
|
||||||
|
if (result) {
|
||||||
|
return ::testing::AssertionFailure() << "Parse succeeded with " << result.AsUnambiguous() << "; expected failure";
|
||||||
|
} else {
|
||||||
|
return ::testing::AssertionSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ::testing::AssertionResult ParsesOK(hammer::Parser parser,
|
||||||
|
const string &input) {
|
||||||
|
hammer::ParseResult result = parser.Parse(input);
|
||||||
|
if (!result) {
|
||||||
|
return ::testing::AssertionFailure() << "Parse failed; expected success";
|
||||||
|
} else {
|
||||||
|
return ::testing::AssertionSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ::testing::AssertionResult ParsesTo(hammer::Parser parser,
|
||||||
|
const string &input,
|
||||||
|
const string &expected_result) {
|
||||||
|
hammer::ParseResult result = parser.Parse(input);
|
||||||
|
if (!result) {
|
||||||
|
return ::testing::AssertionFailure() << "Parse failed; expected success";
|
||||||
|
} else if (result.AsUnambiguous() != expected_result) {
|
||||||
|
return ::testing::AssertionFailure()
|
||||||
|
<< "Parse succeeded with wrong result: got "
|
||||||
|
<< result.AsUnambiguous()
|
||||||
|
<< "; expected "
|
||||||
|
<< expected_result;
|
||||||
|
} else {
|
||||||
|
return ::testing::AssertionSuccess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // defined(HAMMER_HAMMER_TEST__HPP)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue