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 string, 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 // Top-level AST nodes: 31 32 type NewLine struct { 33 Pos Pos 34 } 35 36 func (n *NewLine) Info() (Pos, string, string) { 37 return n.Pos, tok2str[tokNewLine], "" 38 } 39 40 type Comment struct { 41 Pos Pos 42 Text string 43 } 44 45 func (n *Comment) Info() (Pos, string, string) { 46 return n.Pos, tok2str[tokComment], "" 47 } 48 49 type Include struct { 50 Pos Pos 51 File *String 52 } 53 54 func (n *Include) Info() (Pos, string, string) { 55 return n.Pos, tok2str[tokInclude], "" 56 } 57 58 type Incdir struct { 59 Pos Pos 60 Dir *String 61 } 62 63 func (n *Incdir) Info() (Pos, string, string) { 64 return n.Pos, tok2str[tokInclude], "" 65 } 66 67 type Define struct { 68 Pos Pos 69 Name *Ident 70 Value *Int 71 } 72 73 func (n *Define) Info() (Pos, string, string) { 74 return n.Pos, tok2str[tokDefine], n.Name.Name 75 } 76 77 type Resource struct { 78 Pos Pos 79 Name *Ident 80 Base *Type 81 Values []*Int 82 } 83 84 func (n *Resource) Info() (Pos, string, string) { 85 return n.Pos, tok2str[tokResource], n.Name.Name 86 } 87 88 type Call struct { 89 Pos Pos 90 Name *Ident 91 CallName string 92 NR uint64 93 Args []*Field 94 Ret *Type 95 } 96 97 func (n *Call) Info() (Pos, string, string) { 98 return n.Pos, "syscall", n.Name.Name 99 } 100 101 type Struct struct { 102 Pos Pos 103 Name *Ident 104 Fields []*Field 105 Attrs []*Type 106 Comments []*Comment 107 IsUnion bool 108 } 109 110 func (n *Struct) Info() (Pos, string, string) { 111 typ := "struct" 112 if n.IsUnion { 113 typ = "union" 114 } 115 return n.Pos, typ, n.Name.Name 116 } 117 118 type IntFlags struct { 119 Pos Pos 120 Name *Ident 121 Values []*Int 122 } 123 124 func (n *IntFlags) Info() (Pos, string, string) { 125 return n.Pos, "flags", n.Name.Name 126 } 127 128 type StrFlags struct { 129 Pos Pos 130 Name *Ident 131 Values []*String 132 } 133 134 func (n *StrFlags) Info() (Pos, string, string) { 135 return n.Pos, "string flags", n.Name.Name 136 } 137 138 type TypeDef struct { 139 Pos Pos 140 Name *Ident 141 // Non-template type aliases have only Type filled. 142 // Templates have Args and either Type or Struct filled. 143 Args []*Ident 144 Type *Type 145 Struct *Struct 146 } 147 148 func (n *TypeDef) Info() (Pos, string, string) { 149 return n.Pos, "type", n.Name.Name 150 } 151 152 // Not top-level AST nodes: 153 154 type Ident struct { 155 Pos Pos 156 Name string 157 } 158 159 func (n *Ident) Info() (Pos, string, string) { 160 return n.Pos, tok2str[tokIdent], n.Name 161 } 162 163 type String struct { 164 Pos Pos 165 Value string 166 } 167 168 func (n *String) Info() (Pos, string, string) { 169 return n.Pos, tok2str[tokString], "" 170 } 171 172 type IntFmt int 173 174 const ( 175 IntFmtDec IntFmt = iota 176 IntFmtNeg 177 IntFmtHex 178 IntFmtChar 179 ) 180 181 type Int struct { 182 Pos Pos 183 // Only one of Value, Ident, CExpr is filled. 184 Value uint64 185 ValueFmt IntFmt 186 Ident string 187 CExpr string 188 } 189 190 func (n *Int) Info() (Pos, string, string) { 191 return n.Pos, tok2str[tokInt], "" 192 } 193 194 type Type struct { 195 Pos Pos 196 // Only one of Value, Ident, String is filled. 197 Value uint64 198 ValueFmt IntFmt 199 Ident string 200 String string 201 HasString bool 202 // Part after COLON (for ranges and bitfields). 203 HasColon bool 204 Pos2 Pos 205 Value2 uint64 206 Value2Fmt IntFmt 207 Ident2 string 208 Args []*Type 209 } 210 211 func (n *Type) Info() (Pos, string, string) { 212 return n.Pos, "type", n.Ident 213 } 214 215 type Field struct { 216 Pos Pos 217 Name *Ident 218 Type *Type 219 NewBlock bool // separated from previous fields by a new line 220 Comments []*Comment 221 } 222 223 func (n *Field) Info() (Pos, string, string) { 224 return n.Pos, "arg/field", n.Name.Name 225 } 226