update Linux_x86_64
This commit is contained in:
parent
93422b0274
commit
e7ebbedd38
336 changed files with 34353 additions and 21020 deletions
|
|
@ -4,11 +4,11 @@
|
|||
# This package file exports some convenience functions for
|
||||
# interacting with pycparser
|
||||
#
|
||||
# Copyright (C) 2008-2012, Eli Bendersky
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
__all__ = ['c_lexer', 'c_parser', 'c_ast']
|
||||
__version__ = '2.10'
|
||||
__version__ = '2.14'
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from .c_parser import CParser
|
||||
|
|
@ -91,4 +91,3 @@ def parse_file(filename, use_cpp=False, cpp_path='cpp', cpp_args='',
|
|||
if parser is None:
|
||||
parser = CParser()
|
||||
return parser.parse(text, filename)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#-----------------------------------------------------------------
|
||||
# _ast_gen.py
|
||||
#
|
||||
# Generates the AST Node classes from a specification given in
|
||||
# a .yaml file
|
||||
# Generates the AST Node classes from a specification given in
|
||||
# a configuration file
|
||||
#
|
||||
# The design of this module was inspired by astgen.py from the
|
||||
# Python 2.5 code-base.
|
||||
#
|
||||
# Copyright (C) 2008-2012, Eli Bendersky
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
import pprint
|
||||
|
|
@ -20,7 +20,7 @@ class ASTCodeGenerator(object):
|
|||
file.
|
||||
"""
|
||||
self.cfg_filename = cfg_filename
|
||||
self.node_cfg = [NodeCfg(name, contents)
|
||||
self.node_cfg = [NodeCfg(name, contents)
|
||||
for (name, contents) in self.parse_cfgfile(cfg_filename)]
|
||||
|
||||
def generate(self, file=None):
|
||||
|
|
@ -28,11 +28,11 @@ class ASTCodeGenerator(object):
|
|||
"""
|
||||
src = Template(_PROLOGUE_COMMENT).substitute(
|
||||
cfg_filename=self.cfg_filename)
|
||||
|
||||
|
||||
src += _PROLOGUE_CODE
|
||||
for node_cfg in self.node_cfg:
|
||||
src += node_cfg.generate_source() + '\n\n'
|
||||
|
||||
|
||||
file.write(src)
|
||||
|
||||
def parse_cfgfile(self, filename):
|
||||
|
|
@ -57,10 +57,10 @@ class ASTCodeGenerator(object):
|
|||
|
||||
|
||||
class NodeCfg(object):
|
||||
""" Node configuration.
|
||||
""" Node configuration.
|
||||
|
||||
name: node name
|
||||
contents: a list of contents - attributes and child nodes
|
||||
contents: a list of contents - attributes and child nodes
|
||||
See comment at the top of the configuration file for details.
|
||||
"""
|
||||
def __init__(self, name, contents):
|
||||
|
|
@ -73,7 +73,7 @@ class NodeCfg(object):
|
|||
for entry in contents:
|
||||
clean_entry = entry.rstrip('*')
|
||||
self.all_entries.append(clean_entry)
|
||||
|
||||
|
||||
if entry.endswith('**'):
|
||||
self.seq_child.append(clean_entry)
|
||||
elif entry.endswith('*'):
|
||||
|
|
@ -86,26 +86,30 @@ class NodeCfg(object):
|
|||
src += '\n' + self._gen_children()
|
||||
src += '\n' + self._gen_attr_names()
|
||||
return src
|
||||
|
||||
|
||||
def _gen_init(self):
|
||||
src = "class %s(Node):\n" % self.name
|
||||
|
||||
if self.all_entries:
|
||||
args = ', '.join(self.all_entries)
|
||||
slots = ', '.join("'{0}'".format(e) for e in self.all_entries)
|
||||
slots += ", 'coord', '__weakref__'"
|
||||
arglist = '(self, %s, coord=None)' % args
|
||||
else:
|
||||
slots = "'coord', '__weakref__'"
|
||||
arglist = '(self, coord=None)'
|
||||
|
||||
|
||||
src += " __slots__ = (%s)\n" % slots
|
||||
src += " def __init__%s:\n" % arglist
|
||||
|
||||
|
||||
for name in self.all_entries + ['coord']:
|
||||
src += " self.%s = %s\n" % (name, name)
|
||||
|
||||
|
||||
return src
|
||||
|
||||
def _gen_children(self):
|
||||
src = ' def children(self):\n'
|
||||
|
||||
|
||||
if self.all_entries:
|
||||
src += ' nodelist = []\n'
|
||||
|
||||
|
|
@ -114,21 +118,21 @@ class NodeCfg(object):
|
|||
' if self.%(child)s is not None:' +
|
||||
' nodelist.append(("%(child)s", self.%(child)s))\n') % (
|
||||
dict(child=child))
|
||||
|
||||
|
||||
for seq_child in self.seq_child:
|
||||
src += (
|
||||
' for i, child in enumerate(self.%(child)s or []):\n'
|
||||
' nodelist.append(("%(child)s[%%d]" %% i, child))\n') % (
|
||||
dict(child=seq_child))
|
||||
|
||||
|
||||
src += ' return tuple(nodelist)\n'
|
||||
else:
|
||||
src += ' return ()\n'
|
||||
|
||||
return src
|
||||
|
||||
return src
|
||||
|
||||
def _gen_attr_names(self):
|
||||
src = " attr_names = (" + ''.join("%r," % nm for nm in self.attr) + ')'
|
||||
src = " attr_names = (" + ''.join("%r, " % nm for nm in self.attr) + ')'
|
||||
return src
|
||||
|
||||
|
||||
|
|
@ -136,7 +140,7 @@ _PROLOGUE_COMMENT = \
|
|||
r'''#-----------------------------------------------------------------
|
||||
# ** ATTENTION **
|
||||
# This code was automatically generated from the file:
|
||||
# $cfg_filename
|
||||
# $cfg_filename
|
||||
#
|
||||
# Do not modify it directly. Modify the configuration file and
|
||||
# run the generator again.
|
||||
|
|
@ -146,7 +150,7 @@ r'''#-----------------------------------------------------------------
|
|||
#
|
||||
# AST Node classes.
|
||||
#
|
||||
# Copyright (C) 2008-2012, Eli Bendersky
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
|
|
@ -157,6 +161,7 @@ import sys
|
|||
|
||||
|
||||
class Node(object):
|
||||
__slots__ = ()
|
||||
""" Abstract base class for AST nodes.
|
||||
"""
|
||||
def children(self):
|
||||
|
|
@ -167,21 +172,21 @@ class Node(object):
|
|||
def show(self, buf=sys.stdout, offset=0, attrnames=False, nodenames=False, showcoord=False, _my_node_name=None):
|
||||
""" Pretty print the Node and all its attributes and
|
||||
children (recursively) to a buffer.
|
||||
|
||||
buf:
|
||||
|
||||
buf:
|
||||
Open IO buffer into which the Node is printed.
|
||||
|
||||
offset:
|
||||
Initial offset (amount of leading spaces)
|
||||
|
||||
|
||||
offset:
|
||||
Initial offset (amount of leading spaces)
|
||||
|
||||
attrnames:
|
||||
True if you want to see the attribute names in
|
||||
name=value pairs. False to only see the values.
|
||||
|
||||
|
||||
nodenames:
|
||||
True if you want to see the actual node names
|
||||
True if you want to see the actual node names
|
||||
within their parents.
|
||||
|
||||
|
||||
showcoord:
|
||||
Do you want the coordinates of each Node to be
|
||||
displayed.
|
||||
|
|
@ -216,47 +221,47 @@ class Node(object):
|
|||
|
||||
|
||||
class NodeVisitor(object):
|
||||
""" A base NodeVisitor class for visiting c_ast nodes.
|
||||
""" A base NodeVisitor class for visiting c_ast nodes.
|
||||
Subclass it and define your own visit_XXX methods, where
|
||||
XXX is the class name you want to visit with these
|
||||
XXX is the class name you want to visit with these
|
||||
methods.
|
||||
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
class ConstantVisitor(NodeVisitor):
|
||||
def __init__(self):
|
||||
self.values = []
|
||||
|
||||
|
||||
def visit_Constant(self, node):
|
||||
self.values.append(node.value)
|
||||
|
||||
Creates a list of values of all the constant nodes
|
||||
Creates a list of values of all the constant nodes
|
||||
encountered below the given node. To use it:
|
||||
|
||||
|
||||
cv = ConstantVisitor()
|
||||
cv.visit(node)
|
||||
|
||||
|
||||
Notes:
|
||||
|
||||
* generic_visit() will be called for AST nodes for which
|
||||
no visit_XXX method was defined.
|
||||
* The children of nodes for which a visit_XXX was
|
||||
|
||||
* generic_visit() will be called for AST nodes for which
|
||||
no visit_XXX method was defined.
|
||||
* The children of nodes for which a visit_XXX was
|
||||
defined will not be visited - if you need this, call
|
||||
generic_visit() on the node.
|
||||
generic_visit() on the node.
|
||||
You can use:
|
||||
NodeVisitor.generic_visit(self, node)
|
||||
* Modeled after Python's own AST visiting facilities
|
||||
(the ast module of Python 3.0)
|
||||
"""
|
||||
def visit(self, node):
|
||||
""" Visit a node.
|
||||
""" Visit a node.
|
||||
"""
|
||||
method = 'visit_' + node.__class__.__name__
|
||||
visitor = getattr(self, method, self.generic_visit)
|
||||
return visitor(node)
|
||||
|
||||
|
||||
def generic_visit(self, node):
|
||||
""" Called if no explicit visitor function exists for a
|
||||
""" Called if no explicit visitor function exists for a
|
||||
node. Implements preorder visiting of the node.
|
||||
"""
|
||||
for c_name, c in node.children():
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@
|
|||
# Also generates AST code from the configuration file.
|
||||
# Should be called from the pycparser directory.
|
||||
#
|
||||
# Copyright (C) 2008-2012, Eli Bendersky
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
# Generate c_ast.py
|
||||
#
|
||||
from _ast_gen import ASTCodeGenerator
|
||||
ast_gen = ASTCodeGenerator('_c_ast.cfg')
|
||||
ast_gen.generate(open('c_ast.py', 'w'))
|
||||
|
|
|
|||
|
|
@ -1,188 +1,189 @@
|
|||
#-----------------------------------------------------------------
|
||||
# pycparser: _c_ast_gen.cfg
|
||||
#
|
||||
# Defines the AST Node classes used in pycparser.
|
||||
#
|
||||
# Each entry is a Node sub-class name, listing the attributes
|
||||
# and child nodes of the class:
|
||||
# <name>* - a child node
|
||||
# <name>** - a sequence of child nodes
|
||||
# <name> - an attribute
|
||||
#
|
||||
# Copyright (C) 2008-2012, Eli Bendersky
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
ArrayDecl: [type*, dim*]
|
||||
|
||||
ArrayRef: [name*, subscript*]
|
||||
|
||||
# op: =, +=, /= etc.
|
||||
#
|
||||
Assignment: [op, lvalue*, rvalue*]
|
||||
|
||||
BinaryOp: [op, left*, right*]
|
||||
|
||||
Break: []
|
||||
|
||||
Case: [expr*, stmts**]
|
||||
|
||||
Cast: [to_type*, expr*]
|
||||
|
||||
# Compound statement in C99 is a list of block items (declarations or
|
||||
# statements).
|
||||
#
|
||||
Compound: [block_items**]
|
||||
|
||||
# Compound literal (anonymous aggregate) for C99.
|
||||
# (type-name) {initializer_list}
|
||||
# type: the typename
|
||||
# init: InitList for the initializer list
|
||||
#
|
||||
CompoundLiteral: [type*, init*]
|
||||
|
||||
# type: int, char, float, etc. see CLexer for constant token types
|
||||
#
|
||||
Constant: [type, value]
|
||||
|
||||
Continue: []
|
||||
|
||||
# name: the variable being declared
|
||||
# quals: list of qualifiers (const, volatile)
|
||||
# funcspec: list function specifiers (i.e. inline in C99)
|
||||
# storage: list of storage specifiers (extern, register, etc.)
|
||||
# type: declaration type (probably nested with all the modifiers)
|
||||
# init: initialization value, or None
|
||||
# bitsize: bit field size, or None
|
||||
#
|
||||
Decl: [name, quals, storage, funcspec, type*, init*, bitsize*]
|
||||
|
||||
DeclList: [decls**]
|
||||
|
||||
Default: [stmts**]
|
||||
|
||||
DoWhile: [cond*, stmt*]
|
||||
|
||||
# Represents the ellipsis (...) parameter in a function
|
||||
# declaration
|
||||
#
|
||||
EllipsisParam: []
|
||||
|
||||
# An empty statement (a semicolon ';' on its own)
|
||||
#
|
||||
EmptyStatement: []
|
||||
|
||||
# Enumeration type specifier
|
||||
# name: an optional ID
|
||||
# values: an EnumeratorList
|
||||
#
|
||||
Enum: [name, values*]
|
||||
|
||||
# A name/value pair for enumeration values
|
||||
#
|
||||
Enumerator: [name, value*]
|
||||
|
||||
# A list of enumerators
|
||||
#
|
||||
EnumeratorList: [enumerators**]
|
||||
|
||||
# A list of expressions separated by the comma operator.
|
||||
#
|
||||
ExprList: [exprs**]
|
||||
|
||||
# This is the top of the AST, representing a single C file (a
|
||||
# translation unit in K&R jargon). It contains a list of
|
||||
# "external-declaration"s, which is either declarations (Decl),
|
||||
# Typedef or function definitions (FuncDef).
|
||||
#
|
||||
FileAST: [ext**]
|
||||
|
||||
# for (init; cond; next) stmt
|
||||
#
|
||||
For: [init*, cond*, next*, stmt*]
|
||||
|
||||
# name: Id
|
||||
# args: ExprList
|
||||
#
|
||||
FuncCall: [name*, args*]
|
||||
|
||||
# type <decl>(args)
|
||||
#
|
||||
FuncDecl: [args*, type*]
|
||||
|
||||
# Function definition: a declarator for the function name and
|
||||
# a body, which is a compound statement.
|
||||
# There's an optional list of parameter declarations for old
|
||||
# K&R-style definitions
|
||||
#
|
||||
FuncDef: [decl*, param_decls**, body*]
|
||||
|
||||
Goto: [name]
|
||||
|
||||
ID: [name]
|
||||
|
||||
# Holder for types that are a simple identifier (e.g. the built
|
||||
# ins void, char etc. and typedef-defined types)
|
||||
#
|
||||
IdentifierType: [names]
|
||||
|
||||
If: [cond*, iftrue*, iffalse*]
|
||||
|
||||
# An initialization list used for compound literals.
|
||||
#
|
||||
InitList: [exprs**]
|
||||
|
||||
Label: [name, stmt*]
|
||||
|
||||
# A named initializer for C99.
|
||||
# The name of a NamedInitializer is a sequence of Nodes, because
|
||||
# names can be hierarchical and contain constant expressions.
|
||||
#
|
||||
NamedInitializer: [name**, expr*]
|
||||
|
||||
# a list of comma separated function parameter declarations
|
||||
#
|
||||
ParamList: [params**]
|
||||
|
||||
PtrDecl: [quals, type*]
|
||||
|
||||
Return: [expr*]
|
||||
|
||||
# name: struct tag name
|
||||
# decls: declaration of members
|
||||
#
|
||||
Struct: [name, decls**]
|
||||
|
||||
# type: . or ->
|
||||
# name.field or name->field
|
||||
#
|
||||
StructRef: [name*, type, field*]
|
||||
|
||||
Switch: [cond*, stmt*]
|
||||
|
||||
# cond ? iftrue : iffalse
|
||||
#
|
||||
TernaryOp: [cond*, iftrue*, iffalse*]
|
||||
|
||||
# A base type declaration
|
||||
#
|
||||
TypeDecl: [declname, quals, type*]
|
||||
|
||||
# A typedef declaration.
|
||||
# Very similar to Decl, but without some attributes
|
||||
#
|
||||
Typedef: [name, quals, storage, type*]
|
||||
|
||||
Typename: [quals, type*]
|
||||
|
||||
UnaryOp: [op, expr*]
|
||||
|
||||
# name: union tag name
|
||||
# decls: declaration of members
|
||||
#
|
||||
Union: [name, decls**]
|
||||
|
||||
While: [cond*, stmt*]
|
||||
|
||||
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
# pycparser: _c_ast.cfg
|
||||
#
|
||||
# Defines the AST Node classes used in pycparser.
|
||||
#
|
||||
# Each entry is a Node sub-class name, listing the attributes
|
||||
# and child nodes of the class:
|
||||
# <name>* - a child node
|
||||
# <name>** - a sequence of child nodes
|
||||
# <name> - an attribute
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
# ArrayDecl is a nested declaration of an array with the given type.
|
||||
# dim: the dimension (for example, constant 42)
|
||||
# dim_quals: list of dimension qualifiers, to support C99's allowing 'const'
|
||||
# and 'static' within the array dimension in function declarations.
|
||||
ArrayDecl: [type*, dim*, dim_quals]
|
||||
|
||||
ArrayRef: [name*, subscript*]
|
||||
|
||||
# op: =, +=, /= etc.
|
||||
#
|
||||
Assignment: [op, lvalue*, rvalue*]
|
||||
|
||||
BinaryOp: [op, left*, right*]
|
||||
|
||||
Break: []
|
||||
|
||||
Case: [expr*, stmts**]
|
||||
|
||||
Cast: [to_type*, expr*]
|
||||
|
||||
# Compound statement in C99 is a list of block items (declarations or
|
||||
# statements).
|
||||
#
|
||||
Compound: [block_items**]
|
||||
|
||||
# Compound literal (anonymous aggregate) for C99.
|
||||
# (type-name) {initializer_list}
|
||||
# type: the typename
|
||||
# init: InitList for the initializer list
|
||||
#
|
||||
CompoundLiteral: [type*, init*]
|
||||
|
||||
# type: int, char, float, etc. see CLexer for constant token types
|
||||
#
|
||||
Constant: [type, value]
|
||||
|
||||
Continue: []
|
||||
|
||||
# name: the variable being declared
|
||||
# quals: list of qualifiers (const, volatile)
|
||||
# funcspec: list function specifiers (i.e. inline in C99)
|
||||
# storage: list of storage specifiers (extern, register, etc.)
|
||||
# type: declaration type (probably nested with all the modifiers)
|
||||
# init: initialization value, or None
|
||||
# bitsize: bit field size, or None
|
||||
#
|
||||
Decl: [name, quals, storage, funcspec, type*, init*, bitsize*]
|
||||
|
||||
DeclList: [decls**]
|
||||
|
||||
Default: [stmts**]
|
||||
|
||||
DoWhile: [cond*, stmt*]
|
||||
|
||||
# Represents the ellipsis (...) parameter in a function
|
||||
# declaration
|
||||
#
|
||||
EllipsisParam: []
|
||||
|
||||
# An empty statement (a semicolon ';' on its own)
|
||||
#
|
||||
EmptyStatement: []
|
||||
|
||||
# Enumeration type specifier
|
||||
# name: an optional ID
|
||||
# values: an EnumeratorList
|
||||
#
|
||||
Enum: [name, values*]
|
||||
|
||||
# A name/value pair for enumeration values
|
||||
#
|
||||
Enumerator: [name, value*]
|
||||
|
||||
# A list of enumerators
|
||||
#
|
||||
EnumeratorList: [enumerators**]
|
||||
|
||||
# A list of expressions separated by the comma operator.
|
||||
#
|
||||
ExprList: [exprs**]
|
||||
|
||||
# This is the top of the AST, representing a single C file (a
|
||||
# translation unit in K&R jargon). It contains a list of
|
||||
# "external-declaration"s, which is either declarations (Decl),
|
||||
# Typedef or function definitions (FuncDef).
|
||||
#
|
||||
FileAST: [ext**]
|
||||
|
||||
# for (init; cond; next) stmt
|
||||
#
|
||||
For: [init*, cond*, next*, stmt*]
|
||||
|
||||
# name: Id
|
||||
# args: ExprList
|
||||
#
|
||||
FuncCall: [name*, args*]
|
||||
|
||||
# type <decl>(args)
|
||||
#
|
||||
FuncDecl: [args*, type*]
|
||||
|
||||
# Function definition: a declarator for the function name and
|
||||
# a body, which is a compound statement.
|
||||
# There's an optional list of parameter declarations for old
|
||||
# K&R-style definitions
|
||||
#
|
||||
FuncDef: [decl*, param_decls**, body*]
|
||||
|
||||
Goto: [name]
|
||||
|
||||
ID: [name]
|
||||
|
||||
# Holder for types that are a simple identifier (e.g. the built
|
||||
# ins void, char etc. and typedef-defined types)
|
||||
#
|
||||
IdentifierType: [names]
|
||||
|
||||
If: [cond*, iftrue*, iffalse*]
|
||||
|
||||
# An initialization list used for compound literals.
|
||||
#
|
||||
InitList: [exprs**]
|
||||
|
||||
Label: [name, stmt*]
|
||||
|
||||
# A named initializer for C99.
|
||||
# The name of a NamedInitializer is a sequence of Nodes, because
|
||||
# names can be hierarchical and contain constant expressions.
|
||||
#
|
||||
NamedInitializer: [name**, expr*]
|
||||
|
||||
# a list of comma separated function parameter declarations
|
||||
#
|
||||
ParamList: [params**]
|
||||
|
||||
PtrDecl: [quals, type*]
|
||||
|
||||
Return: [expr*]
|
||||
|
||||
# name: struct tag name
|
||||
# decls: declaration of members
|
||||
#
|
||||
Struct: [name, decls**]
|
||||
|
||||
# type: . or ->
|
||||
# name.field or name->field
|
||||
#
|
||||
StructRef: [name*, type, field*]
|
||||
|
||||
Switch: [cond*, stmt*]
|
||||
|
||||
# cond ? iftrue : iffalse
|
||||
#
|
||||
TernaryOp: [cond*, iftrue*, iffalse*]
|
||||
|
||||
# A base type declaration
|
||||
#
|
||||
TypeDecl: [declname, quals, type*]
|
||||
|
||||
# A typedef declaration.
|
||||
# Very similar to Decl, but without some attributes
|
||||
#
|
||||
Typedef: [name, quals, storage, type*]
|
||||
|
||||
Typename: [name, quals, type*]
|
||||
|
||||
UnaryOp: [op, expr*]
|
||||
|
||||
# name: union tag name
|
||||
# decls: declaration of members
|
||||
#
|
||||
Union: [name, decls**]
|
||||
|
||||
While: [cond*, stmt*]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# Some utilities used by the parser to create a friendlier AST.
|
||||
#
|
||||
# Copyright (C) 2008-2012, Eli Bendersky
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ def fix_switch_cases(switch_node):
|
|||
_extract_nested_case(child, new_compound.block_items)
|
||||
last_case = new_compound.block_items[-1]
|
||||
else:
|
||||
# Other statements are added as childrent to the last case, if it
|
||||
# Other statements are added as children to the last case, if it
|
||||
# exists.
|
||||
if last_case is None:
|
||||
new_compound.block_items.append(child)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#-----------------------------------------------------------------
|
||||
# ** ATTENTION **
|
||||
# This code was automatically generated from the file:
|
||||
# _c_ast.cfg
|
||||
# _c_ast.cfg
|
||||
#
|
||||
# Do not modify it directly. Modify the configuration file and
|
||||
# run the generator again.
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# AST Node classes.
|
||||
#
|
||||
# Copyright (C) 2008-2012, Eli Bendersky
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
|
|
@ -20,6 +20,7 @@ import sys
|
|||
|
||||
|
||||
class Node(object):
|
||||
__slots__ = ()
|
||||
""" Abstract base class for AST nodes.
|
||||
"""
|
||||
def children(self):
|
||||
|
|
@ -30,21 +31,21 @@ class Node(object):
|
|||
def show(self, buf=sys.stdout, offset=0, attrnames=False, nodenames=False, showcoord=False, _my_node_name=None):
|
||||
""" Pretty print the Node and all its attributes and
|
||||
children (recursively) to a buffer.
|
||||
|
||||
buf:
|
||||
|
||||
buf:
|
||||
Open IO buffer into which the Node is printed.
|
||||
|
||||
offset:
|
||||
Initial offset (amount of leading spaces)
|
||||
|
||||
|
||||
offset:
|
||||
Initial offset (amount of leading spaces)
|
||||
|
||||
attrnames:
|
||||
True if you want to see the attribute names in
|
||||
name=value pairs. False to only see the values.
|
||||
|
||||
|
||||
nodenames:
|
||||
True if you want to see the actual node names
|
||||
True if you want to see the actual node names
|
||||
within their parents.
|
||||
|
||||
|
||||
showcoord:
|
||||
Do you want the coordinates of each Node to be
|
||||
displayed.
|
||||
|
|
@ -79,47 +80,47 @@ class Node(object):
|
|||
|
||||
|
||||
class NodeVisitor(object):
|
||||
""" A base NodeVisitor class for visiting c_ast nodes.
|
||||
""" A base NodeVisitor class for visiting c_ast nodes.
|
||||
Subclass it and define your own visit_XXX methods, where
|
||||
XXX is the class name you want to visit with these
|
||||
XXX is the class name you want to visit with these
|
||||
methods.
|
||||
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
class ConstantVisitor(NodeVisitor):
|
||||
def __init__(self):
|
||||
self.values = []
|
||||
|
||||
|
||||
def visit_Constant(self, node):
|
||||
self.values.append(node.value)
|
||||
|
||||
Creates a list of values of all the constant nodes
|
||||
Creates a list of values of all the constant nodes
|
||||
encountered below the given node. To use it:
|
||||
|
||||
|
||||
cv = ConstantVisitor()
|
||||
cv.visit(node)
|
||||
|
||||
|
||||
Notes:
|
||||
|
||||
* generic_visit() will be called for AST nodes for which
|
||||
no visit_XXX method was defined.
|
||||
* The children of nodes for which a visit_XXX was
|
||||
|
||||
* generic_visit() will be called for AST nodes for which
|
||||
no visit_XXX method was defined.
|
||||
* The children of nodes for which a visit_XXX was
|
||||
defined will not be visited - if you need this, call
|
||||
generic_visit() on the node.
|
||||
generic_visit() on the node.
|
||||
You can use:
|
||||
NodeVisitor.generic_visit(self, node)
|
||||
* Modeled after Python's own AST visiting facilities
|
||||
(the ast module of Python 3.0)
|
||||
"""
|
||||
def visit(self, node):
|
||||
""" Visit a node.
|
||||
""" Visit a node.
|
||||
"""
|
||||
method = 'visit_' + node.__class__.__name__
|
||||
visitor = getattr(self, method, self.generic_visit)
|
||||
return visitor(node)
|
||||
|
||||
|
||||
def generic_visit(self, node):
|
||||
""" Called if no explicit visitor function exists for a
|
||||
""" Called if no explicit visitor function exists for a
|
||||
node. Implements preorder visiting of the node.
|
||||
"""
|
||||
for c_name, c in node.children():
|
||||
|
|
@ -127,9 +128,11 @@ class NodeVisitor(object):
|
|||
|
||||
|
||||
class ArrayDecl(Node):
|
||||
def __init__(self, type, dim, coord=None):
|
||||
__slots__ = ('type', 'dim', 'dim_quals', 'coord', '__weakref__')
|
||||
def __init__(self, type, dim, dim_quals, coord=None):
|
||||
self.type = type
|
||||
self.dim = dim
|
||||
self.dim_quals = dim_quals
|
||||
self.coord = coord
|
||||
|
||||
def children(self):
|
||||
|
|
@ -138,9 +141,10 @@ class ArrayDecl(Node):
|
|||
if self.dim is not None: nodelist.append(("dim", self.dim))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ()
|
||||
attr_names = ('dim_quals', )
|
||||
|
||||
class ArrayRef(Node):
|
||||
__slots__ = ('name', 'subscript', 'coord', '__weakref__')
|
||||
def __init__(self, name, subscript, coord=None):
|
||||
self.name = name
|
||||
self.subscript = subscript
|
||||
|
|
@ -155,6 +159,7 @@ class ArrayRef(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Assignment(Node):
|
||||
__slots__ = ('op', 'lvalue', 'rvalue', 'coord', '__weakref__')
|
||||
def __init__(self, op, lvalue, rvalue, coord=None):
|
||||
self.op = op
|
||||
self.lvalue = lvalue
|
||||
|
|
@ -167,9 +172,10 @@ class Assignment(Node):
|
|||
if self.rvalue is not None: nodelist.append(("rvalue", self.rvalue))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('op',)
|
||||
attr_names = ('op', )
|
||||
|
||||
class BinaryOp(Node):
|
||||
__slots__ = ('op', 'left', 'right', 'coord', '__weakref__')
|
||||
def __init__(self, op, left, right, coord=None):
|
||||
self.op = op
|
||||
self.left = left
|
||||
|
|
@ -182,9 +188,10 @@ class BinaryOp(Node):
|
|||
if self.right is not None: nodelist.append(("right", self.right))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('op',)
|
||||
attr_names = ('op', )
|
||||
|
||||
class Break(Node):
|
||||
__slots__ = ('coord', '__weakref__')
|
||||
def __init__(self, coord=None):
|
||||
self.coord = coord
|
||||
|
||||
|
|
@ -194,6 +201,7 @@ class Break(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Case(Node):
|
||||
__slots__ = ('expr', 'stmts', 'coord', '__weakref__')
|
||||
def __init__(self, expr, stmts, coord=None):
|
||||
self.expr = expr
|
||||
self.stmts = stmts
|
||||
|
|
@ -209,6 +217,7 @@ class Case(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Cast(Node):
|
||||
__slots__ = ('to_type', 'expr', 'coord', '__weakref__')
|
||||
def __init__(self, to_type, expr, coord=None):
|
||||
self.to_type = to_type
|
||||
self.expr = expr
|
||||
|
|
@ -223,6 +232,7 @@ class Cast(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Compound(Node):
|
||||
__slots__ = ('block_items', 'coord', '__weakref__')
|
||||
def __init__(self, block_items, coord=None):
|
||||
self.block_items = block_items
|
||||
self.coord = coord
|
||||
|
|
@ -236,6 +246,7 @@ class Compound(Node):
|
|||
attr_names = ()
|
||||
|
||||
class CompoundLiteral(Node):
|
||||
__slots__ = ('type', 'init', 'coord', '__weakref__')
|
||||
def __init__(self, type, init, coord=None):
|
||||
self.type = type
|
||||
self.init = init
|
||||
|
|
@ -250,6 +261,7 @@ class CompoundLiteral(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Constant(Node):
|
||||
__slots__ = ('type', 'value', 'coord', '__weakref__')
|
||||
def __init__(self, type, value, coord=None):
|
||||
self.type = type
|
||||
self.value = value
|
||||
|
|
@ -259,9 +271,10 @@ class Constant(Node):
|
|||
nodelist = []
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('type','value',)
|
||||
attr_names = ('type', 'value', )
|
||||
|
||||
class Continue(Node):
|
||||
__slots__ = ('coord', '__weakref__')
|
||||
def __init__(self, coord=None):
|
||||
self.coord = coord
|
||||
|
||||
|
|
@ -271,6 +284,7 @@ class Continue(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Decl(Node):
|
||||
__slots__ = ('name', 'quals', 'storage', 'funcspec', 'type', 'init', 'bitsize', 'coord', '__weakref__')
|
||||
def __init__(self, name, quals, storage, funcspec, type, init, bitsize, coord=None):
|
||||
self.name = name
|
||||
self.quals = quals
|
||||
|
|
@ -288,9 +302,10 @@ class Decl(Node):
|
|||
if self.bitsize is not None: nodelist.append(("bitsize", self.bitsize))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('name','quals','storage','funcspec',)
|
||||
attr_names = ('name', 'quals', 'storage', 'funcspec', )
|
||||
|
||||
class DeclList(Node):
|
||||
__slots__ = ('decls', 'coord', '__weakref__')
|
||||
def __init__(self, decls, coord=None):
|
||||
self.decls = decls
|
||||
self.coord = coord
|
||||
|
|
@ -304,6 +319,7 @@ class DeclList(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Default(Node):
|
||||
__slots__ = ('stmts', 'coord', '__weakref__')
|
||||
def __init__(self, stmts, coord=None):
|
||||
self.stmts = stmts
|
||||
self.coord = coord
|
||||
|
|
@ -317,6 +333,7 @@ class Default(Node):
|
|||
attr_names = ()
|
||||
|
||||
class DoWhile(Node):
|
||||
__slots__ = ('cond', 'stmt', 'coord', '__weakref__')
|
||||
def __init__(self, cond, stmt, coord=None):
|
||||
self.cond = cond
|
||||
self.stmt = stmt
|
||||
|
|
@ -331,6 +348,7 @@ class DoWhile(Node):
|
|||
attr_names = ()
|
||||
|
||||
class EllipsisParam(Node):
|
||||
__slots__ = ('coord', '__weakref__')
|
||||
def __init__(self, coord=None):
|
||||
self.coord = coord
|
||||
|
||||
|
|
@ -340,6 +358,7 @@ class EllipsisParam(Node):
|
|||
attr_names = ()
|
||||
|
||||
class EmptyStatement(Node):
|
||||
__slots__ = ('coord', '__weakref__')
|
||||
def __init__(self, coord=None):
|
||||
self.coord = coord
|
||||
|
||||
|
|
@ -349,6 +368,7 @@ class EmptyStatement(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Enum(Node):
|
||||
__slots__ = ('name', 'values', 'coord', '__weakref__')
|
||||
def __init__(self, name, values, coord=None):
|
||||
self.name = name
|
||||
self.values = values
|
||||
|
|
@ -359,9 +379,10 @@ class Enum(Node):
|
|||
if self.values is not None: nodelist.append(("values", self.values))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('name',)
|
||||
attr_names = ('name', )
|
||||
|
||||
class Enumerator(Node):
|
||||
__slots__ = ('name', 'value', 'coord', '__weakref__')
|
||||
def __init__(self, name, value, coord=None):
|
||||
self.name = name
|
||||
self.value = value
|
||||
|
|
@ -372,9 +393,10 @@ class Enumerator(Node):
|
|||
if self.value is not None: nodelist.append(("value", self.value))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('name',)
|
||||
attr_names = ('name', )
|
||||
|
||||
class EnumeratorList(Node):
|
||||
__slots__ = ('enumerators', 'coord', '__weakref__')
|
||||
def __init__(self, enumerators, coord=None):
|
||||
self.enumerators = enumerators
|
||||
self.coord = coord
|
||||
|
|
@ -388,6 +410,7 @@ class EnumeratorList(Node):
|
|||
attr_names = ()
|
||||
|
||||
class ExprList(Node):
|
||||
__slots__ = ('exprs', 'coord', '__weakref__')
|
||||
def __init__(self, exprs, coord=None):
|
||||
self.exprs = exprs
|
||||
self.coord = coord
|
||||
|
|
@ -401,6 +424,7 @@ class ExprList(Node):
|
|||
attr_names = ()
|
||||
|
||||
class FileAST(Node):
|
||||
__slots__ = ('ext', 'coord', '__weakref__')
|
||||
def __init__(self, ext, coord=None):
|
||||
self.ext = ext
|
||||
self.coord = coord
|
||||
|
|
@ -414,6 +438,7 @@ class FileAST(Node):
|
|||
attr_names = ()
|
||||
|
||||
class For(Node):
|
||||
__slots__ = ('init', 'cond', 'next', 'stmt', 'coord', '__weakref__')
|
||||
def __init__(self, init, cond, next, stmt, coord=None):
|
||||
self.init = init
|
||||
self.cond = cond
|
||||
|
|
@ -432,6 +457,7 @@ class For(Node):
|
|||
attr_names = ()
|
||||
|
||||
class FuncCall(Node):
|
||||
__slots__ = ('name', 'args', 'coord', '__weakref__')
|
||||
def __init__(self, name, args, coord=None):
|
||||
self.name = name
|
||||
self.args = args
|
||||
|
|
@ -446,6 +472,7 @@ class FuncCall(Node):
|
|||
attr_names = ()
|
||||
|
||||
class FuncDecl(Node):
|
||||
__slots__ = ('args', 'type', 'coord', '__weakref__')
|
||||
def __init__(self, args, type, coord=None):
|
||||
self.args = args
|
||||
self.type = type
|
||||
|
|
@ -460,6 +487,7 @@ class FuncDecl(Node):
|
|||
attr_names = ()
|
||||
|
||||
class FuncDef(Node):
|
||||
__slots__ = ('decl', 'param_decls', 'body', 'coord', '__weakref__')
|
||||
def __init__(self, decl, param_decls, body, coord=None):
|
||||
self.decl = decl
|
||||
self.param_decls = param_decls
|
||||
|
|
@ -477,6 +505,7 @@ class FuncDef(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Goto(Node):
|
||||
__slots__ = ('name', 'coord', '__weakref__')
|
||||
def __init__(self, name, coord=None):
|
||||
self.name = name
|
||||
self.coord = coord
|
||||
|
|
@ -485,9 +514,10 @@ class Goto(Node):
|
|||
nodelist = []
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('name',)
|
||||
attr_names = ('name', )
|
||||
|
||||
class ID(Node):
|
||||
__slots__ = ('name', 'coord', '__weakref__')
|
||||
def __init__(self, name, coord=None):
|
||||
self.name = name
|
||||
self.coord = coord
|
||||
|
|
@ -496,9 +526,10 @@ class ID(Node):
|
|||
nodelist = []
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('name',)
|
||||
attr_names = ('name', )
|
||||
|
||||
class IdentifierType(Node):
|
||||
__slots__ = ('names', 'coord', '__weakref__')
|
||||
def __init__(self, names, coord=None):
|
||||
self.names = names
|
||||
self.coord = coord
|
||||
|
|
@ -507,9 +538,10 @@ class IdentifierType(Node):
|
|||
nodelist = []
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('names',)
|
||||
attr_names = ('names', )
|
||||
|
||||
class If(Node):
|
||||
__slots__ = ('cond', 'iftrue', 'iffalse', 'coord', '__weakref__')
|
||||
def __init__(self, cond, iftrue, iffalse, coord=None):
|
||||
self.cond = cond
|
||||
self.iftrue = iftrue
|
||||
|
|
@ -526,6 +558,7 @@ class If(Node):
|
|||
attr_names = ()
|
||||
|
||||
class InitList(Node):
|
||||
__slots__ = ('exprs', 'coord', '__weakref__')
|
||||
def __init__(self, exprs, coord=None):
|
||||
self.exprs = exprs
|
||||
self.coord = coord
|
||||
|
|
@ -539,6 +572,7 @@ class InitList(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Label(Node):
|
||||
__slots__ = ('name', 'stmt', 'coord', '__weakref__')
|
||||
def __init__(self, name, stmt, coord=None):
|
||||
self.name = name
|
||||
self.stmt = stmt
|
||||
|
|
@ -549,9 +583,10 @@ class Label(Node):
|
|||
if self.stmt is not None: nodelist.append(("stmt", self.stmt))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('name',)
|
||||
attr_names = ('name', )
|
||||
|
||||
class NamedInitializer(Node):
|
||||
__slots__ = ('name', 'expr', 'coord', '__weakref__')
|
||||
def __init__(self, name, expr, coord=None):
|
||||
self.name = name
|
||||
self.expr = expr
|
||||
|
|
@ -567,6 +602,7 @@ class NamedInitializer(Node):
|
|||
attr_names = ()
|
||||
|
||||
class ParamList(Node):
|
||||
__slots__ = ('params', 'coord', '__weakref__')
|
||||
def __init__(self, params, coord=None):
|
||||
self.params = params
|
||||
self.coord = coord
|
||||
|
|
@ -580,6 +616,7 @@ class ParamList(Node):
|
|||
attr_names = ()
|
||||
|
||||
class PtrDecl(Node):
|
||||
__slots__ = ('quals', 'type', 'coord', '__weakref__')
|
||||
def __init__(self, quals, type, coord=None):
|
||||
self.quals = quals
|
||||
self.type = type
|
||||
|
|
@ -590,9 +627,10 @@ class PtrDecl(Node):
|
|||
if self.type is not None: nodelist.append(("type", self.type))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('quals',)
|
||||
attr_names = ('quals', )
|
||||
|
||||
class Return(Node):
|
||||
__slots__ = ('expr', 'coord', '__weakref__')
|
||||
def __init__(self, expr, coord=None):
|
||||
self.expr = expr
|
||||
self.coord = coord
|
||||
|
|
@ -605,6 +643,7 @@ class Return(Node):
|
|||
attr_names = ()
|
||||
|
||||
class Struct(Node):
|
||||
__slots__ = ('name', 'decls', 'coord', '__weakref__')
|
||||
def __init__(self, name, decls, coord=None):
|
||||
self.name = name
|
||||
self.decls = decls
|
||||
|
|
@ -616,9 +655,10 @@ class Struct(Node):
|
|||
nodelist.append(("decls[%d]" % i, child))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('name',)
|
||||
attr_names = ('name', )
|
||||
|
||||
class StructRef(Node):
|
||||
__slots__ = ('name', 'type', 'field', 'coord', '__weakref__')
|
||||
def __init__(self, name, type, field, coord=None):
|
||||
self.name = name
|
||||
self.type = type
|
||||
|
|
@ -631,9 +671,10 @@ class StructRef(Node):
|
|||
if self.field is not None: nodelist.append(("field", self.field))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('type',)
|
||||
attr_names = ('type', )
|
||||
|
||||
class Switch(Node):
|
||||
__slots__ = ('cond', 'stmt', 'coord', '__weakref__')
|
||||
def __init__(self, cond, stmt, coord=None):
|
||||
self.cond = cond
|
||||
self.stmt = stmt
|
||||
|
|
@ -648,6 +689,7 @@ class Switch(Node):
|
|||
attr_names = ()
|
||||
|
||||
class TernaryOp(Node):
|
||||
__slots__ = ('cond', 'iftrue', 'iffalse', 'coord', '__weakref__')
|
||||
def __init__(self, cond, iftrue, iffalse, coord=None):
|
||||
self.cond = cond
|
||||
self.iftrue = iftrue
|
||||
|
|
@ -664,6 +706,7 @@ class TernaryOp(Node):
|
|||
attr_names = ()
|
||||
|
||||
class TypeDecl(Node):
|
||||
__slots__ = ('declname', 'quals', 'type', 'coord', '__weakref__')
|
||||
def __init__(self, declname, quals, type, coord=None):
|
||||
self.declname = declname
|
||||
self.quals = quals
|
||||
|
|
@ -675,9 +718,10 @@ class TypeDecl(Node):
|
|||
if self.type is not None: nodelist.append(("type", self.type))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('declname','quals',)
|
||||
attr_names = ('declname', 'quals', )
|
||||
|
||||
class Typedef(Node):
|
||||
__slots__ = ('name', 'quals', 'storage', 'type', 'coord', '__weakref__')
|
||||
def __init__(self, name, quals, storage, type, coord=None):
|
||||
self.name = name
|
||||
self.quals = quals
|
||||
|
|
@ -690,10 +734,12 @@ class Typedef(Node):
|
|||
if self.type is not None: nodelist.append(("type", self.type))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('name','quals','storage',)
|
||||
attr_names = ('name', 'quals', 'storage', )
|
||||
|
||||
class Typename(Node):
|
||||
def __init__(self, quals, type, coord=None):
|
||||
__slots__ = ('name', 'quals', 'type', 'coord', '__weakref__')
|
||||
def __init__(self, name, quals, type, coord=None):
|
||||
self.name = name
|
||||
self.quals = quals
|
||||
self.type = type
|
||||
self.coord = coord
|
||||
|
|
@ -703,9 +749,10 @@ class Typename(Node):
|
|||
if self.type is not None: nodelist.append(("type", self.type))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('quals',)
|
||||
attr_names = ('name', 'quals', )
|
||||
|
||||
class UnaryOp(Node):
|
||||
__slots__ = ('op', 'expr', 'coord', '__weakref__')
|
||||
def __init__(self, op, expr, coord=None):
|
||||
self.op = op
|
||||
self.expr = expr
|
||||
|
|
@ -716,9 +763,10 @@ class UnaryOp(Node):
|
|||
if self.expr is not None: nodelist.append(("expr", self.expr))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('op',)
|
||||
attr_names = ('op', )
|
||||
|
||||
class Union(Node):
|
||||
__slots__ = ('name', 'decls', 'coord', '__weakref__')
|
||||
def __init__(self, name, decls, coord=None):
|
||||
self.name = name
|
||||
self.decls = decls
|
||||
|
|
@ -730,9 +778,10 @@ class Union(Node):
|
|||
nodelist.append(("decls[%d]" % i, child))
|
||||
return tuple(nodelist)
|
||||
|
||||
attr_names = ('name',)
|
||||
attr_names = ('name', )
|
||||
|
||||
class While(Node):
|
||||
__slots__ = ('cond', 'stmt', 'coord', '__weakref__')
|
||||
def __init__(self, cond, stmt, coord=None):
|
||||
self.cond = cond
|
||||
self.stmt = stmt
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# C code generator from pycparser AST nodes.
|
||||
#
|
||||
# Copyright (C) 2008-2012, Eli Bendersky
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#------------------------------------------------------------------------------
|
||||
from . import c_ast
|
||||
|
|
@ -15,8 +15,6 @@ class CGenerator(object):
|
|||
generic_visit.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.output = ''
|
||||
|
||||
# Statements start with indentation of self.indent_level spaces, using
|
||||
# the _make_indent method
|
||||
#
|
||||
|
|
@ -34,7 +32,7 @@ class CGenerator(object):
|
|||
if node is None:
|
||||
return ''
|
||||
else:
|
||||
return ''.join(self.visit(c) for c in node.children())
|
||||
return ''.join(self.visit(c) for c_name, c in node.children())
|
||||
|
||||
def visit_Constant(self, n):
|
||||
return n.value
|
||||
|
|
@ -83,19 +81,22 @@ class CGenerator(object):
|
|||
def visit_IdentifierType(self, n):
|
||||
return ' '.join(n.names)
|
||||
|
||||
def _visit_expr(self, n):
|
||||
if isinstance(n, c_ast.InitList):
|
||||
return '{' + self.visit(n) + '}'
|
||||
elif isinstance(n, c_ast.ExprList):
|
||||
return '(' + self.visit(n) + ')'
|
||||
else:
|
||||
return self.visit(n)
|
||||
|
||||
def visit_Decl(self, n, no_type=False):
|
||||
# no_type is used when a Decl is part of a DeclList, where the type is
|
||||
# explicitly only for the first delaration in a list.
|
||||
# explicitly only for the first declaration in a list.
|
||||
#
|
||||
s = n.name if no_type else self._generate_decl(n)
|
||||
if n.bitsize: s += ' : ' + self.visit(n.bitsize)
|
||||
if n.init:
|
||||
if isinstance(n.init, c_ast.InitList):
|
||||
s += ' = {' + self.visit(n.init) + '}'
|
||||
elif isinstance(n.init, c_ast.ExprList):
|
||||
s += ' = (' + self.visit(n.init) + ')'
|
||||
else:
|
||||
s += ' = ' + self.visit(n.init)
|
||||
s += ' = ' + self._visit_expr(n.init)
|
||||
return s
|
||||
|
||||
def visit_DeclList(self, n):
|
||||
|
|
@ -118,21 +119,13 @@ class CGenerator(object):
|
|||
def visit_ExprList(self, n):
|
||||
visited_subexprs = []
|
||||
for expr in n.exprs:
|
||||
if isinstance(expr, c_ast.ExprList):
|
||||
visited_subexprs.append('{' + self.visit(expr) + '}')
|
||||
else:
|
||||
visited_subexprs.append(self.visit(expr))
|
||||
visited_subexprs.append(self._visit_expr(expr))
|
||||
return ', '.join(visited_subexprs)
|
||||
|
||||
def visit_InitList(self, n):
|
||||
visited_subexprs = []
|
||||
for expr in n.exprs:
|
||||
if isinstance(expr, c_ast.ExprList):
|
||||
visited_subexprs.append('(' + self.visit(expr) + ')')
|
||||
elif isinstance(expr, c_ast.InitList):
|
||||
visited_subexprs.append('{' + self.visit(expr) + '}')
|
||||
else:
|
||||
visited_subexprs.append(self.visit(expr))
|
||||
visited_subexprs.append(self._visit_expr(expr))
|
||||
return ', '.join(visited_subexprs)
|
||||
|
||||
def visit_Enum(self, n):
|
||||
|
|
@ -195,9 +188,9 @@ class CGenerator(object):
|
|||
return 'continue;'
|
||||
|
||||
def visit_TernaryOp(self, n):
|
||||
s = self.visit(n.cond) + ' ? '
|
||||
s += self.visit(n.iftrue) + ' : '
|
||||
s += self.visit(n.iffalse)
|
||||
s = self._visit_expr(n.cond) + ' ? '
|
||||
s += self._visit_expr(n.iftrue) + ' : '
|
||||
s += self._visit_expr(n.iffalse)
|
||||
return s
|
||||
|
||||
def visit_If(self, n):
|
||||
|
|
@ -281,6 +274,9 @@ class CGenerator(object):
|
|||
s += ' = ' + self.visit(n.expr)
|
||||
return s
|
||||
|
||||
def visit_FuncDecl(self, n):
|
||||
return self._generate_type(n)
|
||||
|
||||
def _generate_struct_union(self, n, name):
|
||||
""" Generates code for structs and unions. name should be either
|
||||
'struct' or union.
|
||||
|
|
@ -384,7 +380,7 @@ class CGenerator(object):
|
|||
""" Visits 'n' and returns its string representation, parenthesized
|
||||
if the condition function applied to the node returns True.
|
||||
"""
|
||||
s = self.visit(n)
|
||||
s = self._visit_expr(n)
|
||||
if condition(n):
|
||||
return '(' + s + ')'
|
||||
else:
|
||||
|
|
@ -401,5 +397,3 @@ class CGenerator(object):
|
|||
"""
|
||||
return isinstance(n,( c_ast.Constant, c_ast.ID, c_ast.ArrayRef,
|
||||
c_ast.StructRef, c_ast.FuncCall))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# CLexer class: lexer for the C language
|
||||
#
|
||||
# Copyright (C) 2008-2013, Eli Bendersky
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#------------------------------------------------------------------------------
|
||||
import re
|
||||
|
|
@ -102,7 +102,8 @@ class CLexer(object):
|
|||
keywords = (
|
||||
'_BOOL', '_COMPLEX', 'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST',
|
||||
'CONTINUE', 'DEFAULT', 'DO', 'DOUBLE', 'ELSE', 'ENUM', 'EXTERN',
|
||||
'FLOAT', 'FOR', 'GOTO', 'IF', 'INLINE', 'INT', 'LONG', 'REGISTER',
|
||||
'FLOAT', 'FOR', 'GOTO', 'IF', 'INLINE', 'INT', 'LONG',
|
||||
'REGISTER', 'OFFSETOF',
|
||||
'RESTRICT', 'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT',
|
||||
'SWITCH', 'TYPEDEF', 'UNION', 'UNSIGNED', 'VOID',
|
||||
'VOLATILE', 'WHILE',
|
||||
|
|
@ -129,7 +130,7 @@ class CLexer(object):
|
|||
'TYPEID',
|
||||
|
||||
# constants
|
||||
'INT_CONST_DEC', 'INT_CONST_OCT', 'INT_CONST_HEX',
|
||||
'INT_CONST_DEC', 'INT_CONST_OCT', 'INT_CONST_HEX', 'INT_CONST_BIN',
|
||||
'FLOAT_CONST', 'HEX_FLOAT_CONST',
|
||||
'CHAR_CONST',
|
||||
'WCHAR_CONST',
|
||||
|
|
@ -183,12 +184,15 @@ class CLexer(object):
|
|||
|
||||
hex_prefix = '0[xX]'
|
||||
hex_digits = '[0-9a-fA-F]+'
|
||||
bin_prefix = '0[bB]'
|
||||
bin_digits = '[01]+'
|
||||
|
||||
# integer constants (K&R2: A.2.5.1)
|
||||
integer_suffix_opt = r'(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?'
|
||||
decimal_constant = '(0'+integer_suffix_opt+')|([1-9][0-9]*'+integer_suffix_opt+')'
|
||||
octal_constant = '0[0-7]*'+integer_suffix_opt
|
||||
hex_constant = hex_prefix+hex_digits+integer_suffix_opt
|
||||
bin_constant = bin_prefix+bin_digits+integer_suffix_opt
|
||||
|
||||
bad_octal_constant = '0[0-7]*[89]'
|
||||
|
||||
|
|
@ -302,7 +306,7 @@ class CLexer(object):
|
|||
r'pragma'
|
||||
pass
|
||||
|
||||
t_pppragma_ignore = ' \t<>.-{}();+-*/$%@&^~!?:,0123456789'
|
||||
t_pppragma_ignore = ' \t<>.-{}();=+-*/$%@&^~!?:,0123456789'
|
||||
|
||||
@TOKEN(string_literal)
|
||||
def t_pppragma_STR(self, t): pass
|
||||
|
|
@ -419,6 +423,10 @@ class CLexer(object):
|
|||
def t_INT_CONST_HEX(self, t):
|
||||
return t
|
||||
|
||||
@TOKEN(bin_constant)
|
||||
def t_INT_CONST_BIN(self, t):
|
||||
return t
|
||||
|
||||
@TOKEN(bad_octal_constant)
|
||||
def t_BAD_CONST_OCT(self, t):
|
||||
msg = "Invalid octal constant"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# CParser class: Parser and AST builder for the C language
|
||||
#
|
||||
# Copyright (C) 2008-2013, Eli Bendersky
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#------------------------------------------------------------------------------
|
||||
import re
|
||||
|
|
@ -23,7 +23,8 @@ class CParser(PLYParser):
|
|||
lextab='pycparser.lextab',
|
||||
yacc_optimize=True,
|
||||
yacctab='pycparser.yacctab',
|
||||
yacc_debug=False):
|
||||
yacc_debug=False,
|
||||
taboutputdir=''):
|
||||
""" Create a new CParser.
|
||||
|
||||
Some arguments for controlling the debug/optimization
|
||||
|
|
@ -64,6 +65,10 @@ class CParser(PLYParser):
|
|||
yacc_debug:
|
||||
Generate a parser.out file that explains how yacc
|
||||
built the parsing table from the grammar.
|
||||
|
||||
taboutputdir:
|
||||
Set this parameter to control the location of generated
|
||||
lextab and yacctab files.
|
||||
"""
|
||||
self.clex = CLexer(
|
||||
error_func=self._lex_error_func,
|
||||
|
|
@ -73,7 +78,8 @@ class CParser(PLYParser):
|
|||
|
||||
self.clex.build(
|
||||
optimize=lex_optimize,
|
||||
lextab=lextab)
|
||||
lextab=lextab,
|
||||
outputdir=taboutputdir)
|
||||
self.tokens = self.clex.tokens
|
||||
|
||||
rules_with_opt = [
|
||||
|
|
@ -85,6 +91,7 @@ class CParser(PLYParser):
|
|||
'expression',
|
||||
'identifier_list',
|
||||
'init_declarator_list',
|
||||
'initializer_list',
|
||||
'parameter_type_list',
|
||||
'specifier_qualifier_list',
|
||||
'block_item_list',
|
||||
|
|
@ -100,7 +107,8 @@ class CParser(PLYParser):
|
|||
start='translation_unit_or_empty',
|
||||
debug=yacc_debug,
|
||||
optimize=yacc_optimize,
|
||||
tabmodule=yacctab)
|
||||
tabmodule=yacctab,
|
||||
outputdir=taboutputdir)
|
||||
|
||||
# Stack of scopes for keeping track of symbols. _scope_stack[-1] is
|
||||
# the current (topmost) scope. Each scope is a dictionary that
|
||||
|
|
@ -211,13 +219,11 @@ class CParser(PLYParser):
|
|||
# The basic declaration here is 'int c', and the pointer and
|
||||
# the array are the modifiers.
|
||||
#
|
||||
# Basic declarations are represented by TypeDecl (from module
|
||||
# c_ast) and the modifiers are FuncDecl, PtrDecl and
|
||||
# ArrayDecl.
|
||||
# Basic declarations are represented by TypeDecl (from module c_ast) and the
|
||||
# modifiers are FuncDecl, PtrDecl and ArrayDecl.
|
||||
#
|
||||
# The standard states that whenever a new modifier is parsed,
|
||||
# it should be added to the end of the list of modifiers. For
|
||||
# example:
|
||||
# The standard states that whenever a new modifier is parsed, it should be
|
||||
# added to the end of the list of modifiers. For example:
|
||||
#
|
||||
# K&R2 A.8.6.2: Array Declarators
|
||||
#
|
||||
|
|
@ -236,7 +242,6 @@ class CParser(PLYParser):
|
|||
# useful for pointers, that can come as a chain from the rule
|
||||
# p_pointer. In this case, the whole modifier list is spliced
|
||||
# into the new location.
|
||||
#
|
||||
def _type_modify_decl(self, decl, modifier):
|
||||
""" Tacks a type modifier on a declarator, and returns
|
||||
the modified declarator.
|
||||
|
|
@ -983,28 +988,52 @@ class CParser(PLYParser):
|
|||
p[0] = p[2]
|
||||
|
||||
def p_direct_declarator_3(self, p):
|
||||
""" direct_declarator : direct_declarator LBRACKET assignment_expression_opt RBRACKET
|
||||
""" direct_declarator : direct_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET
|
||||
"""
|
||||
quals = (p[3] if len(p) > 5 else []) or []
|
||||
# Accept dimension qualifiers
|
||||
# Per C99 6.7.5.3 p7
|
||||
arr = c_ast.ArrayDecl(
|
||||
type=None,
|
||||
dim=p[3],
|
||||
dim=p[4] if len(p) > 5 else p[3],
|
||||
dim_quals=quals,
|
||||
coord=p[1].coord)
|
||||
|
||||
p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
|
||||
|
||||
def p_direct_declarator_4(self, p):
|
||||
""" direct_declarator : direct_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET
|
||||
| direct_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET
|
||||
"""
|
||||
# Using slice notation for PLY objects doesn't work in Python 3 for the
|
||||
# version of PLY embedded with pycparser; see PLY Google Code issue 30.
|
||||
# Work around that here by listing the two elements separately.
|
||||
listed_quals = [item if isinstance(item, list) else [item]
|
||||
for item in [p[3],p[4]]]
|
||||
dim_quals = [qual for sublist in listed_quals for qual in sublist
|
||||
if qual is not None]
|
||||
arr = c_ast.ArrayDecl(
|
||||
type=None,
|
||||
dim=p[5],
|
||||
dim_quals=dim_quals,
|
||||
coord=p[1].coord)
|
||||
|
||||
p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
|
||||
|
||||
# Special for VLAs
|
||||
#
|
||||
def p_direct_declarator_4(self, p):
|
||||
""" direct_declarator : direct_declarator LBRACKET TIMES RBRACKET
|
||||
def p_direct_declarator_5(self, p):
|
||||
""" direct_declarator : direct_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET
|
||||
"""
|
||||
arr = c_ast.ArrayDecl(
|
||||
type=None,
|
||||
dim=c_ast.ID(p[3], self._coord(p.lineno(3))),
|
||||
dim=c_ast.ID(p[4], self._coord(p.lineno(4))),
|
||||
dim_quals=p[3] if p[3] != None else [],
|
||||
coord=p[1].coord)
|
||||
|
||||
p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
|
||||
|
||||
def p_direct_declarator_5(self, p):
|
||||
def p_direct_declarator_6(self, p):
|
||||
""" direct_declarator : direct_declarator LPAREN parameter_type_list RPAREN
|
||||
| direct_declarator LPAREN identifier_list_opt RPAREN
|
||||
"""
|
||||
|
|
@ -1037,11 +1066,30 @@ class CParser(PLYParser):
|
|||
| TIMES type_qualifier_list_opt pointer
|
||||
"""
|
||||
coord = self._coord(p.lineno(1))
|
||||
|
||||
p[0] = c_ast.PtrDecl(
|
||||
quals=p[2] or [],
|
||||
type=p[3] if len(p) > 3 else None,
|
||||
coord=coord)
|
||||
# Pointer decls nest from inside out. This is important when different
|
||||
# levels have different qualifiers. For example:
|
||||
#
|
||||
# char * const * p;
|
||||
#
|
||||
# Means "pointer to const pointer to char"
|
||||
#
|
||||
# While:
|
||||
#
|
||||
# char ** const p;
|
||||
#
|
||||
# Means "const pointer to pointer to char"
|
||||
#
|
||||
# So when we construct PtrDecl nestings, the leftmost pointer goes in
|
||||
# as the most nested type.
|
||||
nested_type = c_ast.PtrDecl(quals=p[2] or [], type=None, coord=coord)
|
||||
if len(p) > 3:
|
||||
tail_type = p[3]
|
||||
while tail_type.type is not None:
|
||||
tail_type = tail_type.type
|
||||
tail_type.type = nested_type
|
||||
p[0] = p[3]
|
||||
else:
|
||||
p[0] = nested_type
|
||||
|
||||
def p_type_qualifier_list(self, p):
|
||||
""" type_qualifier_list : type_qualifier
|
||||
|
|
@ -1101,6 +1149,7 @@ class CParser(PLYParser):
|
|||
#
|
||||
else:
|
||||
decl = c_ast.Typename(
|
||||
name='',
|
||||
quals=spec['qual'],
|
||||
type=p[2] or c_ast.TypeDecl(None, None, None),
|
||||
coord=self._coord(p.lineno(2)))
|
||||
|
|
@ -1125,10 +1174,13 @@ class CParser(PLYParser):
|
|||
p[0] = p[1]
|
||||
|
||||
def p_initializer_2(self, p):
|
||||
""" initializer : brace_open initializer_list brace_close
|
||||
""" initializer : brace_open initializer_list_opt brace_close
|
||||
| brace_open initializer_list COMMA brace_close
|
||||
"""
|
||||
p[0] = p[2]
|
||||
if p[2] is None:
|
||||
p[0] = c_ast.InitList([], self._coord(p.lineno(1)))
|
||||
else:
|
||||
p[0] = p[2]
|
||||
|
||||
def p_initializer_list(self, p):
|
||||
""" initializer_list : designation_opt initializer
|
||||
|
|
@ -1172,6 +1224,7 @@ class CParser(PLYParser):
|
|||
#~ print '=========='
|
||||
|
||||
typename = c_ast.Typename(
|
||||
name='',
|
||||
quals=p[1]['qual'],
|
||||
type=p[2] or c_ast.TypeDecl(None, None, None),
|
||||
coord=self._coord(p.lineno(2)))
|
||||
|
|
@ -1211,6 +1264,7 @@ class CParser(PLYParser):
|
|||
arr = c_ast.ArrayDecl(
|
||||
type=None,
|
||||
dim=p[3],
|
||||
dim_quals=[],
|
||||
coord=p[1].coord)
|
||||
|
||||
p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
|
||||
|
|
@ -1221,6 +1275,7 @@ class CParser(PLYParser):
|
|||
p[0] = c_ast.ArrayDecl(
|
||||
type=c_ast.TypeDecl(None, None, None),
|
||||
dim=p[2],
|
||||
dim_quals=[],
|
||||
coord=self._coord(p.lineno(1)))
|
||||
|
||||
def p_direct_abstract_declarator_4(self, p):
|
||||
|
|
@ -1229,6 +1284,7 @@ class CParser(PLYParser):
|
|||
arr = c_ast.ArrayDecl(
|
||||
type=None,
|
||||
dim=c_ast.ID(p[3], self._coord(p.lineno(3))),
|
||||
dim_quals=[],
|
||||
coord=p[1].coord)
|
||||
|
||||
p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
|
||||
|
|
@ -1239,6 +1295,7 @@ class CParser(PLYParser):
|
|||
p[0] = c_ast.ArrayDecl(
|
||||
type=c_ast.TypeDecl(None, None, None),
|
||||
dim=c_ast.ID(p[3], self._coord(p.lineno(3))),
|
||||
dim_quals=[],
|
||||
coord=self._coord(p.lineno(1)))
|
||||
|
||||
def p_direct_abstract_declarator_6(self, p):
|
||||
|
|
@ -1322,7 +1379,8 @@ class CParser(PLYParser):
|
|||
|
||||
def p_iteration_statement_4(self, p):
|
||||
""" iteration_statement : FOR LPAREN declaration expression_opt SEMI expression_opt RPAREN statement """
|
||||
p[0] = c_ast.For(c_ast.DeclList(p[3]), p[4], p[6], p[8], self._coord(p.lineno(1)))
|
||||
p[0] = c_ast.For(c_ast.DeclList(p[3], self._coord(p.lineno(1))),
|
||||
p[4], p[6], p[8], self._coord(p.lineno(1)))
|
||||
|
||||
def p_jump_statement_1(self, p):
|
||||
""" jump_statement : GOTO ID SEMI """
|
||||
|
|
@ -1525,6 +1583,14 @@ class CParser(PLYParser):
|
|||
""" primary_expression : LPAREN expression RPAREN """
|
||||
p[0] = p[2]
|
||||
|
||||
def p_primary_expression_5(self, p):
|
||||
""" primary_expression : OFFSETOF LPAREN type_name COMMA identifier RPAREN
|
||||
"""
|
||||
coord = self._coord(p.lineno(1))
|
||||
p[0] = c_ast.FuncCall(c_ast.ID(p[1], coord),
|
||||
c_ast.ExprList([p[3], p[5]], coord),
|
||||
coord)
|
||||
|
||||
def p_argument_expression_list(self, p):
|
||||
""" argument_expression_list : assignment_expression
|
||||
| argument_expression_list COMMA assignment_expression
|
||||
|
|
@ -1543,6 +1609,7 @@ class CParser(PLYParser):
|
|||
""" constant : INT_CONST_DEC
|
||||
| INT_CONST_OCT
|
||||
| INT_CONST_HEX
|
||||
| INT_CONST_BIN
|
||||
"""
|
||||
p[0] = c_ast.Constant(
|
||||
'int', p[1], self._coord(p.lineno(1)))
|
||||
|
|
@ -1585,7 +1652,7 @@ class CParser(PLYParser):
|
|||
p[0] = c_ast.Constant(
|
||||
'string', p[1], self._coord(p.lineno(1)))
|
||||
else:
|
||||
p[1].value = p[1].value.rstrip[:-1] + p[2][1:]
|
||||
p[1].value = p[1].value.rstrip()[:-1] + p[2][2:]
|
||||
p[0] = p[1]
|
||||
|
||||
def p_brace_open(self, p):
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -4,7 +4,7 @@
|
|||
# PLYParser class and other utilites for simplifying programming
|
||||
# parsers with PLY
|
||||
#
|
||||
# Copyright (C) 2008-2012, Eli Bendersky
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
|
|
@ -15,6 +15,7 @@ class Coord(object):
|
|||
- Line number
|
||||
- (optional) column number, for the Lexer
|
||||
"""
|
||||
__slots__ = ('file', 'line', 'column', '__weakref__')
|
||||
def __init__(self, file, line, column=None):
|
||||
self.file = file
|
||||
self.line = line
|
||||
|
|
@ -52,4 +53,3 @@ class PLYParser(object):
|
|||
|
||||
def _parse_error(self, msg, coord):
|
||||
raise ParseError("%s: %s" % (coord, msg))
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue