summaryrefslogtreecommitdiff
path: root/examples/explore_ast.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/explore_ast.py')
-rw-r--r--examples/explore_ast.py332
1 files changed, 166 insertions, 166 deletions
diff --git a/examples/explore_ast.py b/examples/explore_ast.py
index 24df79f..392e78a 100644
--- a/examples/explore_ast.py
+++ b/examples/explore_ast.py
@@ -1,166 +1,166 @@
-#-----------------------------------------------------------------
-# pycparser: explore_ast.py
-#
-# This example demonstrates how to "explore" the AST created by
-# pycparser to understand its structure. The AST is a n-nary tree
-# of nodes, each node having several children, each with a name.
-# Just read the code, and let the comments guide you. The lines
-# beginning with #~ can be uncommented to print out useful
-# information from the AST.
-# It helps to have the pycparser/_c_ast.cfg file in front of you.
-#
-# Copyright (C) 2008-2011, Eli Bendersky
-# License: BSD
-#-----------------------------------------------------------------
-from __future__ import print_function
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-#
-sys.path.extend(['.', '..'])
-
-from pycparser import c_parser, c_ast
-
-# This is some C source to parse. Note that pycparser must begin
-# at the top level of the C file, i.e. with either declarations
-# or function definitions (this is called "external declarations"
-# in C grammar lingo)
-#
-# Also, a C parser must have all the types declared in order to
-# build the correct AST. It doesn't matter what they're declared
-# to, so I've inserted the dummy typedef in the code to let the
-# parser know Hash and Node are types. You don't need to do it
-# when parsing real, correct C code.
-#
-text = r"""
- typedef int Node, Hash;
-
- void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*))
- {
- unsigned int i;
-
- if (hash == NULL || hash->heads == NULL)
- return;
-
- for (i = 0; i < hash->table_size; ++i)
- {
- Node* temp = hash->heads[i];
-
- while (temp != NULL)
- {
- PrintFunc(temp->entry->key, temp->entry->value);
- temp = temp->next;
- }
- }
- }
-"""
-
-# Create the parser and ask to parse the text. parse() will throw
-# a ParseError if there's an error in the code
-#
-parser = c_parser.CParser()
-ast = parser.parse(text, filename='<none>')
-
-# Uncomment the following line to see the AST in a nice, human
-# readable way. show() is the most useful tool in exploring ASTs
-# created by pycparser. See the c_ast.py file for the options you
-# can pass it.
-#
-#~ ast.show()
-
-# OK, we've seen that the top node is FileAST. This is always the
-# top node of the AST. Its children are "external declarations",
-# and are stored in a list called ext[] (see _c_ast.cfg for the
-# names and types of Nodes and their children).
-# As you see from the printout, our AST has two Typedef children
-# and one FuncDef child.
-# Let's explore FuncDef more closely. As I've mentioned, the list
-# ext[] holds the children of FileAST. Since the function
-# definition is the third child, it's ext[2]. Uncomment the
-# following line to show it:
-#
-#~ ast.ext[2].show()
-
-# A FuncDef consists of a declaration, a list of parameter
-# declarations (for K&R style function definitions), and a body.
-# First, let's examine the declaration.
-#
-function_decl = ast.ext[2].decl
-
-# function_decl, like any other declaration, is a Decl. Its type child
-# is a FuncDecl, which has a return type and arguments stored in a
-# ParamList node
-#~ function_decl.type.show()
-#~ function_decl.type.args.show()
-
-# The following displays the name and type of each argument:
-#
-#~ for param_decl in function_decl.type.args.params:
- #~ print('Arg name: %s' % param_decl.name)
- #~ print('Type:')
- #~ param_decl.type.show(offset=6)
-
-# The body is of FuncDef is a Compound, which is a placeholder for a block
-# surrounded by {} (You should be reading _c_ast.cfg parallel to this
-# explanation and seeing these things by your own eyes).
-#
-# Let's see the block's declarations:
-#
-function_body = ast.ext[2].body
-
-# The following displays the declarations and statements in the function
-# body
-#
-#~ for decl in function_body.block_items:
- #~ decl.show()
-
-# We can see a single variable declaration, i, declared to be a simple type
-# declaration of type 'unsigned int', followed by statements.
-#
-
-# block_items is a list, so the third element is the For statement:
-#
-for_stmt = function_body.block_items[2]
-#~ for_stmt.show()
-
-# As you can see in _c_ast.cfg, For's children are 'init, cond,
-# next' for the respective parts of the 'for' loop specifier,
-# and stmt, which is either a single stmt or a Compound if there's
-# a block.
-#
-# Let's dig deeper, to the while statement inside the for loop:
-#
-while_stmt = for_stmt.stmt.block_items[1]
-#~ while_stmt.show()
-
-# While is simpler, it only has a condition node and a stmt node.
-# The condition:
-#
-while_cond = while_stmt.cond
-#~ while_cond.show()
-
-# Note that it's a BinaryOp node - the basic constituent of
-# expressions in our AST. BinaryOp is the expression tree, with
-# left and right nodes as children. It also has the op attribute,
-# which is just the string representation of the operator.
-#
-#~ print while_cond.op
-#~ while_cond.left.show()
-#~ while_cond.right.show()
-
-#
-# That's if for the example. I hope you now see how easy it is to
-# explore the AST created by pycparser. Although on the surface it
-# is quite complex and has a lot of node types, this is the
-# inherent complexity of the C language every parser/compiler
-# designer has to cope with.
-# Using the tools provided by the c_ast package it's easy to
-# explore the structure of AST nodes and write code that processes
-# them.
-# Specifically, see the cdecl.py example for a non-trivial
-# demonstration of what you can do by recursively going through
-# the AST.
-#
-
-
+#-----------------------------------------------------------------
+# pycparser: explore_ast.py
+#
+# This example demonstrates how to "explore" the AST created by
+# pycparser to understand its structure. The AST is a n-nary tree
+# of nodes, each node having several children, each with a name.
+# Just read the code, and let the comments guide you. The lines
+# beginning with #~ can be uncommented to print out useful
+# information from the AST.
+# It helps to have the pycparser/_c_ast.cfg file in front of you.
+#
+# Copyright (C) 2008-2011, Eli Bendersky
+# License: BSD
+#-----------------------------------------------------------------
+from __future__ import print_function
+import sys
+
+# This is not required if you've installed pycparser into
+# your site-packages/ with setup.py
+#
+sys.path.extend(['.', '..'])
+
+from pycparser import c_parser, c_ast
+
+# This is some C source to parse. Note that pycparser must begin
+# at the top level of the C file, i.e. with either declarations
+# or function definitions (this is called "external declarations"
+# in C grammar lingo)
+#
+# Also, a C parser must have all the types declared in order to
+# build the correct AST. It doesn't matter what they're declared
+# to, so I've inserted the dummy typedef in the code to let the
+# parser know Hash and Node are types. You don't need to do it
+# when parsing real, correct C code.
+#
+text = r"""
+ typedef int Node, Hash;
+
+ void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*))
+ {
+ unsigned int i;
+
+ if (hash == NULL || hash->heads == NULL)
+ return;
+
+ for (i = 0; i < hash->table_size; ++i)
+ {
+ Node* temp = hash->heads[i];
+
+ while (temp != NULL)
+ {
+ PrintFunc(temp->entry->key, temp->entry->value);
+ temp = temp->next;
+ }
+ }
+ }
+"""
+
+# Create the parser and ask to parse the text. parse() will throw
+# a ParseError if there's an error in the code
+#
+parser = c_parser.CParser()
+ast = parser.parse(text, filename='<none>')
+
+# Uncomment the following line to see the AST in a nice, human
+# readable way. show() is the most useful tool in exploring ASTs
+# created by pycparser. See the c_ast.py file for the options you
+# can pass it.
+#
+#~ ast.show()
+
+# OK, we've seen that the top node is FileAST. This is always the
+# top node of the AST. Its children are "external declarations",
+# and are stored in a list called ext[] (see _c_ast.cfg for the
+# names and types of Nodes and their children).
+# As you see from the printout, our AST has two Typedef children
+# and one FuncDef child.
+# Let's explore FuncDef more closely. As I've mentioned, the list
+# ext[] holds the children of FileAST. Since the function
+# definition is the third child, it's ext[2]. Uncomment the
+# following line to show it:
+#
+#~ ast.ext[2].show()
+
+# A FuncDef consists of a declaration, a list of parameter
+# declarations (for K&R style function definitions), and a body.
+# First, let's examine the declaration.
+#
+function_decl = ast.ext[2].decl
+
+# function_decl, like any other declaration, is a Decl. Its type child
+# is a FuncDecl, which has a return type and arguments stored in a
+# ParamList node
+#~ function_decl.type.show()
+#~ function_decl.type.args.show()
+
+# The following displays the name and type of each argument:
+#
+#~ for param_decl in function_decl.type.args.params:
+ #~ print('Arg name: %s' % param_decl.name)
+ #~ print('Type:')
+ #~ param_decl.type.show(offset=6)
+
+# The body is of FuncDef is a Compound, which is a placeholder for a block
+# surrounded by {} (You should be reading _c_ast.cfg parallel to this
+# explanation and seeing these things by your own eyes).
+#
+# Let's see the block's declarations:
+#
+function_body = ast.ext[2].body
+
+# The following displays the declarations and statements in the function
+# body
+#
+#~ for decl in function_body.block_items:
+ #~ decl.show()
+
+# We can see a single variable declaration, i, declared to be a simple type
+# declaration of type 'unsigned int', followed by statements.
+#
+
+# block_items is a list, so the third element is the For statement:
+#
+for_stmt = function_body.block_items[2]
+#~ for_stmt.show()
+
+# As you can see in _c_ast.cfg, For's children are 'init, cond,
+# next' for the respective parts of the 'for' loop specifier,
+# and stmt, which is either a single stmt or a Compound if there's
+# a block.
+#
+# Let's dig deeper, to the while statement inside the for loop:
+#
+while_stmt = for_stmt.stmt.block_items[1]
+#~ while_stmt.show()
+
+# While is simpler, it only has a condition node and a stmt node.
+# The condition:
+#
+while_cond = while_stmt.cond
+#~ while_cond.show()
+
+# Note that it's a BinaryOp node - the basic constituent of
+# expressions in our AST. BinaryOp is the expression tree, with
+# left and right nodes as children. It also has the op attribute,
+# which is just the string representation of the operator.
+#
+#~ print while_cond.op
+#~ while_cond.left.show()
+#~ while_cond.right.show()
+
+#
+# That's if for the example. I hope you now see how easy it is to
+# explore the AST created by pycparser. Although on the surface it
+# is quite complex and has a lot of node types, this is the
+# inherent complexity of the C language every parser/compiler
+# designer has to cope with.
+# Using the tools provided by the c_ast package it's easy to
+# explore the structure of AST nodes and write code that processes
+# them.
+# Specifically, see the cdecl.py example for a non-trivial
+# demonstration of what you can do by recursively going through
+# the AST.
+#
+
+