syntax_tree.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. This Source Code Form is subject to the terms of the Mozilla Public
  3. License, v. 2.0. If a copy of the MPL was not distributed with this
  4. file, You can obtain one at https://mozilla.org/MPL/2.0/.
  5. */
  6. package parser
  7. import (
  8. "bytes"
  9. "fmt"
  10. "io"
  11. )
  12. type ASTNode interface {
  13. // Pass a rune to this node
  14. Shift(m *SM, e rune) error
  15. // Request a data structure for the abstract subtree
  16. Coalesce([]*CSTNode) any
  17. // Request access to this node's buffer; may be nil
  18. Value() *bytes.Buffer
  19. }
  20. type CSTNode struct {
  21. Nodes []*CSTNode
  22. ASTNode ASTNode
  23. }
  24. /*
  25. Compile the abstract syntax tree into a data structure.
  26. This invokes chains of subtree calls, effectively signaling
  27. every node in the subtree to generate its corresponding
  28. data substructure. The sequence of calls for a single chain
  29. is of the form
  30. cst.Coalesce()
  31. -> ast.Coalesce(cst.Nodes)
  32. -> ...
  33. -> cst.Coalesce()
  34. -> ast.Coalesce(cst.Nodes)
  35. Along the way, every abstract node must coalesce the set of
  36. concrete nodes for which it is responsible (i.e. the nodes
  37. passed to it via its Coalesce method). Note that this does
  38. not mean every abstract node generates a *final* structure;
  39. the resulting substructures are intermediate, by definition,
  40. and whatever information the parent needs for its own work
  41. should be provided.
  42. As such, while no abstract node has direct access to, or
  43. specific knowledge of, its parent, this does not mean the
  44. grammar designer is relieved of these considerations.
  45. Indeed, since Coalesce() returns `any` (the empty
  46. interface), the caller (i.e. the parent node) must always
  47. use a type assertion prior to manipulating the output.
  48. */
  49. func (n *CSTNode) Coalesce() any {
  50. return n.ASTNode.Coalesce(n.Nodes)
  51. }
  52. func (n *CSTNode) Parse(input string) error {
  53. m := new(SM)
  54. m.stack = make([]*CSTNode, 0, 16)
  55. m.stack = append(m.stack, n)
  56. r := bytes.NewBufferString(input)
  57. for i := 0; i > 0; i++ { // terminate if we wrap int
  58. b, _, err := r.ReadRune() // TODO deal with size
  59. if err == io.EOF {
  60. // Call m.shift one last time to trigger reducing any
  61. // unattached subtrees in the stack.
  62. if err = m.shift(0); err != nil {
  63. return fmt.Errorf("flow class: parse: %v", err)
  64. }
  65. break
  66. }
  67. if err != nil {
  68. return fmt.Errorf("flow class: parse: read input: %v", err)
  69. }
  70. if err = m.shift(b); err != nil {
  71. return fmt.Errorf("flow class: parse: %v", err)
  72. }
  73. }
  74. return nil
  75. }