Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
tree: 097236a9c4
Fetching contributors…

Cannot retrieve contributors at this time

132 lines (120 sloc) 2.993 kB
#include <iostream>
#include <string>
template <char C>
struct char_ {
template <class Iterator>
static
bool parse(Iterator& first, Iterator& last) {
if(first == last) {
return false;
}
if(C != *first) {
return false;
}
++first;
return true;
}
};
template <class A, class B>
struct or_ {
template <class Iterator>
static
bool parse(Iterator& first, Iterator& last) {
return
A::parse(first, last) ||
B::parse(first, last);
}
};
template <char BeginC, char EndC>
struct char_range_ {
template <class Iterator>
static
bool parse(Iterator& first, Iterator& last) {
if(first == last) {
return false;
}
if(*first < BeginC || EndC < *first) {
return false;
}
++first;
return true;
}
};
template <class A>
struct star_ {
template <class Iterator>
static
bool parse(Iterator& first, Iterator& last) {
while(A::parse(first, last));
return true;
}
};
template <class A, class B>
struct seq_ {
template <class Iterator>
static
bool parse(Iterator& first, Iterator& last) {
Iterator mark = first;
if(!A::parse(first, last)) {
return false;
}
if(!B::parse(first, last)) {
first = mark;
return false;
}
return true;
}
};
struct end_ {
template <class Iterator>
static
bool parse(Iterator& first, Iterator& last) {
return first == last;
}
};
template <class Parser>
inline
bool parse(const std::string& text) {
std::string::const_iterator begin = text.begin();
std::string::const_iterator end = text.end();
return Parser::parse(begin, end);
}
inline
void check(bool x) {
std::cout << (x ? "OK" : "NG") << std::endl;
}
int main() {
typedef char_<0x0a> lf_;
typedef char_<0x0d> cr_;
typedef char_<0x22> dquate_;
typedef char_<0x2c> comma_;
typedef seq_<cr_, lf_> crlf_;
typedef or_<or_<
char_range_<0x20, 0x21>,
char_range_<0x23, 0x2b> >,
char_range_<0x2d, 0x7e> > text_;
typedef star_<text_> non_escaped_;
typedef seq_<seq_<
dquate_,
star_<or_<or_<or_<or_<
text_,
comma_>,
cr_>,
lf_>,
seq_<dquate_, dquate_> > > >,
dquate_> escaped_;
typedef or_<escaped_, non_escaped_> field_;
typedef seq_<
field_,
star_<seq_<comma_, field_> > > record_;
typedef seq_<
record_,
star_<or_<
seq_<crlf_, end_>,
seq_<crlf_, record_> > > > file_;
check(parse<file_>("123"));
check(parse<file_>("123,Hello"));
check(parse<file_>("123,Hello,\"This is Test.\""));
check(parse<file_>("\"\"\"This \r\nis Test.\"\"\""));
return 0;
}
Jump to Line
Something went wrong with that request. Please try again.