code.dwrz.net

Go monorepo.
Log | Files | Refs

ast.go (2567B)


      1 package ini
      2 
      3 // ASTKind represents different states in the parse table
      4 // and the type of AST that is being constructed
      5 type ASTKind int
      6 
      7 // ASTKind* is used in the parse table to transition between
      8 // the different states
      9 const (
     10 	ASTKindNone = ASTKind(iota)
     11 	ASTKindStart
     12 	ASTKindExpr
     13 	ASTKindEqualExpr
     14 	ASTKindStatement
     15 	ASTKindSkipStatement
     16 	ASTKindExprStatement
     17 	ASTKindSectionStatement
     18 	ASTKindNestedSectionStatement
     19 	ASTKindCompletedNestedSectionStatement
     20 	ASTKindCommentStatement
     21 	ASTKindCompletedSectionStatement
     22 )
     23 
     24 func (k ASTKind) String() string {
     25 	switch k {
     26 	case ASTKindNone:
     27 		return "none"
     28 	case ASTKindStart:
     29 		return "start"
     30 	case ASTKindExpr:
     31 		return "expr"
     32 	case ASTKindStatement:
     33 		return "stmt"
     34 	case ASTKindSectionStatement:
     35 		return "section_stmt"
     36 	case ASTKindExprStatement:
     37 		return "expr_stmt"
     38 	case ASTKindCommentStatement:
     39 		return "comment"
     40 	case ASTKindNestedSectionStatement:
     41 		return "nested_section_stmt"
     42 	case ASTKindCompletedSectionStatement:
     43 		return "completed_stmt"
     44 	case ASTKindSkipStatement:
     45 		return "skip"
     46 	default:
     47 		return ""
     48 	}
     49 }
     50 
     51 // AST interface allows us to determine what kind of node we
     52 // are on and casting may not need to be necessary.
     53 //
     54 // The root is always the first node in Children
     55 type AST struct {
     56 	Kind      ASTKind
     57 	Root      Token
     58 	RootToken bool
     59 	Children  []AST
     60 }
     61 
     62 func newAST(kind ASTKind, root AST, children ...AST) AST {
     63 	return AST{
     64 		Kind:     kind,
     65 		Children: append([]AST{root}, children...),
     66 	}
     67 }
     68 
     69 func newASTWithRootToken(kind ASTKind, root Token, children ...AST) AST {
     70 	return AST{
     71 		Kind:      kind,
     72 		Root:      root,
     73 		RootToken: true,
     74 		Children:  children,
     75 	}
     76 }
     77 
     78 // AppendChild will append to the list of children an AST has.
     79 func (a *AST) AppendChild(child AST) {
     80 	a.Children = append(a.Children, child)
     81 }
     82 
     83 // GetRoot will return the root AST which can be the first entry
     84 // in the children list or a token.
     85 func (a *AST) GetRoot() AST {
     86 	if a.RootToken {
     87 		return *a
     88 	}
     89 
     90 	if len(a.Children) == 0 {
     91 		return AST{}
     92 	}
     93 
     94 	return a.Children[0]
     95 }
     96 
     97 // GetChildren will return the current AST's list of children
     98 func (a *AST) GetChildren() []AST {
     99 	if len(a.Children) == 0 {
    100 		return []AST{}
    101 	}
    102 
    103 	if a.RootToken {
    104 		return a.Children
    105 	}
    106 
    107 	return a.Children[1:]
    108 }
    109 
    110 // SetChildren will set and override all children of the AST.
    111 func (a *AST) SetChildren(children []AST) {
    112 	if a.RootToken {
    113 		a.Children = children
    114 	} else {
    115 		a.Children = append(a.Children[:1], children...)
    116 	}
    117 }
    118 
    119 // Start is used to indicate the starting state of the parse table.
    120 var Start = newAST(ASTKindStart, AST{})