parse_subtree_consumer.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_SEMANTICS_PARSE_SUBTREE_CONSUMER_H_
  5. #define CARBON_TOOLCHAIN_SEMANTICS_PARSE_SUBTREE_CONSUMER_H_
  6. #include <iterator>
  7. #include "llvm/ADT/Optional.h"
  8. #include "toolchain/parser/parse_node_kind.h"
  9. #include "toolchain/parser/parse_tree.h"
  10. namespace Carbon {
  11. // Consumes a subtree from the parser, returning only its direct children.
  12. //
  13. // This traverses in reverse postorder because the parent of a subtree needs to
  14. // be seen before its children.
  15. class ParseSubtreeConsumer {
  16. public:
  17. using ParseTreeIterator = std::reverse_iterator<ParseTree::PostorderIterator>;
  18. // Returns a subtree consumer for a particular node in the tree.
  19. static auto ForParent(const ParseTree& parse_tree,
  20. ParseTree::Node parent_node) -> ParseSubtreeConsumer;
  21. // Returns a subtree consumer for the root of the tree.
  22. static auto ForTree(const ParseTree& parse_tree) -> ParseSubtreeConsumer;
  23. // Prevent copies because we require completion of parsing in the destructor.
  24. ParseSubtreeConsumer(const ParseSubtreeConsumer&) = delete;
  25. auto operator=(const ParseSubtreeConsumer&) -> ParseSubtreeConsumer& = delete;
  26. ~ParseSubtreeConsumer();
  27. // Returns the next node.
  28. // CHECK-fails on unexpected states.
  29. [[nodiscard]] auto RequireConsume() -> ParseTree::Node;
  30. // Requires the next node be of the given kind, and returns it.
  31. // CHECK-fails on unexpected states.
  32. [[nodiscard]] auto RequireConsume(ParseNodeKind node_kind) -> ParseTree::Node;
  33. // Returns the next node if one exists.
  34. [[nodiscard]] auto TryConsume() -> llvm::Optional<ParseTree::Node>;
  35. // Returns the next node if it's of the given kind.
  36. [[nodiscard]] auto TryConsume(ParseNodeKind node_kind)
  37. -> llvm::Optional<ParseTree::Node>;
  38. // Returns true if there are no more nodes to consume.
  39. auto is_done() -> bool { return cursor_ == subtree_end_; }
  40. private:
  41. // Constructs for a subtree.
  42. ParseSubtreeConsumer(const ParseTree& parse_tree, ParseTreeIterator cursor,
  43. ParseTreeIterator subtree_end)
  44. : parse_tree_(&parse_tree), cursor_(cursor), subtree_end_(subtree_end) {}
  45. // Advances to the next sibling, returning the current node.
  46. auto GetNodeAndAdvance() -> ParseTree::Node;
  47. const ParseTree* parse_tree_;
  48. ParseTreeIterator cursor_;
  49. ParseTreeIterator subtree_end_;
  50. };
  51. } // namespace Carbon
  52. #endif // CARBON_TOOLCHAIN_SEMANTICS_PARSE_SUBTREE_CONSUMER_H_