Using ragel to parse input from files, in C++

Manoj Rajagopalan ma... at
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
     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(); }
     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

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 

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?


More information about the ragel-users mailing list