13 #ifndef WIBBLE_PARSE_H
14 #define WIBBLE_PARSE_H
28 template<
typename _Id >
51 template<
typename X,
typename Y >
52 inline std::ostream &
operator<<( std::ostream &o,
const std::pair< X, Y > &x ) {
53 return o <<
"(" << x.first <<
", " << x.second <<
")";
64 template<
typename Token,
typename Stream >
75 std::string r =
stream.remove();
76 std::copy( r.begin(), r.end(), std::back_inserter(
_window ) );
86 static_cast< void >( valid );
89 return std::string( b, e );
99 for(
int i = 0; i < n; ++i ) {
127 template<
typename I >
135 if (
match( data.begin(), data.end() ) )
136 return keep(
id, data );
140 unsigned n = 1, max = 0;
167 void match(
const std::string &from,
const std::string &to,
typename Token::Id id ) {
168 if ( !
match( from.begin(), from.end() ) )
172 int n = from.length();
178 if ( std::equal( to.begin(), to.end(), where ) )
186 while ( !
eof() && isspace(
window( 1 )[ 0 ] ) )
200 template<
typename Token,
typename Stream >
235 failures = std::priority_queue< Fail >();
238 void error( std::ostream &o, std::string prefix,
const Fail &fail ) {
240 switch ( fail.
type ) {
246 <<
", but seen " << Token::tokenName[ t.
id ] <<
" '" << t.
data <<
"'"
275 o <<
" error in context " <<
name <<
": ";
277 o <<
failures.size() <<
" rightmost alternatives:" << std::endl;
291 }
while ( t.
id == Token::Comment );
317 template<
typename Token,
typename Stream >
344 void fail(
const char *what,
FailType type = FailType::Syntax ) __attribute__((noreturn))
355 if ( t.
id == Token::Punctuation && t.
data ==
";" )
364 if ( t.
id == Token::Punctuation && t.
data ==
":" )
376 fail( Token::tokenName[
id].c_str() );
380 #if __cplusplus >= 201103L
381 template<
typename F >
382 void either(
void (F::*f)() ) {
383 (
static_cast< F*
>( this )->*f)();
386 template<
typename F,
typename... Args >
387 void either( F f, Args... args ) {
393 template<
typename F,
typename G >
397 (
static_cast< G*
>( this )->*g)();
402 #if __cplusplus >= 201103L
403 template<
typename F,
typename... Args >
404 bool maybe( F f, Args... args ) {
407 return maybe( args... );
411 template<
typename F,
typename G >
419 template<
typename F,
typename G,
typename H >
430 template<
typename F >
434 (
static_cast< F*
>( this )->*f)();
453 template<
typename T,
typename I >
465 #if __cplusplus >= 201103L
466 template<
typename F >
467 bool arbitrary( F f ) {
471 template<
typename F,
typename... Args >
472 bool arbitrary( F f, Args... args ) {
473 bool retval = arbitrary( args... );
474 retval |=
maybe( f );
475 retval |= arbitrary( args... );
480 template<
typename T,
typename I >
484 }
while (
next( sep ) );
487 template<
typename T,
typename I,
typename F >
488 void list( I i,
void (F::*sep)() ) {
494 (
static_cast< F*
>( this )->*sep)();
501 template<
typename T,
typename I >
511 if ( _fail && !t.
valid() ) {
513 fail(
"valid token" );
size_t matchLength(int idx)
Definition: regexp.cpp:118
bool match(const std::string &str, int flags=0)
Definition: regexp.cpp:73
ListIterator< List > end(List)
Definition: list.h:425
ListIterator< List > begin(List l)
Definition: list.h:420
std::ostream & operator<<(std::ostream &o, const std::pair< X, Y > &x)
Definition: parse.h:52
Iterator< typename I::value_type > iterator(I i)
Definition: iterator.h:123
void skipWhitespace()
Definition: parse.h:185
Position current
Definition: parse.h:69
void shift()
Definition: parse.h:73
void match(Regexp &r, typename Token::Id id)
Definition: parse.h:139
void match(const std::string &from, const std::string &to, typename Token::Id id)
Definition: parse.h:167
Token _match
Definition: parse.h:71
std::deque< char > Window
Definition: parse.h:67
Stream & stream
Definition: parse.h:66
bool ensure_window(unsigned n)
Definition: parse.h:92
std::string window(unsigned n)
Definition: parse.h:83
Window _window
Definition: parse.h:68
bool eof()
Definition: parse.h:79
Lexer(Stream &s)
Definition: parse.h:197
bool match(I begin, I end)
Definition: parse.h:128
void match(int(*first)(int), int(*rest)(int), typename Token::Id id)
Definition: parse.h:149
void consume(const Token &t)
Definition: parse.h:115
Token decide()
Definition: parse.h:190
void consume(const std::string &s)
Definition: parse.h:111
void match(const std::string &data, typename Token::Id id)
Definition: parse.h:134
void consume(int n)
Definition: parse.h:98
void keep(typename Token::Id id, const std::string &data)
Definition: parse.h:120
Type type
Definition: parse.h:218
Type
Definition: parse.h:214
@ Syntax
Definition: parse.h:214
@ Semantic
Definition: parse.h:214
bool operator<(const Fail &other) const
Definition: parse.h:220
const char * expected
Definition: parse.h:217
~Fail()
Definition: parse.h:229
int position
Definition: parse.h:216
Fail(const char *err, int pos, Type t=Syntax)
Definition: parse.h:224
Stream & stream()
Definition: parse.h:204
std::vector< This > children
Definition: parse.h:211
std::priority_queue< Fail > failures
Definition: parse.h:232
void rewind(int n)
Definition: parse.h:300
void errors(std::ostream &o)
Definition: parse.h:259
This & createChild(Stream &s, std::string name)
Definition: parse.h:307
ParseContext< Token, Stream > This
Definition: parse.h:210
int position
Definition: parse.h:208
void clearErrors()
Definition: parse.h:234
ParseContext(Stream &s, std::string name)
Definition: parse.h:312
std::deque< Token > window
Definition: parse.h:206
void error(std::ostream &o, std::string prefix, const Fail &fail)
Definition: parse.h:238
std::string name
Definition: parse.h:209
Stream * _stream
Definition: parse.h:203
Token remove()
Definition: parse.h:286
int window_pos
Definition: parse.h:207
void semicolon()
Definition: parse.h:353
Context * ctx
Definition: parse.h:321
void fail(const char *what, FailType type=FailType::Syntax) __attribute__((noreturn))
Definition: parse.h:344
void many(I i)
Definition: parse.h:454
void list(I i, TokenId sep)
Definition: parse.h:481
bool maybe(void(F::*f)())
Definition: parse.h:431
Parser(Context &c)
Definition: parse.h:526
int _position
Definition: parse.h:324
Parser()
Definition: parse.h:527
Token::Id TokenId
Definition: parse.h:319
bool maybe(F f, G g, H h)
Definition: parse.h:420
void list(I i, void(F::*sep)())
Definition: parse.h:488
int position()
Definition: parse.h:335
void rewind(int i)
Definition: parse.h:339
bool valid() const
Definition: parse.h:326
void colon()
Definition: parse.h:362
Token eat(bool _fail=true)
Definition: parse.h:508
void either(F f, void(G::*g)())
Definition: parse.h:394
bool next(TokenId id)
Definition: parse.h:518
Fail::Type FailType
Definition: parse.h:323
bool maybe(TokenId id)
Definition: parse.h:442
ParseContext< Token, Stream > Context
Definition: parse.h:320
Context & context()
Definition: parse.h:330
Context::Fail Fail
Definition: parse.h:322
bool maybe(F f, G g)
Definition: parse.h:412
Token eat(TokenId id)
Definition: parse.h:371
void list(I i, TokenId first, TokenId sep, TokenId last)
Definition: parse.h:502
int column
Definition: parse.h:21
bool operator==(const Position &o) const
Definition: parse.h:23
Position()
Definition: parse.h:22
int line
Definition: parse.h:20
std::string source
Definition: parse.h:19
bool _valid
Definition: parse.h:34
Position position
Definition: parse.h:33
std::string data
Definition: parse.h:32
Token(Id _id, std::string d)
Definition: parse.h:42
_Id Id
Definition: parse.h:30
bool valid()
Definition: parse.h:36
Token()
Definition: parse.h:43
bool operator==(const Token &o) const
Definition: parse.h:45
Token(Id _id, char c)
Definition: parse.h:38
Id id
Definition: parse.h:31
#define assert(x)
Definition: test.h:30