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

Adrian Thurston thurs... at cs.queensu.ca
Sat Feb 9 22:38:19 UTC 2008


Hi Manoj,

Ragel does a number of other pointer operations. Sometimes it moves the
pointer back one. Scanners sometimes move the pointer back a number of
characters. The ++ operator is used. Pointers are also copied. Here are
some examples:

if ( ++p == pe )
{{p = ((te))-1;} token( KW_Action ); }
{te = p+1;{
{te = p;p--;{
{ts = p;}

Adrian

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