ParserRuleContext.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
  2. * Use of this file is governed by the BSD 3-clause license that
  3. * can be found in the LICENSE.txt file in the project root.
  4. */
  5. #pragma once
  6. #include "RuleContext.h"
  7. #include "support/CPPUtils.h"
  8. namespace antlr4 {
  9. /// <summary>
  10. /// A rule invocation record for parsing.
  11. ///
  12. /// Contains all of the information about the current rule not stored in the
  13. /// RuleContext. It handles parse tree children list, Any ATN state
  14. /// tracing, and the default values available for rule invocatons:
  15. /// start, stop, rule index, current alt number.
  16. ///
  17. /// Subclasses made for each rule and grammar track the parameters,
  18. /// return values, locals, and labels specific to that rule. These
  19. /// are the objects that are returned from rules.
  20. ///
  21. /// Note text is not an actual field of a rule return value; it is computed
  22. /// from start and stop using the input stream's toString() method. I
  23. /// could add a ctor to this so that we can pass in and store the input
  24. /// stream, but I'm not sure we want to do that. It would seem to be undefined
  25. /// to get the .text property anyway if the rule matches tokens from multiple
  26. /// input streams.
  27. ///
  28. /// I do not use getters for fields of objects that are used simply to
  29. /// group values such as this aggregate. The getters/setters are there to
  30. /// satisfy the superclass interface.
  31. /// </summary>
  32. class ANTLR4CPP_PUBLIC ParserRuleContext : public RuleContext {
  33. public:
  34. static ParserRuleContext EMPTY;
  35. /// <summary>
  36. /// For debugging/tracing purposes, we want to track all of the nodes in
  37. /// the ATN traversed by the parser for a particular rule.
  38. /// This list indicates the sequence of ATN nodes used to match
  39. /// the elements of the children list. This list does not include
  40. /// ATN nodes and other rules used to match rule invocations. It
  41. /// traces the rule invocation node itself but nothing inside that
  42. /// other rule's ATN submachine.
  43. ///
  44. /// There is NOT a one-to-one correspondence between the children and
  45. /// states list. There are typically many nodes in the ATN traversed
  46. /// for each element in the children list. For example, for a rule
  47. /// invocation there is the invoking state and the following state.
  48. ///
  49. /// The parser setState() method updates field s and adds it to this list
  50. /// if we are debugging/tracing.
  51. ///
  52. /// This does not trace states visited during prediction.
  53. /// </summary>
  54. // public List<Integer> states;
  55. Token *start;
  56. Token *stop;
  57. /// The exception that forced this rule to return. If the rule successfully
  58. /// completed, this is "null exception pointer".
  59. std::exception_ptr exception;
  60. ParserRuleContext();
  61. ParserRuleContext(ParserRuleContext *parent, size_t invokingStateNumber);
  62. /** COPY a ctx (I'm deliberately not using copy constructor) to avoid
  63. * confusion with creating node with parent. Does not copy children
  64. * (except error leaves).
  65. */
  66. virtual void copyFrom(ParserRuleContext *ctx);
  67. // Double dispatch methods for listeners
  68. virtual void enterRule(tree::ParseTreeListener *listener);
  69. virtual void exitRule(tree::ParseTreeListener *listener);
  70. /** Add a token leaf node child and force its parent to be this node. */
  71. tree::TerminalNode* addChild(tree::TerminalNode *t);
  72. RuleContext* addChild(RuleContext *ruleInvocation);
  73. /// Used by enterOuterAlt to toss out a RuleContext previously added as
  74. /// we entered a rule. If we have # label, we will need to remove
  75. /// generic ruleContext object.
  76. void removeLastChild();
  77. tree::TerminalNode* getToken(size_t ttype, std::size_t i) const;
  78. std::vector<tree::TerminalNode*> getTokens(size_t ttype) const;
  79. template<typename T>
  80. T* getRuleContext(size_t i) const {
  81. static_assert(std::is_base_of_v<RuleContext, T>, "T must be derived from RuleContext");
  82. size_t j = 0; // what element have we found with ctxType?
  83. for (auto *child : children) {
  84. if (RuleContext::is(child)) {
  85. if (auto *typedChild = dynamic_cast<T*>(child); typedChild != nullptr) {
  86. if (j++ == i) {
  87. return typedChild;
  88. }
  89. }
  90. }
  91. }
  92. return nullptr;
  93. }
  94. template<typename T>
  95. std::vector<T*> getRuleContexts() const {
  96. static_assert(std::is_base_of_v<RuleContext, T>, "T must be derived from RuleContext");
  97. std::vector<T*> contexts;
  98. for (auto *child : children) {
  99. if (RuleContext::is(child)) {
  100. if (auto *typedChild = dynamic_cast<T*>(child); typedChild != nullptr) {
  101. contexts.push_back(typedChild);
  102. }
  103. }
  104. }
  105. return contexts;
  106. }
  107. virtual misc::Interval getSourceInterval() override;
  108. /**
  109. * Get the initial token in this context.
  110. * Note that the range from start to stop is inclusive, so for rules that do not consume anything
  111. * (for example, zero length or error productions) this token may exceed stop.
  112. */
  113. Token* getStart() const;
  114. /**
  115. * Get the final token in this context.
  116. * Note that the range from start to stop is inclusive, so for rules that do not consume anything
  117. * (for example, zero length or error productions) this token may precede start.
  118. */
  119. Token* getStop() const;
  120. /// <summary>
  121. /// Used for rule context info debugging during parse-time, not so much for ATN debugging </summary>
  122. virtual std::string toInfoString(Parser *recognizer);
  123. };
  124. } // namespace antlr4