C++ bindings getting underway.
This commit is contained in:
parent
a7e4def944
commit
2408106191
3 changed files with 655 additions and 0 deletions
152
src/hammer.cxx
Normal file
152
src/hammer.cxx
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
#include "hammer.hxx"
|
||||||
|
|
||||||
|
namespace hammer {
|
||||||
|
|
||||||
|
typedef variant<BytesResult, UintResult, IntResult, NullResult, SequenceResult> 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<BytesResult>::parse(const string &input) {
|
||||||
|
HParseResult *res = h_parse(_parser, reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
|
||||||
|
return BytesResult(vector<uint8_t>(res->ast->bytes.token, res->ast->bytes.token+res->ast->bytes.len));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
BytesResult Parser<BytesResult>::parse(const uint8_t *input, size_t length) {
|
||||||
|
HParseResult *res = h_parse(_parser, input, length);
|
||||||
|
return BytesResult(vector<uint8_t>(res->ast->bytes.token, res->ast->bytes.token+res->ast->bytes.len));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
UintResult Parser<UintResult>::parse(const string &input) {
|
||||||
|
HParseResult *res = h_parse(_parser, reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
|
||||||
|
return UintResult(res->ast->uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
UintResult Parser<UintResult>::parse(const uint8_t *input, size_t length) {
|
||||||
|
HParseResult *res = h_parse(_parser, input, length);
|
||||||
|
return UintResult(res->ast->uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
IntResult Parser<IntResult>::parse(const string &input) {
|
||||||
|
HParseResult *res = h_parse(_parser, reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
|
||||||
|
return IntResult(res->ast->sint);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
IntResult Parser<IntResult>::parse(const uint8_t *input, size_t length) {
|
||||||
|
HParseResult *res = h_parse(_parser, input, length);
|
||||||
|
return IntResult(res->ast->sint);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
NullResult Parser<NullResult>::parse(const string &input) {
|
||||||
|
HParseResult *res = h_parse(_parser, reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
|
||||||
|
return NullResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
NullResult Parser<NullResult>::parse(const uint8_t *input, size_t length) {
|
||||||
|
HParseResult *res = h_parse(_parser, input, length);
|
||||||
|
return NullResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<AnyResult> make_seq(HCountedArray *seq) {
|
||||||
|
vector<AnyResult> ret;
|
||||||
|
for (size_t i=0; i<seq->used; ++i) {
|
||||||
|
switch(seq->elements[i]->token_type) {
|
||||||
|
case TT_NONE:
|
||||||
|
ret.push_back(NullResult());
|
||||||
|
break;
|
||||||
|
case TT_BYTES:
|
||||||
|
ret.push_back(BytesResult(vector<uint8_t>(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<SequenceResult>::parse(const string &input) {
|
||||||
|
HParseResult *res = h_parse(_parser, reinterpret_cast<const uint8_t*>(input.c_str()), input.size());
|
||||||
|
return SequenceResult(make_seq(res->ast->seq));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
SequenceResult Parser<SequenceResult>::parse(const uint8_t *input, size_t length) {
|
||||||
|
HParseResult *res = h_parse(_parser, input, length);
|
||||||
|
return SequenceResult(make_seq(res->ast->seq));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Many<T> Parser<T>::many() {
|
||||||
|
return Many<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
RepeatN<T> Parser<T>::many(size_t n) {
|
||||||
|
return RepeatN<T>(this, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Optional<T> Parser<T>::optional() {
|
||||||
|
return Optional<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
RepeatN<T> Parser<T>::operator[](size_t n) {
|
||||||
|
return RepeatN<T>(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);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
10
src/hammer.h
10
src/hammer.h
|
|
@ -27,7 +27,13 @@
|
||||||
#define BIT_LITTLE_ENDIAN 0x0
|
#define BIT_LITTLE_ENDIAN 0x0
|
||||||
#define BYTE_LITTLE_ENDIAN 0x0
|
#define BYTE_LITTLE_ENDIAN 0x0
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
typedef int bool;
|
typedef int bool;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct HParseState_ HParseState;
|
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);
|
void h_benchmark_dump_optimized_code(FILE* stream, HBenchmarkResults* results);
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // #ifndef HAMMER_HAMMER__H
|
#endif // #ifndef HAMMER_HAMMER__H
|
||||||
|
|
|
||||||
493
src/hammer.hxx
Normal file
493
src/hammer.hxx
Normal file
|
|
@ -0,0 +1,493 @@
|
||||||
|
#ifndef HAMMER_HAMMER__HXX
|
||||||
|
#define HAMMER_HAMMER__HXX
|
||||||
|
|
||||||
|
#include "hammer.h"
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
|
using std::list; using std::string; using std::vector;
|
||||||
|
using boost::variant;
|
||||||
|
|
||||||
|
namespace hammer {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class ParseResult {
|
||||||
|
public:
|
||||||
|
typedef T result_type;
|
||||||
|
protected:
|
||||||
|
ParseResult() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
class BytesResult : public ParseResult<vector<uint8_t> > {
|
||||||
|
public:
|
||||||
|
typedef vector<uint8_t> result_type;
|
||||||
|
BytesResult(const vector<uint8_t> res) : _bytes(res) { }
|
||||||
|
const result_type result();
|
||||||
|
private:
|
||||||
|
BytesResult() { }
|
||||||
|
result_type _bytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UintResult : public ParseResult<uint64_t> {
|
||||||
|
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<int64_t> {
|
||||||
|
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<void*> {
|
||||||
|
public:
|
||||||
|
NullResult() { }
|
||||||
|
typedef void* result_type;
|
||||||
|
const result_type result() { return NULL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class SequenceResult : public ParseResult<vector<variant<BytesResult, UintResult, IntResult, NullResult, SequenceResult> > > {
|
||||||
|
public:
|
||||||
|
typedef vector<variant<BytesResult, UintResult, IntResult, NullResult, SequenceResult> > result_type;
|
||||||
|
SequenceResult(result_type res) : _seq(res) { }
|
||||||
|
const result_type result();
|
||||||
|
private:
|
||||||
|
SequenceResult() { }
|
||||||
|
result_type _seq;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* forward declarations */
|
||||||
|
template<class T> class Many;
|
||||||
|
template<class T> class Many1;
|
||||||
|
template<class T> class Optional;
|
||||||
|
template<class T> class RepeatN;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class Parser {
|
||||||
|
public:
|
||||||
|
typedef T result_type;
|
||||||
|
result_type parse(const string &input);
|
||||||
|
result_type parse(const uint8_t *input, size_t length);
|
||||||
|
Many<T> many();
|
||||||
|
RepeatN<T> many(size_t n);
|
||||||
|
Optional<T> optional();
|
||||||
|
RepeatN<T> operator[](size_t n);
|
||||||
|
HParser* parser() { return _parser; }
|
||||||
|
HParser* _parser;
|
||||||
|
Parser() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Token : public Parser<BytesResult> {
|
||||||
|
public:
|
||||||
|
Token(string &str) : _tok(str) {
|
||||||
|
_parser = h_token(reinterpret_cast<const uint8_t*>(str.c_str()), str.size());
|
||||||
|
}
|
||||||
|
Token(const uint8_t *str, size_t length) : _tok(reinterpret_cast<const char*>(str), length) {
|
||||||
|
_parser = h_token(str, length);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
string _tok;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Ch : public Parser<UintResult> {
|
||||||
|
public:
|
||||||
|
Ch(const uint8_t c) : _c(c) {
|
||||||
|
_parser = h_ch(c);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
uint8_t _c;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ChRange : public Parser<UintResult> {
|
||||||
|
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<IntResult> {
|
||||||
|
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<IntResult> {
|
||||||
|
public:
|
||||||
|
SignedBits(size_t len) : _len(len) {
|
||||||
|
_parser = h_bits(len, true);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
size_t _len;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UnsignedBits : public Parser<UintResult> {
|
||||||
|
public:
|
||||||
|
UnsignedBits(size_t len) : _len(len) {
|
||||||
|
_parser = h_bits(len, false);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
size_t _len;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Int64 : public Parser<IntResult> {
|
||||||
|
public:
|
||||||
|
Int64() {
|
||||||
|
_parser = h_int64();
|
||||||
|
}
|
||||||
|
Int64 in_range(const int64_t lower, const int64_t upper);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Int32 : public Parser<IntResult> {
|
||||||
|
public:
|
||||||
|
Int32() {
|
||||||
|
_parser = h_int32();
|
||||||
|
}
|
||||||
|
Int32 in_range(const int32_t lower, const int32_t upper);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Int16 : public Parser<IntResult> {
|
||||||
|
public:
|
||||||
|
Int16() {
|
||||||
|
_parser = h_int16();
|
||||||
|
}
|
||||||
|
Int16 in_range(const int16_t lower, const int16_t upper);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Int8 : public Parser<IntResult> {
|
||||||
|
public:
|
||||||
|
Int8() {
|
||||||
|
_parser = h_int8();
|
||||||
|
}
|
||||||
|
Int8 in_range(const int8_t lower, const int8_t upper);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Uint64 : public Parser<UintResult> {
|
||||||
|
public:
|
||||||
|
Uint64() {
|
||||||
|
_parser = h_uint64();
|
||||||
|
}
|
||||||
|
Uint64 in_range(const uint64_t lower, const uint64_t upper);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Uint32 : public Parser<UintResult> {
|
||||||
|
public:
|
||||||
|
Uint32() {
|
||||||
|
_parser = h_uint32();
|
||||||
|
}
|
||||||
|
Uint32 in_range(const uint32_t lower, const uint32_t upper);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Uint16 : public Parser<UintResult> {
|
||||||
|
public:
|
||||||
|
Uint16() {
|
||||||
|
_parser = h_uint16();
|
||||||
|
}
|
||||||
|
Uint16 in_range(const uint16_t lower, const uint16_t upper);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Uint8 : public Parser<UintResult> {
|
||||||
|
public:
|
||||||
|
Uint8() {
|
||||||
|
_parser = h_uint8();
|
||||||
|
}
|
||||||
|
Uint8 in_range(const uint8_t lower, const uint8_t upper);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Whitespace : public Parser<T> {
|
||||||
|
public:
|
||||||
|
typedef typename T::result_type result_type;
|
||||||
|
Whitespace(Parser<T> &p) : _p(p) {
|
||||||
|
this->_parser = h_whitespace(p.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
class Left : public Parser<T> {
|
||||||
|
public:
|
||||||
|
typedef typename T::result_type result_type;
|
||||||
|
Left(Parser<T> &p, Parser<U> &q) : _p(p), _q(q) {
|
||||||
|
this->_parser = h_left(p.parser(), q.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
Parser<U> _q;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
class Right : public Parser<U> {
|
||||||
|
public:
|
||||||
|
typedef typename U::result_type result_type;
|
||||||
|
Right(Parser<T> &p, Parser<U> &q) : _p(p), _q(q) {
|
||||||
|
this->_parser = h_right(p.parser(), q.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
Parser<U> _q;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U, class V>
|
||||||
|
class Middle : public Parser<U> {
|
||||||
|
public:
|
||||||
|
typedef typename U::result_type result_type;
|
||||||
|
Middle(Parser<T> &p, Parser<U> &x, Parser<V> &q) : _p(p), _x(x), _q(q) {
|
||||||
|
this->_parser = h_middle(p.parser(), x.parser(), q.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
Parser<U> _x;
|
||||||
|
Parser<V> _q;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* what are we doing about h_action? */
|
||||||
|
|
||||||
|
class In : public Parser<UintResult> {
|
||||||
|
public:
|
||||||
|
In(string &charset) : _charset(charset) {
|
||||||
|
_parser = h_in(reinterpret_cast<const uint8_t*>(charset.c_str()), charset.size());
|
||||||
|
}
|
||||||
|
In(const uint8_t *charset, size_t length) : _charset(reinterpret_cast<const char*>(charset), length) {
|
||||||
|
_parser = h_in(charset, length);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
string _charset;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NotIn : public Parser<UintResult> {
|
||||||
|
public:
|
||||||
|
NotIn(string &charset) : _charset(charset) {
|
||||||
|
_parser = h_not_in(reinterpret_cast<const uint8_t*>(charset.c_str()), charset.size());
|
||||||
|
}
|
||||||
|
NotIn(const uint8_t *charset, size_t length) : _charset(reinterpret_cast<const char*>(charset), length) {
|
||||||
|
_parser = h_not_in(charset, length);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
string _charset;
|
||||||
|
};
|
||||||
|
|
||||||
|
class End : public Parser<NullResult> {
|
||||||
|
public:
|
||||||
|
End() {
|
||||||
|
_parser = h_end_p();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Nothing : public Parser<NullResult> {
|
||||||
|
public:
|
||||||
|
Nothing() {
|
||||||
|
_parser = h_nothing_p();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Sequence : public Parser<SequenceResult> {
|
||||||
|
public:
|
||||||
|
Sequence(list<Parser> &ps) : _ps(ps) {
|
||||||
|
void *parsers[ps.size()];
|
||||||
|
size_t i = 0;
|
||||||
|
for (list<Parser>::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<Parser> _ps;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Choice : public Parser<SequenceResult> {
|
||||||
|
public:
|
||||||
|
Choice(list<Parser<SequenceResult> > &ps) : _ps(ps) {
|
||||||
|
void *parsers[ps.size()];
|
||||||
|
size_t i = 0;
|
||||||
|
for (list<Parser<SequenceResult> >::iterator it=ps.begin(); it != ps.end(); ++it, ++i) {
|
||||||
|
parsers[i] = it->parser();
|
||||||
|
}
|
||||||
|
_parser = h_choice__a(parsers);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
list<Parser<SequenceResult> > _ps;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
class ButNot : public Parser<T> {
|
||||||
|
public:
|
||||||
|
typedef typename T::result_type result_type;
|
||||||
|
ButNot(Parser<T> &p, Parser<U> &q) : _p(p), _q(q) {
|
||||||
|
this->_parser = h_butnot(p.parser(), q.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
Parser<U> _q;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
class Difference : public Parser<T> {
|
||||||
|
public:
|
||||||
|
typedef typename T::result_type result_type;
|
||||||
|
Difference(Parser<T> &p, Parser<U> &q) : _p(p), _q(q) {
|
||||||
|
this->_parser = h_difference(p.parser(), q.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
Parser<U> _q;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
class Xor : public Parser<variant<T, U> > {
|
||||||
|
public:
|
||||||
|
typedef variant<T, U> result_type;
|
||||||
|
Xor(Parser<T> &p, Parser<U> &q) : _p(p), _q(q) {
|
||||||
|
this->_parser = h_xor(p.parser(), q.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
Parser<U> _q;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Many : public Parser<SequenceResult> {
|
||||||
|
public:
|
||||||
|
Many(Parser<T> &p) : _p(p) {
|
||||||
|
_parser = h_many(p.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Many1 : public Parser<SequenceResult> {
|
||||||
|
public:
|
||||||
|
Many1(Parser<T> &p) : _p(p) {
|
||||||
|
_parser = h_many1(p.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class RepeatN: public Parser<SequenceResult> {
|
||||||
|
public:
|
||||||
|
RepeatN(Parser<T> &p, const size_t n) : _p(p), _n(n) {
|
||||||
|
_parser = h_repeat_n(p.parser(), n);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
size_t _n;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Optional : public Parser<T> {
|
||||||
|
public:
|
||||||
|
typedef typename T::result_type result_type;
|
||||||
|
Optional(Parser<T> &p) : _p(p) {
|
||||||
|
this->_parser = h_optional(p.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Ignore : public Parser<NullResult> {
|
||||||
|
public:
|
||||||
|
Ignore(Parser<T> &p) : _p(p) {
|
||||||
|
_parser = h_ignore(p.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
class SepBy : public Parser<SequenceResult> {
|
||||||
|
public:
|
||||||
|
SepBy(Parser<T> &p, Parser<U> &sep) : _p(p), _sep(sep) {
|
||||||
|
_parser = h_sepBy(p.parser(), sep.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
Parser<U> _sep;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class U>
|
||||||
|
class SepBy1 : public Parser<SequenceResult> {
|
||||||
|
public:
|
||||||
|
SepBy1(Parser<T> &p, Parser<U> &sep) : _p(p), _sep(sep) {
|
||||||
|
_parser = h_sepBy1(p.parser(), sep.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
Parser<U> _sep;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Epsilon : public Parser<NullResult> {
|
||||||
|
public:
|
||||||
|
Epsilon() {
|
||||||
|
_parser = h_epsilon_p();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class LengthValue : public Parser<SequenceResult> {
|
||||||
|
public:
|
||||||
|
LengthValue(Parser<UintResult> &length, Parser<T> &value) : _length(length), _value(value) {
|
||||||
|
_parser = h_length_value(length.parser(), value.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<UintResult> _length;
|
||||||
|
Parser<T> _value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* FIXME attr_bool */
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class And : public Parser<NullResult> {
|
||||||
|
public:
|
||||||
|
And(Parser<T> &p) : _p(p) {
|
||||||
|
_parser = h_and(p.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Not : public Parser<NullResult> {
|
||||||
|
public:
|
||||||
|
Not(Parser &p) : _p(p) {
|
||||||
|
_parser = h_not(p.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class Indirect : public Parser<T> {
|
||||||
|
public:
|
||||||
|
Indirect(Parser<T> &p) : _p(p) {
|
||||||
|
this->_parser = h_indirect();
|
||||||
|
h_bind_indirect(this->_parser, p.parser());
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Parser<T> _p;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue