buffered input (examples?)

Michel Fortin michel.fortin at michelf.com
Mon Feb 7 12:57:55 PST 2011


On 2011-02-07 13:25:53 -0500, spir <denis.spir at gmail.com> said:

> On 02/07/2011 03:40 PM, Michel Fortin wrote:
>> On 2011-02-07 08:24:32 -0500, spir <denis.spir at gmail.com> said:
>> 
>>> Does this have anything to do with currently discussed buffered input ranges?
>>> If yes, how does such a design, or any alternative, fit their proposed
>>> interface?
>> 
>> You can build all of this on top of a buffered input range. The buffered input
>> range is not an alternative for your complex parsing algorithm, it's just the
>> component managing the buffer.
>> 
>> Having the underlying range manage the buffer (as opposed to having your parser
>> algorithm doing it) means that the buffer implementation can vary depending on
>> the type of range. For instance, if you're parsing directly data in memory, the
>> buffered range can use directly this data in memory as the buffer, requiring no
>> allocation and no copy; if you're parsing from a file or a network stream it'll
>> use a more standard buffer.
>> 
>> But how exactly the buffer is implemented does not affect your parsing
>> algorithm in any way. That's the great thing about it, separation of concerns:
>> your algorithm will work independently of the buffer implementation used. All
>> your parser algorithm has to do is say "shiftFront" and "appendToFront" to
>> control what's available in the buffer.
> 
> Right, that's nice. But I was certainly unclear. My question was in 
> fact how to make the lexeme stream be a buffered range. So that, 
> precisely, the parser does not have to cope about buffering (or rather 
> has to cope about it the std way clients will use to cope with buffered 
> ranges once they are standardised).
> In my hypothetical design, store() and unstore() are commands used to 
> manage buffering, thus similar in purpose, but different from what 
> Andrei's proposal provifdes. They just match the way I see a parser's 
> needs, naively. Now, how to translate this design to make the lexeme 
> stream a buffered range is very unclear for me; needed operations do 
> not directly translate to appendToFront / shiftFront (unless I do not 
> understand their action). I'm not even sure whether it would be simply 
> correct to use a buffered range.

You'd probably need a wrapper around the buffered range to handle 
backtracking nicely. Something like this:

	struct Backtracker(R) {
		R bufRange;
		size_t backtrackLength;

		ElementType!R front() @property {
			bufRange.front[0..$-backtrackLength];
		}

		void shiftFront(n) {
			bufRange.shiftFront(size_t n);
		}

		void backtrackFront(size_t n) {
			backtrackLength += n;
		}
		
		void appendToFront(size_t n) {
			if (backtrackLength <= n) {
				backtrackLength -= n;
			} else {
				bufRange.appendToFront(n-backtrackLength);
				backtrackLength = 0;
			}
		}

		void popFront() {
			assert(backtrackLength == 0, "mixin backtracking with by-chunk 
iteration not implemented");
			buffRange.popFront();
		}
	}

Perhaps this "backtrackFront()" function could be an optional part of 
the standard buffered range interface. If an algorithm requires a 
backtracking buffered input range and the input range you're provided 
with does not support backtracking, then you can use a wrapper like the 
one I drafted above to make the input acceptable to the algorithm.

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/



More information about the Digitalmars-d mailing list