ast.go 2.5 KB

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