[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