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