Home | History | Annotate | Download | only in ast
      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