Has anyone implemented BASIC in Python?

Michael J. Fromberger Michael.J.Fromberger at Clothing.Dartmouth.EDU
Mon Aug 23 11:10:53 EDT 2004


In article <9h0ji0lvc0be65nuvcugaa3vsq5mcl3ck8 at 4ax.com>,
 Andrea Griffini <agriff at tin.it> wrote:

> Writing parsers, interpreters and compilers is a lot simpler than
> many do think. Of course the evil is in the details and getting
> something that comes even just close to (just for example ;-) )
> python is a *LOT* harder.
> 
> [...]
> 
> I never use yacc/lex, I just prefer hand-coding the parsers.
> 
> I never felt as pressing the problem of the speed of parsing
> (I've read that this is one main superiority of shift-reduce
> parsers). An hand-coded recursive descent parser is in my
> opinion very easy to write... and very easy to maintain.

For simple, single-purpose languages, I am inclined to agree that 
hand-written parsers are easy enough to write and maintain.  However, 
when you are dealing with a more complex general-purpose language, and 
one whose grammar needs to evolve over time, then I think a 
parser-generator is a much better solution by far.

The chief trouble in maintaining a hand-written recursive descent parser 
is that the grammar for the input language is hidden inside the 
implementation.  The author of the code can usually pick it out, but 
over time, even the author may find it difficult (and yes, I am speaking 
from a certain degree of first-hand experience in this matter).

In contrast, the grammars consumed by most parser-generators are 
explicitly written out as grammars, in the spirit (of not the form) of 
BNF notation.  If you want to make a change to the grammar (and thereby, 
the parser), you can easily see how the changes will affect the rest of 
the language, and a new parser can be created quickly and easily, simply 
by re-running the parser generator.  The only lines of code you need to 
touch are the places where your change affects the translation, and that 
is often quite minimal.

Furthermore, naive implementation of recursive descent is fraught with a 
few subtle perils to trip the novice and the unwary.  For instance, you 
must carefully avoid left-recursive productions, or your parser may not 
terminate.  Also, error-handling is tricky in recursive descent, because 
much of the parser's state is implicit in stack frames that must be 
correctly unwound when an error forces you to bail out.  If you're 
writing in a language (like Python) with good automatic memory 
management, the latter is less of an issue, but recursive descent 
parsers written in languages without automatic memory management, like C 
and C++, must contend mightily with this.

Of course, there is no silver bullet, but the availability of good LR(1) 
and LALR(1) parser generators should not be discounted, even if the 
theory behind them seems to be slightly complicated, on the surface.

Cheers,
-M

-- 
Michael J. Fromberger             | Lecturer, Dept. of Computer Science
http://www.dartmouth.edu/~sting/  | Dartmouth College, Hanover, NH, USA



More information about the Python-list mailing list