[ragel-users] Using ragel to parse input from files, in C++

Manoj Rajagopalan ma... at nanorex.com
Sat Feb 9 02:47:16 UTC 2008


Actually, I just realized that we don't have to even consider the 
filebuf part unless we are interested in implementing custom buffers.

The following simple class should also work (haven't tested)

class ragelfile_ptr
{
public:
      ragelfile_ptr(char const *const filename)
          : infile(filename, std::ios::in) , c('\0')
          { if(infile) c = infile.peek(); }
      ~ragelfile_ptr() { if(infile.is_open()) infile.close(); }
      // allow advancement or pointer
      ragelfile_ptr& operator += (int )
      { infile.get(c); return *this;} // assuming ragel always does p+=1
      // allow access to current character
      char operator * () { return c; }
private:
      std::ifstream infile;
      char c;
};


cheers!
Manoj


Manoj Rajagopalan wrote:
> 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