| // Copyright 2017 syzkaller project authors. All rights reserved. |
| // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. |
| |
| // Package ast parses and formats sys files. |
| package ast |
| |
| // Pos represents source info for AST nodes. |
| type Pos struct { |
| File string |
| Off int // byte offset, starting at 0 |
| Line int // line number, starting at 1 |
| Col int // column number, starting at 1 (byte count) |
| } |
| |
| // Description contains top-level nodes of a parsed sys description. |
| type Description struct { |
| Nodes []Node |
| } |
| |
| // Node is AST node interface. |
| type Node interface { |
| Info() (pos Pos, typ string, name string) |
| // Clone makes a deep copy of the node. |
| Clone() Node |
| // Walk calls callback cb for all child nodes of this node. |
| // Note: it's not recursive. Use Recursive helper for recursive walk. |
| Walk(cb func(Node)) |
| } |
| |
| // Top-level AST nodes: |
| |
| type NewLine struct { |
| Pos Pos |
| } |
| |
| func (n *NewLine) Info() (Pos, string, string) { |
| return n.Pos, tok2str[tokNewLine], "" |
| } |
| |
| type Comment struct { |
| Pos Pos |
| Text string |
| } |
| |
| func (n *Comment) Info() (Pos, string, string) { |
| return n.Pos, tok2str[tokComment], "" |
| } |
| |
| type Include struct { |
| Pos Pos |
| File *String |
| } |
| |
| func (n *Include) Info() (Pos, string, string) { |
| return n.Pos, tok2str[tokInclude], "" |
| } |
| |
| type Incdir struct { |
| Pos Pos |
| Dir *String |
| } |
| |
| func (n *Incdir) Info() (Pos, string, string) { |
| return n.Pos, tok2str[tokInclude], "" |
| } |
| |
| type Define struct { |
| Pos Pos |
| Name *Ident |
| Value *Int |
| } |
| |
| func (n *Define) Info() (Pos, string, string) { |
| return n.Pos, tok2str[tokDefine], n.Name.Name |
| } |
| |
| type Resource struct { |
| Pos Pos |
| Name *Ident |
| Base *Type |
| Values []*Int |
| } |
| |
| func (n *Resource) Info() (Pos, string, string) { |
| return n.Pos, tok2str[tokResource], n.Name.Name |
| } |
| |
| type Call struct { |
| Pos Pos |
| Name *Ident |
| CallName string |
| NR uint64 |
| Args []*Field |
| Ret *Type |
| } |
| |
| func (n *Call) Info() (Pos, string, string) { |
| return n.Pos, "syscall", n.Name.Name |
| } |
| |
| type Struct struct { |
| Pos Pos |
| Name *Ident |
| Fields []*Field |
| Attrs []*Type |
| Comments []*Comment |
| IsUnion bool |
| } |
| |
| func (n *Struct) Info() (Pos, string, string) { |
| typ := "struct" |
| if n.IsUnion { |
| typ = "union" |
| } |
| return n.Pos, typ, n.Name.Name |
| } |
| |
| type IntFlags struct { |
| Pos Pos |
| Name *Ident |
| Values []*Int |
| } |
| |
| func (n *IntFlags) Info() (Pos, string, string) { |
| return n.Pos, "flags", n.Name.Name |
| } |
| |
| type StrFlags struct { |
| Pos Pos |
| Name *Ident |
| Values []*String |
| } |
| |
| func (n *StrFlags) Info() (Pos, string, string) { |
| return n.Pos, "string flags", n.Name.Name |
| } |
| |
| type TypeDef struct { |
| Pos Pos |
| Name *Ident |
| // Non-template type aliases have only Type filled. |
| // Templates have Args and either Type or Struct filled. |
| Args []*Ident |
| Type *Type |
| Struct *Struct |
| } |
| |
| func (n *TypeDef) Info() (Pos, string, string) { |
| return n.Pos, "type", n.Name.Name |
| } |
| |
| // Not top-level AST nodes: |
| |
| type Ident struct { |
| Pos Pos |
| Name string |
| } |
| |
| func (n *Ident) Info() (Pos, string, string) { |
| return n.Pos, tok2str[tokIdent], n.Name |
| } |
| |
| type String struct { |
| Pos Pos |
| Value string |
| } |
| |
| func (n *String) Info() (Pos, string, string) { |
| return n.Pos, tok2str[tokString], "" |
| } |
| |
| type IntFmt int |
| |
| const ( |
| IntFmtDec IntFmt = iota |
| IntFmtNeg |
| IntFmtHex |
| IntFmtChar |
| ) |
| |
| type Int struct { |
| Pos Pos |
| // Only one of Value, Ident, CExpr is filled. |
| Value uint64 |
| ValueFmt IntFmt |
| Ident string |
| CExpr string |
| } |
| |
| func (n *Int) Info() (Pos, string, string) { |
| return n.Pos, tok2str[tokInt], "" |
| } |
| |
| type Type struct { |
| Pos Pos |
| // Only one of Value, Ident, String is filled. |
| Value uint64 |
| ValueFmt IntFmt |
| Ident string |
| String string |
| HasString bool |
| // Part after COLON (for ranges and bitfields). |
| HasColon bool |
| Pos2 Pos |
| Value2 uint64 |
| Value2Fmt IntFmt |
| Ident2 string |
| Args []*Type |
| } |
| |
| func (n *Type) Info() (Pos, string, string) { |
| return n.Pos, "type", n.Ident |
| } |
| |
| type Field struct { |
| Pos Pos |
| Name *Ident |
| Type *Type |
| NewBlock bool // separated from previous fields by a new line |
| Comments []*Comment |
| } |
| |
| func (n *Field) Info() (Pos, string, string) { |
| return n.Pos, "arg/field", n.Name.Name |
| } |