Using ragel to parse input from files, in C++
Manoj Rajagopalan
ma... at nanorex.com
Sat Feb 9 02:38:34 UTC 2008
Hi all,
I have the following approach. It passes basic tests and I'd like to
share this with you. Can someone spot bugs?
// class to access a file (through buffer) but to appear like a pointer
class ragelfilebuf_ptr
{
public:
ragelfilebuf_ptr(char const *const filename)
: infile(filename, std::ios::in),
fbptr(infile.rdbuf()) { }
~ragelfilebuf_ptr() { if(infile.is_open()) infile.close(); }
// allow advancement or pointer
ragelfilebuf_ptr& operator += (int n) { for(int i=0; i<n;
++i)fbptr->snextc(); return *this;}
// allow access to current character
char operator * () { return (char)fbptr->sgetc(); }
private:
std::ifstream infile;
std::filebuf *fbptr;
};
int main()
{
int cs;
ragelfilebuf_ptr p("filename"); // create ragel's p variable
%% write exec noend # see 1. below
}
NOTES:
1. When writing your state machine define a machine to detect 0xff
(which is EOF) and perform the fbreak action. Note that I have used the
'noend' qualifier to the 'write exec' statement above - the program
won't terminate without our explicit instruction to do so.
2. The ifstream class performs buffered input. If its 'get' pointer goes
past the boundary its associated std::filebuf instance automatically
reads in more stuff from the file. By subclassing filebuf and
implementing its virtual methods you can set your own buffer using
ifstream::rdbuf(std::streambuf*).
3. If it is guaranteed that Ragel will never advance the p pointer by
more than one, then we can do away with the 'for' part of the
advancement statement in the definition of operator += above, i.e., we
simply need have fbptr->snext() only. Your comments, Alan?
cheers!
Manoj
More information about the ragel-users
mailing list