<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>
<channel>
	<title>Comments on: Recursive descent, LL and predictive parsers</title>
	<atom:link href="http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/feed/" rel="self" type="application/rss+xml" />
	<link>http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/</link>
	<description>Eli Bendersky's personal website</description>
	<pubDate>Wed, 07 Jan 2009 23:33:39 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: SteveP</title>
		<link>http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/comment-page-1/#comment-133790</link>
		<dc:creator>SteveP</dc:creator>
		<pubDate>Mon, 13 Oct 2008 14:29:54 +0000</pubDate>
		<guid isPermaLink="false">http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/#comment-133790</guid>
		<description>You may find a project I recently uploaded of interest.  It allows an LL(1) parser to be described directly in java using an approximation of EBNF.  It is available at http://code.google.com/p/jelan/.

Steve</description>
		<content:encoded><![CDATA[<p>You may find a project I recently uploaded of interest.  It allows an LL(1) parser to be described directly in java using an approximation of EBNF.  It is available at <a href="http://code.google.com/p/jelan/" rel="nofollow">http://code.google.com/p/jelan/</a>.</p>
<p>Steve</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Baihao Yuan</title>
		<link>http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/comment-page-1/#comment-133170</link>
		<dc:creator>Baihao Yuan</dc:creator>
		<pubDate>Thu, 02 Oct 2008 00:11:27 +0000</pubDate>
		<guid isPermaLink="false">http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/#comment-133170</guid>
		<description>Can you please write a non-recursive version of this implementation by using an explicit stack.

Thanks,
Michael</description>
		<content:encoded><![CDATA[<p>Can you please write a non-recursive version of this implementation by using an explicit stack.</p>
<p>Thanks,<br />
Michael</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: eliben</title>
		<link>http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/comment-page-1/#comment-132610</link>
		<dc:creator>eliben</dc:creator>
		<pubDate>Sat, 27 Sep 2008 04:06:40 +0000</pubDate>
		<guid isPermaLink="false">http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/#comment-132610</guid>
		<description>@Barry

Thanks for the detailed comment. Using EBNF and looping sounds like a good way to simplify expression parsing. I've looked at TDOP before, and will look at it again, though this article was intended as a review of the basics.

Finally, you meant "for LL(1)" in the first paragraph of the comment, right ? If not, in what sense do you mean "one token peek-ahead" ?</description>
		<content:encoded><![CDATA[<p>@Barry</p>
<p>Thanks for the detailed comment. Using EBNF and looping sounds like a good way to simplify expression parsing. I&#8217;ve looked at TDOP before, and will look at it again, though this article was intended as a review of the basics.</p>
<p>Finally, you meant &#8220;for LL(1)&#8221; in the first paragraph of the comment, right ? If not, in what sense do you mean &#8220;one token peek-ahead&#8221; ?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Barry Kelly</title>
		<link>http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/comment-page-1/#comment-132586</link>
		<dc:creator>Barry Kelly</dc:creator>
		<pubDate>Fri, 26 Sep 2008 23:17:58 +0000</pubDate>
		<guid isPermaLink="false">http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/#comment-132586</guid>
		<description>Almost all commercial compilers use hand-written recursive descent, and use one-token peek-ahead (for LL(2)) or backtracking via syntactic / semantic predicates to resolve ambiguities. Also, there is often lexer hackery as required for e.g. types in C++ (types become keywords).

Your right-recursive calculator grammar will create parse trees that have incorrect operator association, BTW. You can see this trivially in your provided source - the example '5 - 3 - 5' evaluates to the incorrect answer 7. Note that the only point in distinguishing between expr and term is for operator precedence, as both rules simply parse binary operators.

EBNF maps closer to hand-written LL grammars than does plain BNF, because loops are easily written in LL, and are thus best represented explicitly rather than by recursion. So, for example, your expr production would look better like this:

expr ::=  term { "+" term &#124; "-" term } ;

The natural way to write a parser for this production will result in correct operator associativity.

(Angle-bracketed text is generally reserved in grammars for terminals produced by the lexer; I am aware that you are including the lexical structure in the grammar too, though using regular grammar rather than the context-free BNF grammar.)

Finally, let me point out that unmodified recursive descent is not an efficient way to parse expressions, particularly for languages with many precedence levels. There are simple precedence parser idioms which integrate well with recursive descent, see e.g.:

http://javascript.crockford.com/tdop/tdop.html

The Delphi compiler, on which I work, uses a similar mechanism to the one Doug describes for its expression parser. Similarly, Google Chrome's JavaScript engine, V8, also uses a precedence parser for expressions. (It also uses hand-written recursive descent.)</description>
		<content:encoded><![CDATA[<p>Almost all commercial compilers use hand-written recursive descent, and use one-token peek-ahead (for LL(2)) or backtracking via syntactic / semantic predicates to resolve ambiguities. Also, there is often lexer hackery as required for e.g. types in C++ (types become keywords).</p>
<p>Your right-recursive calculator grammar will create parse trees that have incorrect operator association, BTW. You can see this trivially in your provided source - the example &#8216;5 - 3 - 5&#8242; evaluates to the incorrect answer 7. Note that the only point in distinguishing between expr and term is for operator precedence, as both rules simply parse binary operators.</p>
<p>EBNF maps closer to hand-written LL grammars than does plain BNF, because loops are easily written in LL, and are thus best represented explicitly rather than by recursion. So, for example, your expr production would look better like this:</p>
<p>expr ::=  term { &#8220;+&#8221; term | &#8220;-&#8221; term } ;</p>
<p>The natural way to write a parser for this production will result in correct operator associativity.</p>
<p>(Angle-bracketed text is generally reserved in grammars for terminals produced by the lexer; I am aware that you are including the lexical structure in the grammar too, though using regular grammar rather than the context-free BNF grammar.)</p>
<p>Finally, let me point out that unmodified recursive descent is not an efficient way to parse expressions, particularly for languages with many precedence levels. There are simple precedence parser idioms which integrate well with recursive descent, see e.g.:</p>
<p><a href="http://javascript.crockford.com/tdop/tdop.html" rel="nofollow">http://javascript.crockford.com/tdop/tdop.html</a></p>
<p>The Delphi compiler, on which I work, uses a similar mechanism to the one Doug describes for its expression parser. Similarly, Google Chrome&#8217;s JavaScript engine, V8, also uses a precedence parser for expressions. (It also uses hand-written recursive descent.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sam</title>
		<link>http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/comment-page-1/#comment-132584</link>
		<dc:creator>Sam</dc:creator>
		<pubDate>Fri, 26 Sep 2008 23:13:30 +0000</pubDate>
		<guid isPermaLink="false">http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/#comment-132584</guid>
		<description>Another interesting top-down parser that isn't in the Dragon is the top-down-operator-precedence used in jslint. It's really is worth looking at for a new point of view after finishing the Dragon Book. http://javascript.crockford.com/tdop/tdop.html</description>
		<content:encoded><![CDATA[<p>Another interesting top-down parser that isn&#8217;t in the Dragon is the top-down-operator-precedence used in jslint. It&#8217;s really is worth looking at for a new point of view after finishing the Dragon Book. <a href="http://javascript.crockford.com/tdop/tdop.html" rel="nofollow">http://javascript.crockford.com/tdop/tdop.html</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ben</title>
		<link>http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/comment-page-1/#comment-132512</link>
		<dc:creator>Ben</dc:creator>
		<pubDate>Fri, 26 Sep 2008 12:41:47 +0000</pubDate>
		<guid isPermaLink="false">http://eli.thegreenplace.net/2008/09/26/recursive-descent-ll-and-predictive-parsers/#comment-132512</guid>
		<description>Another (nice) LL[k] parser generator: http://www.ssw.uni-linz.ac.at/coco/</description>
		<content:encoded><![CDATA[<p>Another (nice) LL[k] parser generator: <a href="http://www.ssw.uni-linz.ac.at/coco/" rel="nofollow">http://www.ssw.uni-linz.ac.at/coco/</a></p>
]]></content:encoded>
	</item>
</channel>
</rss>
