1 - I really meant, an example of why you needed lookahead in tokens.
2 - I don't think you will have the problem you described, though, with not
using tokens.
For example (this is untested, so please try to ignore stupid mistakes):
name = Word()
with DroppedSpace():
while = "while" & name & ":"
assignment = name & "=" & name
statement = while | assignment
now consider statement.parse("whilex = foo")
First, "while" & name will match. But then ":" will fail. So then the parser
will try assignment instead.
3 - If you want to force spaces, use:
with Separator(Drop(Space()[1:])):
(there's a couple of errors in the docs - one is that DroppedSpace isn't in
the index; the other is that it says that it matches one or more spaces when,
as you have seen, it matches zero or more)
4 - This (requiring spaces) gets complicated when you have optional values
separated by spaces (because if the optional thing is missing, you can
stillend up requiring a space on either side of "nothing"). SmartSeparator1()
and SmartSeparator2() try to address this - see
http://www.acooke.org/lepl/operators.html#index-97
5 - However, getting offside parsing to work (if you are trying to parse
Python) without the lexer is going to be "interesting". If you want offside
parsing, finding a solution with tokens is important.
Hope that helps - handling spaces is complex, and there are many different
options. Personally I would recommend (2) - simply going with zero or more
spaces and relying on the parser backtracking.
Andrew