github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/ast/ast.go (about)

     1  // Copyright 2017 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  // Package ast parses and formats sys files.
     5  package ast
     6  
     7  // Pos represents source info for AST nodes.
     8  type Pos struct {
     9  	File string
    10  	Off  int // byte offset, starting at 0
    11  	Line int // line number, starting at 1
    12  	Col  int // column number, starting at 1 (byte count)
    13  }
    14  
    15  // Description contains top-level nodes of a parsed sys description.
    16  type Description struct {
    17  	Nodes []Node
    18  }
    19  
    20  // Node is AST node interface.
    21  type Node interface {
    22  	Info() (pos Pos, typ, name string)
    23  	// Clone makes a deep copy of the node.
    24  	Clone() Node
    25  	// walk calls callback cb for all child nodes of this node.
    26  	// Note: it's not recursive. Use Recursive helper for recursive walk.
    27  	walk(cb func(Node))
    28  }
    29  
    30  type Flags[T FlagValue] interface {
    31  	SetValues(values []T)
    32  	GetValues() []T
    33  	GetPos() Pos
    34  }
    35  
    36  type FlagValue interface {
    37  	GetName() string
    38  }
    39  
    40  // Top-level AST nodes.
    41  
    42  type NewLine struct {
    43  	Pos Pos
    44  }
    45  
    46  func (n *NewLine) Info() (Pos, string, string) {
    47  	return n.Pos, tok2str[tokNewLine], ""
    48  }
    49  
    50  type Comment struct {
    51  	Pos  Pos
    52  	Text string
    53  }
    54  
    55  func (n *Comment) Info() (Pos, string, string) {
    56  	return n.Pos, tok2str[tokComment], ""
    57  }
    58  
    59  type Meta struct {
    60  	Pos   Pos
    61  	Value *Type
    62  }
    63  
    64  func (n *Meta) Info() (Pos, string, string) {
    65  	return n.Pos, "meta", n.Value.Ident
    66  }
    67  
    68  type Include struct {
    69  	Pos  Pos
    70  	File *String
    71  }
    72  
    73  func (n *Include) Info() (Pos, string, string) {
    74  	return n.Pos, tok2str[tokInclude], ""
    75  }
    76  
    77  type Incdir struct {
    78  	Pos Pos
    79  	Dir *String
    80  }
    81  
    82  func (n *Incdir) Info() (Pos, string, string) {
    83  	return n.Pos, tok2str[tokInclude], ""
    84  }
    85  
    86  type Define struct {
    87  	Pos   Pos
    88  	Name  *Ident
    89  	Value *Int
    90  }
    91  
    92  func (n *Define) Info() (Pos, string, string) {
    93  	return n.Pos, tok2str[tokDefine], n.Name.Name
    94  }
    95  
    96  type Resource struct {
    97  	Pos    Pos
    98  	Name   *Ident
    99  	Base   *Type
   100  	Values []*Int
   101  }
   102  
   103  func (n *Resource) Info() (Pos, string, string) {
   104  	return n.Pos, tok2str[tokResource], n.Name.Name
   105  }
   106  
   107  type Call struct {
   108  	Pos      Pos
   109  	Name     *Ident
   110  	CallName string
   111  	NR       uint64
   112  	Args     []*Field
   113  	Ret      *Type
   114  	Attrs    []*Type
   115  }
   116  
   117  func (n *Call) Info() (Pos, string, string) {
   118  	return n.Pos, "syscall", n.Name.Name
   119  }
   120  
   121  type Struct struct {
   122  	Pos      Pos
   123  	Name     *Ident
   124  	Fields   []*Field
   125  	Attrs    []*Type
   126  	Comments []*Comment
   127  	IsUnion  bool
   128  }
   129  
   130  func (n *Struct) Info() (Pos, string, string) {
   131  	typ := "struct"
   132  	if n.IsUnion {
   133  		typ = "union"
   134  	}
   135  	return n.Pos, typ, n.Name.Name
   136  }
   137  
   138  type IntFlags struct {
   139  	Pos    Pos
   140  	Name   *Ident
   141  	Values []*Int
   142  }
   143  
   144  func (n *IntFlags) Info() (Pos, string, string) {
   145  	return n.Pos, "flags", n.Name.Name
   146  }
   147  
   148  func (n *IntFlags) SetValues(values []*Int) {
   149  	n.Values = values
   150  }
   151  
   152  func (n *IntFlags) GetValues() []*Int {
   153  	return n.Values
   154  }
   155  
   156  func (n *IntFlags) GetPos() Pos {
   157  	return n.Pos
   158  }
   159  
   160  type StrFlags struct {
   161  	Pos    Pos
   162  	Name   *Ident
   163  	Values []*String
   164  }
   165  
   166  func (n *StrFlags) Info() (Pos, string, string) {
   167  	return n.Pos, "string flags", n.Name.Name
   168  }
   169  
   170  func (n *StrFlags) SetValues(values []*String) {
   171  	n.Values = values
   172  }
   173  
   174  func (n *StrFlags) GetValues() []*String {
   175  	return n.Values
   176  }
   177  
   178  func (n *StrFlags) GetPos() Pos {
   179  	return n.Pos
   180  }
   181  
   182  type TypeDef struct {
   183  	Pos  Pos
   184  	Name *Ident
   185  	// Non-template type aliases have only Type filled.
   186  	// Templates have Args and either Type or Struct filled.
   187  	Args   []*Ident
   188  	Type   *Type
   189  	Struct *Struct
   190  }
   191  
   192  func (n *TypeDef) Info() (Pos, string, string) {
   193  	return n.Pos, "type", n.Name.Name
   194  }
   195  
   196  // Not top-level AST nodes.
   197  
   198  type Ident struct {
   199  	Pos  Pos
   200  	Name string
   201  }
   202  
   203  func (n *Ident) Info() (Pos, string, string) {
   204  	return n.Pos, tok2str[tokIdent], n.Name
   205  }
   206  
   207  type String struct {
   208  	Pos   Pos
   209  	Value string
   210  	Fmt   StrFmt
   211  }
   212  
   213  func (n *String) Info() (Pos, string, string) {
   214  	return n.Pos, tok2str[tokString], ""
   215  }
   216  
   217  func (n *String) GetName() string {
   218  	return n.Value
   219  }
   220  
   221  type IntFmt int
   222  
   223  const (
   224  	IntFmtDec IntFmt = iota
   225  	IntFmtNeg
   226  	IntFmtHex
   227  	IntFmtChar
   228  )
   229  
   230  type StrFmt int
   231  
   232  const (
   233  	StrFmtRaw StrFmt = iota
   234  	StrFmtHex
   235  	StrFmtIdent
   236  )
   237  
   238  type Int struct {
   239  	Pos Pos
   240  	// Only one of Value, Ident, CExpr is filled.
   241  	Value    uint64
   242  	ValueFmt IntFmt
   243  	Ident    string
   244  	CExpr    string
   245  }
   246  
   247  func (n *Int) Info() (Pos, string, string) {
   248  	return n.Pos, tok2str[tokInt], ""
   249  }
   250  
   251  func (n *Int) GetName() string {
   252  	return n.Ident
   253  }
   254  
   255  type Operator int
   256  
   257  const (
   258  	OperatorCompareEq = iota + 1
   259  	OperatorCompareNeq
   260  	OperatorBinaryAnd
   261  )
   262  
   263  type BinaryExpression struct {
   264  	Pos      Pos
   265  	Operator Operator
   266  	Left     *Type
   267  	Right    *Type
   268  }
   269  
   270  func (n *BinaryExpression) Info() (Pos, string, string) {
   271  	return n.Pos, "binary-expression", ""
   272  }
   273  
   274  type Type struct {
   275  	Pos Pos
   276  	// Only one of Value, Ident, String, Expression is filled.
   277  	Value      uint64
   278  	ValueFmt   IntFmt
   279  	Ident      string
   280  	String     string
   281  	StringFmt  StrFmt
   282  	HasString  bool
   283  	Expression *BinaryExpression
   284  	// Parts after COLON (for ranges and bitfields).
   285  	Colon []*Type
   286  	// Sub-types in [].
   287  	Args []*Type
   288  }
   289  
   290  func (n *Type) Info() (Pos, string, string) {
   291  	return n.Pos, "type-opt", n.Ident
   292  }
   293  
   294  type Field struct {
   295  	Pos      Pos
   296  	Name     *Ident
   297  	Type     *Type
   298  	Attrs    []*Type
   299  	NewBlock bool // separated from previous fields by a new line
   300  	Comments []*Comment
   301  }
   302  
   303  func (n *Field) Info() (Pos, string, string) {
   304  	return n.Pos, "arg/field", n.Name.Name
   305  }