<?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 for Refactored scope</title>
	<atom:link href="http://ominian.com/comments/feed/" rel="self" type="application/rss+xml" />
	<link>http://ominian.com</link>
	<description>PyMethius project notes</description>
	<lastBuildDate>Sat, 14 Jan 2012 19:54:12 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>Comment on Working with &amp; using pynarcissus to parse Javascript in Python by David</title>
		<link>http://ominian.com/2012/01/06/working-with-using-pynarcissus-to-parse-javascript-in-python/comment-page-1/#comment-1627</link>
		<dc:creator>David</dc:creator>
		<pubDate>Sat, 14 Jan 2012 19:54:12 +0000</pubDate>
		<guid isPermaLink="false">http://ominian.com/?p=178#comment-1627</guid>
		<description>Patrick,
   Unfortunately I did this inside of juggernaut ( client project ) but a useful debugging cheat sheet I found was to make a simple Visitor child class that only implements visit_ANY and records something like defaultdict(list) sources like  self.node2lines[node.lineno].append( (node.type, node.source) ).   At the end you&#039;d dump that to a html file like so:

for lineno, nodes for sources.items():
print &lt;div&gt;&lt;span&gt;Line: %(lineno)s&lt;/span&gt;&lt;br&gt;
     for (node_type, node_source) in nodes:
     print &lt;span title=&quot;%(node_type)s&quot;&gt;%(node_source)s&lt;/span&gt;\n
print &lt;div&gt;

