literal.hh 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #ifndef RUBY_PARSER_LITERAL_HH
  2. #define RUBY_PARSER_LITERAL_HH
  3. #include <string>
  4. #include <utility>
  5. #include <optional>
  6. #include "token.hh"
  7. namespace ruby_parser {
  8. enum class literal_type {
  9. SQUOTE_STRING,
  10. SQUOTE_HEREDOC,
  11. LOWERQ_STRING,
  12. DQUOTE_STRING,
  13. DQUOTE_HEREDOC,
  14. PERCENT_STRING,
  15. UPPERQ_STRING,
  16. LOWERW_WORDS,
  17. UPPERW_WORDS,
  18. LOWERI_SYMBOLS,
  19. UPPERI_SYMBOLS,
  20. SQUOTE_SYMBOL,
  21. LOWERS_SYMBOL,
  22. DQUOTE_SYMBOL,
  23. SLASH_REGEXP,
  24. PERCENT_REGEXP,
  25. LOWERX_XSTRING,
  26. BACKTICK_XSTRING,
  27. BACKTICK_HEREDOC,
  28. };
  29. using optional_size = std::optional<size_t>;
  30. class lexer;
  31. class literal {
  32. lexer& _lexer;
  33. size_t _nesting;
  34. literal_type _type;
  35. std::string start_delim;
  36. std::string end_delim;
  37. bool indent;
  38. bool dedent_body;
  39. bool label_allowed;
  40. optional_size _dedentLevel;
  41. size_t _interp_braces;
  42. bool space_emitted;
  43. bool monolithic;
  44. std::string buffer;
  45. const char* buffer_s;
  46. const char* buffer_e;
  47. public:
  48. // lexer needs access to these:
  49. const char* str_s;
  50. const char* saved_herebody_s;
  51. const char* heredoc_e;
  52. literal(lexer& lexer, literal_type type, std::string delimiter, const char* str_s, const char* heredoc_e = nullptr, bool indent = false, bool dedent_body = false, bool label_allowed = false);
  53. // delete copy constructor to prevent accidental copies. we never
  54. // legitimately need to copy literal.
  55. literal(const literal&) = delete;
  56. bool words() const;
  57. bool backslash_delimited() const;
  58. bool interpolate() const;
  59. bool regexp() const;
  60. bool heredoc() const;
  61. token_type start_token_type() const;
  62. optional_size dedentLevel() const;
  63. bool munge_escape(char c) const;
  64. void infer_indent_level(std::string& line);
  65. void start_interp_brace();
  66. bool end_interp_brace_and_try_closing();
  67. bool nest_and_try_closing(std::string& delimiter, const char* ts, const char* te, std::string lookahead = "");
  68. void extend_space(const char* ts, const char* te);
  69. void extend_string(std::string& str, const char* ts, const char* te);
  70. void extend_content();
  71. void flush_string();
  72. private:
  73. bool is_delimiter(std::string& delimiter) const;
  74. void clear_buffer();
  75. void emit_start_token();
  76. void emit(token_type tok, std::string& value, const char* s, const char* e);
  77. };
  78. }
  79. // there is a circular dependency between lexer and literal.
  80. // lexer was forward-declared above, but now we need to include it
  81. // properly.
  82. #include "lexer.hh"
  83. #endif