抽象语法树(c_ast)

#pycpraser #C-Language #编译原理

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> 的,是一个属性值

ArrayDecl

数组声明,其拥有以下属性值:

  • type*
  • dim**
  • dim_equals

当其为一位数组时,该

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
                  )
            ]
        )

ArrayRef

数组值引用,其拥有以下属性值:

  • name*
  • subscript*

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
                  )
            ]
        )

Assignment

赋值操作符,有以下几种:

  • =
  • *=
  • /=
  • %=
  • +=
  • -=
  • <<=
  • >>=
  • &=
  • |=
  • ^=

其拥有以下属性值:

  • op
  • lvalue*
  • rvalue*

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'
                                                                           )
                                                           )
                                               ]
                                   )
                     )
            ]
        )

Alignas

字节对齐,即C11中的 _AlignasC标准学习笔记 > 6 7 5 字节对齐说明符,其拥有以下属性:

  • alignment*

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
                  )
            ]
        )

BinaryOp

二进制运算符,有以下几种:

  • +
  • -
  • *
  • /
  • %
  • |
  • &
  • ~
  • ^
  • <<
  • >>
  • ||
  • &&
  • !
  • <
  • >
  • <=
  • >=
  • ==
  • !=

其拥有如下属性:

  • op
  • left*
  • right*

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
                  )
            ]
        )

Break

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()
                                                                                ]
                                                                    )
                                                      )
                                               ]
                                   )
                     )
            ]
        )

Case

Cast(强制类型转换)

Compound

C标准学习笔记 > 6 8 2 Compound statement 复合语句,即'块',block

6.8.2 Compound statement(复合语句,即'块',block)

复合语句即由花括号及其包含的可选块序列 { block-item-list(opt) } 构成,符合语句必须包含花括号。

语义
一个 Compound statement 就是一个块(block)。

CompoundLiteral

C标准学习笔记 > 6.5.2.5 复合字面量(Compound literals)
6.5.2.5 复合字面量(Compound literals)
6.5.2.5 复合字面量(Compound literals)

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
                  )
            ]
        )

Constant

即常量,其属性有:

  • type
  • value

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
                  )
            ]
        )

Continue

Decl

所有声明语句均为Decl,
其属性有:

  • name
  • quals
  • align
  • storage
  • funcspec
  • type*
  • init*
  • bitsize*

name

name 仅为声明对象的名字,类型为字符串

quals

quals 为对象的限定符,包含:

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
    当然,同笔记中所言:
    1. 除了之外 _Thread_local 可以和 staticextern 联合使用以外,一个变量最多使用一个储存类型说明符。

funcspec 为C语言的函数说明符,详见:C标准学习笔记 > 6.7.4 函数说明符

Demo

最小示例:

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
                  )
            ]
        )

变量示例:

DeclList

int a, b;

Default

DoWhile

EllipsisParam

int mprint(char* fmt, ...);

EmptyStatement

;

Enum

Demo

enum enum_type { a, b, c };
enum enum_type obj;

则其中的 obj 即为 Enuma 则为 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
                  )
            ]
        )

Enumerator

Demo

enum enum_type { a, b, c };
enum enum_type obj;

则其中的 obj 即为 Enuma 则为 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
                  )
            ]
        )

EnumeratorList

Demo

enum enum_type { a, b, c };
enum enum_type obj;

则其中的 obj 即为 Enuma 则为 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
                  )
            ]
        )

ExprList

Demo

int a, b, c = (a = 1, b = 2);

expression list以逗号为分隔,其表达式值为最后一个语句的值,此时的 abc 分别为 122

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

FileAST作为AST的顶部,表示经过预处理后的单个C文件,也是C语言标准中的术语 翻译单元 ,其包含外部声明列表("external-declaration"s),即声明(Decl)、Typedef或函数定义(FuncDef)。

其拥有属性值:

  • ext**

ext
是子节点序列,元素即为上述的"external-declaration"s

For

FuncCall

FuncDecl

args

type

FuncDef

Goto

IdentifierType

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
                  )
            ]
        )

InitList

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
                  )
            ]
        )

NamedInitializer

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
                  )
            ]
        )

pragma

Demo

#pragma once
FileAST(ext=[Pragma(string='once'
                    )
            ]
        )

PtrDecl

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
                  )
            ]
        )

Return

Struct

TernaryOp

TypeDecl

Typename

Demo

void func(int);

UnaryOp

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
                  )
            ]
        )

Union

While