pycparser的语法树节点可由_c_ast.cfg配置并生成,默认情况下其提供了以下节点(Node):
在该文件的原文中是按照如下规则标记属性值的:
# 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
即:
<name>*
的,是一个子节点
<name>**
的,是子节点序列
<name>
的,是一个属性值
数组声明,其拥有以下属性值:
当其为一位数组时,该
type
是一个Node,TODO
dim
是一个Node,是维度,TODO
Demo
int length = 10;
int arr[5][length] = { 0 };
FileAST(ext=[Decl(name='length',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='length',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=Constant(type='int',
value='10'
),
bitsize=None
),
Decl(name='arr',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=ArrayDecl(type=ArrayDecl(type=TypeDecl(declname='arr',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
dim=ID(name='length'
),
dim_quals=[
]
),
dim=Constant(type='int',
value='5'
),
dim_quals=[
]
),
init=InitList(exprs=[Constant(type='int',
value='0'
)
]
),
bitsize=None
)
]
)
数组值引用,其拥有以下属性值:
name
subscript
Demo
int array[10] = { 0 };
int val = array[5];
FileAST(ext=[Decl(name='array',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=ArrayDecl(type=TypeDecl(declname='array',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
dim=Constant(type='int',
value='10'
),
dim_quals=[
]
),
init=InitList(exprs=[Constant(type='int',
value='0'
)
]
),
bitsize=None
),
Decl(name='val',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='val',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=ArrayRef(name=ID(name='array'
),
subscript=Constant(type='int',
value='5'
)
),
bitsize=None
)
]
)
赋值操作符,有以下几种:
=
*=
/=
%=
+=
-=
<<=
>>=
&=
|=
^=
其拥有以下属性值:
op
类型为字符串,是上述操作符的字符串形式
lvalue
左值
rvalue
右值
Demo
void func()
{
int val = 0;
val += 1;
}
FileAST(ext=[FuncDef(decl=Decl(name='func',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=FuncDecl(args=None,
type=TypeDecl(declname='func',
quals=[
],
align=None,
type=IdentifierType(names=['void'
]
)
)
),
init=None,
bitsize=None
),
param_decls=None,
body=Compound(block_items=[Decl(name='val',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='val',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=Constant(type='int',
value='0'
),
bitsize=None
),
Assignment(op='+=',
lvalue=ID(name='val'
),
rvalue=Constant(type='int',
value='1'
)
)
]
)
)
]
)
字节对齐,即C11中的 _Alignas
,C标准学习笔记 > 6 7 5 字节对齐说明符,其拥有以下属性:
alignment
是一个Node,含义为对齐参数
Demo
int _Alignas(8) a;
int b;
FileAST(ext=[Decl(name='a',
quals=[
],
align=[Alignas(alignment=Constant(type='int',
value='8'
)
)
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=None,
bitsize=None
),
Decl(name='b',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='b',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=None,
bitsize=None
)
]
)
二进制运算符,有以下几种:
+
-
*
/
%
|
&
~
^
<<
>>
||
&&
!
<
>
<=
>=
==
!=
Dataview (inline field '='): Error: -- PARSING FAILED -------------------------------------------------- > 1 | = | ^ Expected one of the following: '(', 'null', boolean, date, duration, file link, list ('[1, 2, 3]'), negated field, number, object ('{ a: 1, b: 2 }'), string, variable
其拥有如下属性:
op
类型为字符串,是上述操作符的字符串形式
TODO.
Demo
int a = 1;
int b = a == 1;
FileAST(ext=[Decl(name='a',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=Constant(type='int',
value='1'
),
bitsize=None
),
Decl(name='b',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='b',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=BinaryOp(op='==',
left=ID(name='a'
),
right=Constant(type='int',
value='1'
)
),
bitsize=None
)
]
)
Demo
void func()
{
while(1)
{
break;
}
}
FileAST(ext=[FuncDef(decl=Decl(name='func',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=FuncDecl(args=None,
type=TypeDecl(declname='func',
quals=[
],
align=None,
type=IdentifierType(names=['void'
]
)
)
),
init=None,
bitsize=None
),
param_decls=None,
body=Compound(block_items=[While(cond=Constant(type='int',
value='1'
),
stmt=Compound(block_items=[Break()
]
)
)
]
)
)
]
)
Demo
int *p = (int[]) { 1, 2, 3 };
FileAST(ext=[Decl(name='p',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=PtrDecl(quals=[
],
type=TypeDecl(declname='p',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
)
),
init=CompoundLiteral(type=Typename(name=None,
quals=[
],
align=None,
type=ArrayDecl(type=TypeDecl(declname=None,
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
dim=None,
dim_quals=[
]
)
),
init=InitList(exprs=[Constant(type='int',
value='1'
),
Constant(type='int',
value='2'
),
Constant(type='int',
value='3'
)
]
)
),
bitsize=None
)
]
)
即常量,其属性有:
type
value
Demo
const int a = 1;
int b = 0;
FileAST(ext=[Decl(name='a',
quals=['const'
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='a',
quals=['const'
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=Constant(type='int',
value='1'
),
bitsize=None
),
Decl(name='b',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='b',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=Constant(type='int',
value='1'
),
bitsize=None
)
]
)
所有声明语句均为Decl,
其属性有:
name
name
仅为声明对象的名字,类型为字符串
quals
quals
为对象的限定符,包含:
const
volatile
restrict
align
即C语言中的字节对齐说明符:C标准学习笔记 > 6 7 5 字节对齐说明符
Demo
_Alignas(char) int a;
FileAST(ext=[Decl(name='a',
quals=[
],
align=[Alignas(alignment=Typename(name=None,
quals=[
],
align=None,
type=TypeDecl(declname=None,
quals=[
],
align=None,
type=IdentifierType(names=['char'
]
)
)
)
)
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=None,
bitsize=None
)
]
)
_Alignas(2) int a;
FileAST(ext=[Decl(name='a',
quals=[
],
align=[Alignas(alignment=Constant(type='int',
value='2'
)
)
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=None,
bitsize=None
)
]
)
storge
storage` 为C语言的储存类型说明符,详见:C标准学习笔记 > 6.7.1 储存类型说明符
typedef
extern
static
_Thread_local
auto
register
funcspec
为C语言的函数说明符,详见:C标准学习笔记 > 6.7.4 函数说明符
最小示例:
int a;
FileAST(ext=[Decl(name='a',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=None,
bitsize=None
)
]
)
变量示例:
int a, b;
int mprint(char* fmt, ...);
;
Demo
enum enum_type { a, b, c };
enum enum_type obj;
则其中的 obj
即为 Enum
, a
则为 Enumerator
, { a, b, c }
则为 EnumeratorList
FileAST(ext=[Decl(name=None,
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=Enum(name='enum_type',
values=EnumeratorList(enumerators=[Enumerator(name='a',
value=None
),
Enumerator(name='b',
value=None
),
Enumerator(name='c',
value=None
)
]
)
),
init=None,
bitsize=None
),
Decl(name='obj',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='obj',
quals=[
],
align=None,
type=Enum(name='enum_type',
values=None
)
),
init=None,
bitsize=None
)
]
)
Demo
enum enum_type { a, b, c };
enum enum_type obj;
则其中的 obj
即为 Enum
, a
则为 Enumerator
, { a, b, c }
则为 EnumeratorList
FileAST(ext=[Decl(name=None,
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=Enum(name='enum_type',
values=EnumeratorList(enumerators=[Enumerator(name='a',
value=None
),
Enumerator(name='b',
value=None
),
Enumerator(name='c',
value=None
)
]
)
),
init=None,
bitsize=None
),
Decl(name='obj',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='obj',
quals=[
],
align=None,
type=Enum(name='enum_type',
values=None
)
),
init=None,
bitsize=None
)
]
)
Demo
enum enum_type { a, b, c };
enum enum_type obj;
则其中的 obj
即为 Enum
, a
则为 Enumerator
, { a, b, c }
则为 EnumeratorList
FileAST(ext=[Decl(name=None,
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=Enum(name='enum_type',
values=EnumeratorList(enumerators=[Enumerator(name='a',
value=None
),
Enumerator(name='b',
value=None
),
Enumerator(name='c',
value=None
)
]
)
),
init=None,
bitsize=None
),
Decl(name='obj',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='obj',
quals=[
],
align=None,
type=Enum(name='enum_type',
values=None
)
),
init=None,
bitsize=None
)
]
)
Demo
int a, b, c = (a = 1, b = 2);
expression list以逗号为分隔,其表达式值为最后一个语句的值,此时的 a
、 b
、 c
分别为 1
、 2
、 2
。
FileAST(ext=[Decl(name='a',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=None,
bitsize=None
),
Decl(name='b',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='b',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=None,
bitsize=None
),
Decl(name='c',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='c',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=ExprList(exprs=[Assignment(op='=',
lvalue=ID(name='a'
),
rvalue=Constant(type='int',
value='1'
)
),
Assignment(op='=',
lvalue=ID(name='b'
),
rvalue=Constant(type='int',
value='2'
)
)
]
),
bitsize=None
)
]
)
FileAST作为AST的顶部,表示经过预处理后的单个C文件,也是C语言标准中的术语 翻译单元
,其包含外部声明列表("external-declaration"s),即声明(Decl)、Typedef或函数定义(FuncDef)。
其拥有属性值:
ext
是子节点序列,元素即为上述的"external-declaration"s
args
type
int a;
FileAST(ext=[Decl(name='a',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=None,
bitsize=None
)
]
)
Demo
int a[3] = { 1, 2, 3 };
FileAST(ext=[Decl(name='a',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=ArrayDecl(type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
dim=Constant(type='int',
value='3'
),
dim_quals=[
]
),
init=InitList(exprs=[Constant(type='int',
value='1'
),
Constant(type='int',
value='2'
),
Constant(type='int',
value='3'
)
]
),
bitsize=None
)
]
)
Demo
struct { int a; int b; } obj = { .a = 1, .b = 2 };
FileAST(ext=[Decl(name='obj',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='obj',
quals=[
],
align=None,
type=Struct(name=None,
decls=[Decl(name='a',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=None,
bitsize=None
),
Decl(name='b',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='b',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
),
init=None,
bitsize=None
)
]
)
),
init=InitList(exprs=[NamedInitializer(name=[ID(name='a'
)
],
expr=Constant(type='int',
value='1'
)
),
NamedInitializer(name=[ID(name='b'
)
],
expr=Constant(type='int',
value='2'
)
)
]
),
bitsize=None
)
]
)
Demo
int *a;
FileAST(ext=[Decl(name='a',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=PtrDecl(quals=[
],
type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['int'
]
)
)
),
init=None,
bitsize=None
)
]
)
Demo
void func(int);
Demo
char a = ! 0xf0;
FileAST(ext=[Decl(name='a',
quals=[
],
align=[
],
storage=[
],
funcspec=[
],
type=TypeDecl(declname='a',
quals=[
],
align=None,
type=IdentifierType(names=['char'
]
)
),
init=UnaryOp(op='!',
expr=Constant(type='int',
value='0xf0'
)
),
bitsize=None
)
]
)