From 2408106191956f20360c3663e4ba0d11ee6cb0d8 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Fri, 9 Aug 2013 18:45:26 +0200 Subject: [PATCH] C++ bindings getting underway. --- src/hammer.cxx | 152 +++++++++++++++ src/hammer.h | 10 + src/hammer.hxx | 493 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 655 insertions(+) create mode 100644 src/hammer.cxx create mode 100644 src/hammer.hxx diff --git a/src/hammer.cxx b/src/hammer.cxx new file mode 100644 index 0000000..dc2b104 --- /dev/null +++ b/src/hammer.cxx @@ -0,0 +1,152 @@ +#include "hammer.hxx" + +namespace hammer { + + typedef variant AnyResult; + + const BytesResult::result_type BytesResult::result() { return _bytes; } + const UintResult::result_type UintResult::result() { return _uint; } + const IntResult::result_type IntResult::result() { return _sint; } + const SequenceResult::result_type SequenceResult::result() { return _seq; } + + template<> + BytesResult Parser::parse(const string &input) { + HParseResult *res = h_parse(_parser, reinterpret_cast(input.c_str()), input.size()); + return BytesResult(vector(res->ast->bytes.token, res->ast->bytes.token+res->ast->bytes.len)); + } + + template<> + BytesResult Parser::parse(const uint8_t *input, size_t length) { + HParseResult *res = h_parse(_parser, input, length); + return BytesResult(vector(res->ast->bytes.token, res->ast->bytes.token+res->ast->bytes.len)); + } + + template<> + UintResult Parser::parse(const string &input) { + HParseResult *res = h_parse(_parser, reinterpret_cast(input.c_str()), input.size()); + return UintResult(res->ast->uint); + } + + template<> + UintResult Parser::parse(const uint8_t *input, size_t length) { + HParseResult *res = h_parse(_parser, input, length); + return UintResult(res->ast->uint); + } + + template<> + IntResult Parser::parse(const string &input) { + HParseResult *res = h_parse(_parser, reinterpret_cast(input.c_str()), input.size()); + return IntResult(res->ast->sint); + } + + template<> + IntResult Parser::parse(const uint8_t *input, size_t length) { + HParseResult *res = h_parse(_parser, input, length); + return IntResult(res->ast->sint); + } + + template<> + NullResult Parser::parse(const string &input) { + HParseResult *res = h_parse(_parser, reinterpret_cast(input.c_str()), input.size()); + return NullResult(); + } + + template<> + NullResult Parser::parse(const uint8_t *input, size_t length) { + HParseResult *res = h_parse(_parser, input, length); + return NullResult(); + } + + vector make_seq(HCountedArray *seq) { + vector ret; + for (size_t i=0; iused; ++i) { + switch(seq->elements[i]->token_type) { + case TT_NONE: + ret.push_back(NullResult()); + break; + case TT_BYTES: + ret.push_back(BytesResult(vector(seq->elements[i]->bytes.token, seq->elements[i]->bytes.token+seq->elements[i]->bytes.len))); + break; + case TT_SINT: + ret.push_back(IntResult(seq->elements[i]->sint)); + break; + case TT_UINT: + ret.push_back(UintResult(seq->elements[i]->uint)); + break; + case TT_SEQUENCE: + ret.push_back(make_seq(seq->elements[i]->seq)); + break; + default: + //TODO some kind of error + break; + } + } + return ret; + } + + template<> + SequenceResult Parser::parse(const string &input) { + HParseResult *res = h_parse(_parser, reinterpret_cast(input.c_str()), input.size()); + return SequenceResult(make_seq(res->ast->seq)); + } + + template<> + SequenceResult Parser::parse(const uint8_t *input, size_t length) { + HParseResult *res = h_parse(_parser, input, length); + return SequenceResult(make_seq(res->ast->seq)); + } + + template + Many Parser::many() { + return Many(this); + } + + template + RepeatN Parser::many(size_t n) { + return RepeatN(this, n); + } + + template + Optional Parser::optional() { + return Optional(this); + } + + template + RepeatN Parser::operator[](size_t n) { + return RepeatN(this, n); + } + + /* + Int64 Int64::in_range(const int64_t lower, const int64_t upper) { + return IntRange(Int64(), lower, upper); + } + + Int32 Int32::in_range(const int32_t lower, const int32_t upper) { + return IntRange(Int32(), lower, upper); + } + + Int16 Int16::in_range(const int16_t lower, const int16_t upper) { + return IntRange(Int16(), lower, upper); + } + + Int8 Int8::in_range(const int8_t lower, const int8_t upper) { + return IntRange(Int8(), lower, upper); + } + + Uint64 Uint64::in_range(const uint64_t lower, const uint64_t upper) { + return IntRange(Uint64(), lower, upper); + } + + Uint32 Uint32::in_range(const uint32_t lower, const uint32_t upper) { + return IntRange(Uint32(), lower, upper); + } + + Uint16 Uint16::in_range(const uint16_t lower, const uint16_t upper) { + return IntRange(Uint16(), lower, upper); + } + + Uint8 Uint8::in_range(const uint8_t lower, const uint8_t upper) { + return IntRange(Uint8(), lower, upper); + } + */ +} diff --git a/src/hammer.h b/src/hammer.h index 67fb8e4..89a9570 100644 --- a/src/hammer.h +++ b/src/hammer.h @@ -27,7 +27,13 @@ #define BIT_LITTLE_ENDIAN 0x0 #define BYTE_LITTLE_ENDIAN 0x0 +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __cplusplus typedef int bool; +#endif typedef struct HParseState_ HParseState; @@ -617,4 +623,8 @@ void h_benchmark_report(FILE* stream, HBenchmarkResults* results); void h_benchmark_dump_optimized_code(FILE* stream, HBenchmarkResults* results); // }}} +#ifdef __cplusplus +} +#endif + #endif // #ifndef HAMMER_HAMMER__H diff --git a/src/hammer.hxx b/src/hammer.hxx new file mode 100644 index 0000000..0baee86 --- /dev/null +++ b/src/hammer.hxx @@ -0,0 +1,493 @@ +#ifndef HAMMER_HAMMER__HXX +#define HAMMER_HAMMER__HXX + +#include "hammer.h" +#include +#include +#include +#include + +using std::list; using std::string; using std::vector; +using boost::variant; + +namespace hammer { + + template + class ParseResult { + public: + typedef T result_type; + protected: + ParseResult() { } + }; + + class BytesResult : public ParseResult > { + public: + typedef vector result_type; + BytesResult(const vector res) : _bytes(res) { } + const result_type result(); + private: + BytesResult() { } + result_type _bytes; + }; + + class UintResult : public ParseResult { + public: + typedef uint64_t result_type; + UintResult(const uint64_t res) : _uint(res) { } + const result_type result(); + private: + UintResult() { } + result_type _uint; + }; + + class IntResult : public ParseResult { + public: + typedef int64_t result_type; + IntResult(const int64_t res) : _sint(res) { } + const result_type result(); + private: + IntResult() { } + result_type _sint; + }; + + class NullResult: public ParseResult { + public: + NullResult() { } + typedef void* result_type; + const result_type result() { return NULL; } + }; + + class SequenceResult : public ParseResult > > { + public: + typedef vector > result_type; + SequenceResult(result_type res) : _seq(res) { } + const result_type result(); + private: + SequenceResult() { } + result_type _seq; + }; + + /* forward declarations */ + template class Many; + template class Many1; + template class Optional; + template class RepeatN; + + template + class Parser { + public: + typedef T result_type; + result_type parse(const string &input); + result_type parse(const uint8_t *input, size_t length); + Many many(); + RepeatN many(size_t n); + Optional optional(); + RepeatN operator[](size_t n); + HParser* parser() { return _parser; } + HParser* _parser; + Parser() { } + }; + + class Token : public Parser { + public: + Token(string &str) : _tok(str) { + _parser = h_token(reinterpret_cast(str.c_str()), str.size()); + } + Token(const uint8_t *str, size_t length) : _tok(reinterpret_cast(str), length) { + _parser = h_token(str, length); + } + private: + string _tok; + }; + + class Ch : public Parser { + public: + Ch(const uint8_t c) : _c(c) { + _parser = h_ch(c); + } + private: + uint8_t _c; + }; + + class ChRange : public Parser { + public: + ChRange(const uint8_t lower, const uint8_t upper) : _lower(lower), _upper(upper) { + _parser = h_ch_range(lower, upper); + } + private: + uint8_t _lower, _upper; + }; + + class IntRange : public Parser { + public: + IntRange(Parser &p, const int64_t lower, const int64_t upper) : _p(p), _lower(lower), _upper(upper) { + _parser = h_int_range(p.parser(), lower, upper); + } + private: + Parser _p; + int64_t _lower, _upper; + }; + + class SignedBits : public Parser { + public: + SignedBits(size_t len) : _len(len) { + _parser = h_bits(len, true); + } + private: + size_t _len; + }; + + class UnsignedBits : public Parser { + public: + UnsignedBits(size_t len) : _len(len) { + _parser = h_bits(len, false); + } + private: + size_t _len; + }; + + class Int64 : public Parser { + public: + Int64() { + _parser = h_int64(); + } + Int64 in_range(const int64_t lower, const int64_t upper); + }; + + class Int32 : public Parser { + public: + Int32() { + _parser = h_int32(); + } + Int32 in_range(const int32_t lower, const int32_t upper); + }; + + class Int16 : public Parser { + public: + Int16() { + _parser = h_int16(); + } + Int16 in_range(const int16_t lower, const int16_t upper); + }; + + class Int8 : public Parser { + public: + Int8() { + _parser = h_int8(); + } + Int8 in_range(const int8_t lower, const int8_t upper); + }; + + class Uint64 : public Parser { + public: + Uint64() { + _parser = h_uint64(); + } + Uint64 in_range(const uint64_t lower, const uint64_t upper); + }; + + class Uint32 : public Parser { + public: + Uint32() { + _parser = h_uint32(); + } + Uint32 in_range(const uint32_t lower, const uint32_t upper); + }; + + class Uint16 : public Parser { + public: + Uint16() { + _parser = h_uint16(); + } + Uint16 in_range(const uint16_t lower, const uint16_t upper); + }; + + class Uint8 : public Parser { + public: + Uint8() { + _parser = h_uint8(); + } + Uint8 in_range(const uint8_t lower, const uint8_t upper); + }; + + template + class Whitespace : public Parser { + public: + typedef typename T::result_type result_type; + Whitespace(Parser &p) : _p(p) { + this->_parser = h_whitespace(p.parser()); + } + private: + Parser _p; + }; + + template + class Left : public Parser { + public: + typedef typename T::result_type result_type; + Left(Parser &p, Parser &q) : _p(p), _q(q) { + this->_parser = h_left(p.parser(), q.parser()); + } + private: + Parser _p; + Parser _q; + }; + + template + class Right : public Parser { + public: + typedef typename U::result_type result_type; + Right(Parser &p, Parser &q) : _p(p), _q(q) { + this->_parser = h_right(p.parser(), q.parser()); + } + private: + Parser _p; + Parser _q; + }; + + template + class Middle : public Parser { + public: + typedef typename U::result_type result_type; + Middle(Parser &p, Parser &x, Parser &q) : _p(p), _x(x), _q(q) { + this->_parser = h_middle(p.parser(), x.parser(), q.parser()); + } + private: + Parser _p; + Parser _x; + Parser _q; + }; + + /* what are we doing about h_action? */ + + class In : public Parser { + public: + In(string &charset) : _charset(charset) { + _parser = h_in(reinterpret_cast(charset.c_str()), charset.size()); + } + In(const uint8_t *charset, size_t length) : _charset(reinterpret_cast(charset), length) { + _parser = h_in(charset, length); + } + private: + string _charset; + }; + + class NotIn : public Parser { + public: + NotIn(string &charset) : _charset(charset) { + _parser = h_not_in(reinterpret_cast(charset.c_str()), charset.size()); + } + NotIn(const uint8_t *charset, size_t length) : _charset(reinterpret_cast(charset), length) { + _parser = h_not_in(charset, length); + } + private: + string _charset; + }; + + class End : public Parser { + public: + End() { + _parser = h_end_p(); + } + }; + + class Nothing : public Parser { + public: + Nothing() { + _parser = h_nothing_p(); + } + }; + + class Sequence : public Parser { + public: + Sequence(list &ps) : _ps(ps) { + void *parsers[ps.size()]; + size_t i = 0; + for (list::iterator it=ps.begin(); it != ps.end(); ++it, ++i) { + parsers[i] = it->parser(); + } + _parser = h_sequence__a(parsers); + } + // maybe also a begin and end iterator version + private: + list _ps; + }; + + class Choice : public Parser { + public: + Choice(list > &ps) : _ps(ps) { + void *parsers[ps.size()]; + size_t i = 0; + for (list >::iterator it=ps.begin(); it != ps.end(); ++it, ++i) { + parsers[i] = it->parser(); + } + _parser = h_choice__a(parsers); + } + private: + list > _ps; + }; + + template + class ButNot : public Parser { + public: + typedef typename T::result_type result_type; + ButNot(Parser &p, Parser &q) : _p(p), _q(q) { + this->_parser = h_butnot(p.parser(), q.parser()); + } + private: + Parser _p; + Parser _q; + }; + + template + class Difference : public Parser { + public: + typedef typename T::result_type result_type; + Difference(Parser &p, Parser &q) : _p(p), _q(q) { + this->_parser = h_difference(p.parser(), q.parser()); + } + private: + Parser _p; + Parser _q; + }; + + template + class Xor : public Parser > { + public: + typedef variant result_type; + Xor(Parser &p, Parser &q) : _p(p), _q(q) { + this->_parser = h_xor(p.parser(), q.parser()); + } + private: + Parser _p; + Parser _q; + }; + + template + class Many : public Parser { + public: + Many(Parser &p) : _p(p) { + _parser = h_many(p.parser()); + } + private: + Parser _p; + }; + + template + class Many1 : public Parser { + public: + Many1(Parser &p) : _p(p) { + _parser = h_many1(p.parser()); + } + private: + Parser _p; + }; + + template + class RepeatN: public Parser { + public: + RepeatN(Parser &p, const size_t n) : _p(p), _n(n) { + _parser = h_repeat_n(p.parser(), n); + } + private: + Parser _p; + size_t _n; + }; + + template + class Optional : public Parser { + public: + typedef typename T::result_type result_type; + Optional(Parser &p) : _p(p) { + this->_parser = h_optional(p.parser()); + } + private: + Parser _p; + }; + + template + class Ignore : public Parser { + public: + Ignore(Parser &p) : _p(p) { + _parser = h_ignore(p.parser()); + } + private: + Parser _p; + }; + + template + class SepBy : public Parser { + public: + SepBy(Parser &p, Parser &sep) : _p(p), _sep(sep) { + _parser = h_sepBy(p.parser(), sep.parser()); + } + private: + Parser _p; + Parser _sep; + }; + + template + class SepBy1 : public Parser { + public: + SepBy1(Parser &p, Parser &sep) : _p(p), _sep(sep) { + _parser = h_sepBy1(p.parser(), sep.parser()); + } + private: + Parser _p; + Parser _sep; + }; + + class Epsilon : public Parser { + public: + Epsilon() { + _parser = h_epsilon_p(); + } + }; + + template + class LengthValue : public Parser { + public: + LengthValue(Parser &length, Parser &value) : _length(length), _value(value) { + _parser = h_length_value(length.parser(), value.parser()); + } + private: + Parser _length; + Parser _value; + }; + + /* FIXME attr_bool */ + + template + class And : public Parser { + public: + And(Parser &p) : _p(p) { + _parser = h_and(p.parser()); + } + private: + Parser _p; + }; + + template + class Not : public Parser { + public: + Not(Parser &p) : _p(p) { + _parser = h_not(p.parser()); + } + private: + Parser _p; + }; + + template + class Indirect : public Parser { + public: + Indirect(Parser &p) : _p(p) { + this->_parser = h_indirect(); + h_bind_indirect(this->_parser, p.parser()); + } + private: + Parser _p; + }; + +} + +#endif