Not sure if the tag soup will make much sense... but the idea is that this decorator visitor ingests a raw javascript file and spits it back out with every token wrapped in span tags.  The oddest discovery I made is the &lt; node type=jsparser.SEMICOLON &gt; which usually encapsulates entire blocks of code ( entire functions, objects, conditional statements, vars, etc ).</description>
		<content:encoded><![CDATA[<p>Patrick,<br />
   Unfortunately I did this inside of juggernaut ( client project ) but a useful debugging cheat sheet I found was to make a simple Visitor child class that only implements visit_ANY and records something like defaultdict(list) sources like  self.node2lines[node.lineno].append( (node.type, node.source) ).   At the end you&#8217;d dump that to a html file like so:</p>
<p>for lineno, nodes for sources.items():<br />
print &lt;div&gt;&lt;span&gt;Line: %(lineno)s&lt;/span&gt;&lt;br&gt;<br />
     for (node_type, node_source) in nodes:<br />
     print &lt;span title=&#8221;%(node_type)s&#8221;&gt;%(node_source)s&lt;/span&gt;\n<br />
print &lt;div&gt;</p>
<p>Not sure if the tag soup will make much sense&#8230; but the idea is that this decorator visitor ingests a raw javascript file and spits it back out with every token wrapped in span tags.  The oddest discovery I made is the &lt; node type=jsparser.SEMICOLON &gt; which usually encapsulates entire blocks of code ( entire functions, objects, conditional statements, vars, etc ).</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Working with &amp; using pynarcissus to parse Javascript in Python by Patrick</title>
		<link>http://ominian.com/2012/01/06/working-with-using-pynarcissus-to-parse-javascript-in-python/comment-page-1/#comment-1626</link>
		<dc:creator>Patrick</dc:creator>
		<pubDate>Sat, 14 Jan 2012 14:20:21 +0000</pubDate>
		<guid isPermaLink="false">http://ominian.com/?p=178#comment-1626</guid>
		<description>Your solution worked great, thanks.
I fixed a tiny mistake though: https://gist.github.com/1611632
In the case of PROPERTY_INIT type of node, the line number returned was the last line of the value. I replaced print str(node.lineno) by print str(node[0].lineno)
Cheers</description>
		<content:encoded><![CDATA[<p>Your solution worked great, thanks.<br />
I fixed a tiny mistake though: <a href="https://gist.github.com/1611632" rel="nofollow">https://gist.github.com/1611632</a><br />
In the case of PROPERTY_INIT type of node, the line number returned was the last line of the value. I replaced print str(node.lineno) by print str(node[0].lineno)<br />
Cheers</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Working with &amp; using pynarcissus to parse Javascript in Python by Patrick</title>
		<link>http://ominian.com/2012/01/06/working-with-using-pynarcissus-to-parse-javascript-in-python/comment-page-1/#comment-1623</link>
		<dc:creator>Patrick</dc:creator>
		<pubDate>Thu, 12 Jan 2012 07:07:40 +0000</pubDate>
		<guid isPermaLink="false">http://ominian.com/?p=178#comment-1623</guid>
		<description>Thanks David for that. I&#039;ll have a look at it.</description>
		<content:encoded><![CDATA[<p>Thanks David for that. I&#8217;ll have a look at it.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Working with &amp; using pynarcissus to parse Javascript in Python by David</title>
		<link>http://ominian.com/2012/01/06/working-with-using-pynarcissus-to-parse-javascript-in-python/comment-page-1/#comment-1622</link>
		<dc:creator>David</dc:creator>
		<pubDate>Thu, 12 Jan 2012 04:47:32 +0000</pubDate>
		<guid isPermaLink="false">http://ominian.com/?p=178#comment-1622</guid>
		<description>Try something like this - https://gist.github.com/1598830  My system uses something like Visitor and then has a bunch of sub-classes for different cases... but for just scanning for functions this might be a slightly cleaner approach and it would be trivial to add a dict property to record the functions by name or by line as the key.    Also the if &quot;node.type ==&quot; can obviously be stripped off, I was just in a hurry and copy &amp; pasted your code into a stripped down version of my class.</description>
		<content:encoded><![CDATA[<p>Try something like this &#8211; <a href="https://gist.github.com/1598830" rel="nofollow">https://gist.github.com/1598830</a>  My system uses something like Visitor and then has a bunch of sub-classes for different cases&#8230; but for just scanning for functions this might be a slightly cleaner approach and it would be trivial to add a dict property to record the functions by name or by line as the key.    Also the if &#8220;node.type ==&#8221; can obviously be stripped off, I was just in a hurry and copy &amp; pasted your code into a stripped down version of my class.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Working with &amp; using pynarcissus to parse Javascript in Python by Patrick</title>
		<link>http://ominian.com/2012/01/06/working-with-using-pynarcissus-to-parse-javascript-in-python/comment-page-1/#comment-1620</link>
		<dc:creator>Patrick</dc:creator>
		<pubDate>Tue, 10 Jan 2012 23:38:28 +0000</pubDate>
		<guid isPermaLink="false">http://ominian.com/?p=178#comment-1620</guid>
		<description>Hi David,
Thanks a lot for this post. I myself was in need of a JS parser written in Python for a code review tool I&#039;m working on and pynarcissus seems to be doing the job perfectly.
I have to admit I gave antlr a try before but couldn&#039;t get it working for some reason.
pynarcissus worked perfectly the first time but now I&#039;m facing my own lack of understanding of how parsers work and how one is supposed to visit the resulting tree.

My use case is that I want to get all functions from a given file (whether they&#039;re anonymous or not, closures, object properties, etc...). I have created the following code which works, but I was wondering if you could point me into the direction of how one is supposed to write these kinds of visitors &quot;correctly&quot;:

&lt;pre&gt;def visitFunctions(root):
	for node in root:
		# Most nodes are lists
		if len(node) &gt; 0:
			visitFunctions(node)
		# Some have additional attributes to be visited as well
		for attr in [&#039;thenPart&#039;, &#039;elsePart&#039;, &#039;expression&#039;, &#039;body&#039;, &#039;initializer&#039;]:
			child = getattr(node, attr, None)
			if child:
				visitFunctions(child)
		
		# Named functions
		if node.type == &quot;FUNCTION&quot; and getattr(node, &quot;name&quot;, None):
			print str(node.lineno) + &quot; &#124; function &quot; + node.name

		# Anonymous functions declared with var name = function() {};
		try:
			if node.type == &quot;IDENTIFIER&quot; and node.initializer.type == &quot;FUNCTION&quot;:
				print str(node.lineno) + &quot; &#124; function &quot; + node.name
		except:
			pass
			
		# Anonymous functions declared as a property of an object
		try:
			if node.type == &quot;PROPERTY_INIT&quot; and node[1].type == &quot;FUNCTION&quot;:
				print str(node.lineno) + &quot; &#124; function &quot; + node[0].value
		except:
			pass
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Hi David,<br />
Thanks a lot for this post. I myself was in need of a JS parser written in Python for a code review tool I&#8217;m working on and pynarcissus seems to be doing the job perfectly.<br />
I have to admit I gave antlr a try before but couldn&#8217;t get it working for some reason.<br />
pynarcissus worked perfectly the first time but now I&#8217;m facing my own lack of understanding of how parsers work and how one is supposed to visit the resulting tree.</p>
<p>My use case is that I want to get all functions from a given file (whether they&#8217;re anonymous or not, closures, object properties, etc&#8230;). I have created the following code which works, but I was wondering if you could point me into the direction of how one is supposed to write these kinds of visitors &#8220;correctly&#8221;:</p>
<pre>def visitFunctions(root):
	for node in root:
		# Most nodes are lists
		if len(node) &gt; 0:
			visitFunctions(node)
		# Some have additional attributes to be visited as well
		for attr in ['thenPart', 'elsePart', 'expression', 'body', 'initializer']:
			child = getattr(node, attr, None)
			if child:
				visitFunctions(child)

		# Named functions
		if node.type == "FUNCTION" and getattr(node, "name", None):
			print str(node.lineno) + " | function " + node.name

		# Anonymous functions declared with var name = function() {};
		try:
			if node.type == "IDENTIFIER" and node.initializer.type == "FUNCTION":
				print str(node.lineno) + " | function " + node.name
		except:
			pass

		# Anonymous functions declared as a property of an object
		try:
			if node.type == "PROPERTY_INIT" and node[1].type == "FUNCTION":
				print str(node.lineno) + " | function " + node[0].value
		except:
			pass
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Canvas pixel collision detection by Canvas tag: Collision detection &#38; pixel decay - Refactored scope</title>
		<link>http://ominian.com/2011/03/09/canvas-pixel-collision-detection/comment-page-1/#comment-479</link>
		<dc:creator>Canvas tag: Collision detection &#38; pixel decay - Refactored scope</dc:creator>
		<pubDate>Mon, 14 Mar 2011 16:36:13 +0000</pubDate>
		<guid isPermaLink="false">http://ominian.com/?p=82#comment-479</guid>
		<description>[...] by David on Mar.02, 2010, under canvas, javascript UPDATED: March 14, 2011 here [...]</description>
		<content:encoded><![CDATA[<p>[...] by David on Mar.02, 2010, under canvas, javascript UPDATED: March 14, 2011 here [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Python module dis by Python &#8211; batteries included - Refactored scope</title>
		<link>http://ominian.com/2011/02/27/python-module-dis/comment-page-1/#comment-309</link>
		<dc:creator>Python &#8211; batteries included - Refactored scope</dc:creator>
		<pubDate>Sun, 27 Feb 2011 23:04:11 +0000</pubDate>
		<guid isPermaLink="false">http://ominian.com/?p=70#comment-309</guid>
		<description>[...] dis -&gt; disassembles a python script Example [...]</description>
		<content:encoded><![CDATA[<p>[...] dis -&gt; disassembles a python script Example [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Python urllib by Python &#8211; batteries included - Refactored scope</title>
		<link>http://ominian.com/2011/02/27/python-urllib/comment-page-1/#comment-308</link>
		<dc:creator>Python &#8211; batteries included - Refactored scope</dc:creator>
		<pubDate>Sun, 27 Feb 2011 22:57:13 +0000</pubDate>
		<guid isPermaLink="false">http://ominian.com/?p=71#comment-308</guid>
		<description>[...] urllib -&gt; ghetto wget Example [...]</description>
		<content:encoded><![CDATA[<p>[...] urllib -&gt; ghetto wget Example [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Python SimpleHTTPServer by Python &#8211; batteries included - Refactored scope</title>
		<link>http://ominian.com/2011/02/27/python-simplehttpserver/comment-page-1/#comment-307</link>
		<dc:creator>Python &#8211; batteries included - Refactored scope</dc:creator>
		<pubDate>Sun, 27 Feb 2011 22:37:41 +0000</pubDate>
		<guid isPermaLink="false">http://ominian.com/?p=68#comment-307</guid>
		<description>[...] SimpleHTTPServer -&gt; serve the current directory over HTTP on port 8080 Examples [...]</description>
		<content:encoded><![CDATA[<p>[...] SimpleHTTPServer -&gt; serve the current directory over HTTP on port 8080 Examples [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>Comment on Python json.tool module by Python &#8211; batteries included - Refactored scope</title>
		<link>http://ominian.com/2011/02/27/python-json-tool-module/comment-page-1/#comment-306</link>
		<dc:creator>Python &#8211; batteries included - Refactored scope</dc:creator>
		<pubDate>Sun, 27 Feb 2011 22:14:57 +0000</pubDate>
		<guid isPermaLink="false">http://ominian.com/?p=66#comment-306</guid>
		<description>[...] json.tool -&gt; pretty prints JSON Examples [...]</description>
		<content:encoded><![CDATA[<p>[...] json.tool -&gt; pretty prints JSON Examples [...]</p>
]]></content:encoded>
	</item>
</channel>
</rss>

