Class: Parser::Lexer::Literal
- Inherits:
-
Object
- Object
- Parser::Lexer::Literal
- Defined in:
- lib/parser/lexer/literal.rb
Constant Summary collapse
- DELIMITERS =
{ '(' => ')', '[' => ']', '{' => '}', '<' => '>' }
- MONOLITHIC =
{ :tSTRING_BEG => :tSTRING }
- TYPES =
{ # type start token interpolate? "'" => [ :tSTRING_BEG, false ], '%q' => [ :tSTRING_BEG, false ], '"' => [ :tSTRING_BEG, true ], '%' => [ :tSTRING_BEG, true ], '%Q' => [ :tSTRING_BEG, true ], '%w' => [ :tQWORDS_BEG, false ], '%W' => [ :tWORDS_BEG, true ], '%i' => [ :tQSYMBOLS_BEG, false ], '%I' => [ :tSYMBOLS_BEG, true ], ":'" => [ :tSYMBEG, false ], '%s' => [ :tSYMBEG, false ], ':"' => [ :tSYMBEG, true ], '/' => [ :tREGEXP_BEG, true ], '%r' => [ :tREGEXP_BEG, true ], '%x' => [ :tXSTRING_BEG, true ], '`' => [ :tXSTRING_BEG, true ], }
Instance Attribute Summary collapse
-
#heredoc_e ⇒ Object
readonly
Returns the value of attribute heredoc_e.
-
#saved_herebody_s ⇒ Object
Returns the value of attribute saved_herebody_s.
-
#str_s ⇒ Object
readonly
Returns the value of attribute str_s.
Instance Method Summary collapse
- #delimiter?(delimiter) ⇒ Boolean
- #emit(token, type, s, e) ⇒ Object protected
- #emit_start_tok ⇒ Object protected
- #end_interp_brace_and_try_closing ⇒ Object
- #extend_content ⇒ Object
- #extend_space(ts, te) ⇒ Object
- #extend_string(string, ts, te) ⇒ Object
- #flush_string ⇒ Object
- #heredoc? ⇒ Boolean
-
#initialize(lexer, str_type, delimiter, str_s, heredoc_e = nil, indent = false) ⇒ Literal
constructor
A new instance of Literal.
- #interpolate? ⇒ Boolean
- #munge_escape?(character) ⇒ Boolean
- #nest_and_try_closing(delimiter, ts, te) ⇒ Object
- #regexp? ⇒ Boolean
- #start_interp_brace ⇒ Object
- #type ⇒ Object
- #words? ⇒ Boolean
Constructor Details
#initialize(lexer, str_type, delimiter, str_s, heredoc_e = nil, indent = false) ⇒ Literal
Returns a new instance of Literal.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/parser/lexer/literal.rb', line 35 def initialize(lexer, str_type, delimiter, str_s, heredoc_e = nil, indent = false) @lexer = lexer @nesting = 1 unless TYPES.include?(str_type) = ERRORS[:unexpected_percent_str] % { :type => str_type } lexer.send(:diagnostic, :error, , @lexer.send(:range, str_s, str_s + 2)) end # String type. For :'foo', it is :' @str_type = str_type # Start of the string type specifier. @str_s = str_s # Data buffer. @buffer = '' # Start of the current chunk in data buffer. @buffer_s = nil @start_tok, @interpolate = TYPES[str_type] @start_delim = DELIMITERS.include?(delimiter) ? delimiter : nil @end_delim = DELIMITERS.fetch(delimiter, delimiter) @heredoc_e = heredoc_e @indent = indent @interp_braces = 0 @space_emitted = true # Monolithic strings are glued into a single token, e.g. # tSTRING_BEG tSTRING_CONTENT tSTRING_END -> tSTRING. @monolithic = (@start_tok == :tSTRING_BEG && %w(' ").include?(str_type) && !heredoc?) # Capture opening delimiter in percent-literals. unless @heredoc_e || @str_type.end_with?(delimiter) @str_type << delimiter end emit_start_tok unless @monolithic end |
Instance Attribute Details
#heredoc_e ⇒ Object (readonly)
Returns the value of attribute heredoc_e.
32 33 34 |
# File 'lib/parser/lexer/literal.rb', line 32 def heredoc_e @heredoc_e end |
#saved_herebody_s ⇒ Object
Returns the value of attribute saved_herebody_s.
33 34 35 |
# File 'lib/parser/lexer/literal.rb', line 33 def saved_herebody_s @saved_herebody_s end |
#str_s ⇒ Object (readonly)
Returns the value of attribute str_s.
32 33 34 |
# File 'lib/parser/lexer/literal.rb', line 32 def str_s @str_s end |
Instance Method Details
#delimiter?(delimiter) ⇒ Boolean
108 109 110 111 112 113 114 |
# File 'lib/parser/lexer/literal.rb', line 108 def delimiter?(delimiter) if @indent @end_delim == delimiter.lstrip else @end_delim == delimiter end end |
#emit(token, type, s, e) ⇒ Object (protected)
200 201 202 |
# File 'lib/parser/lexer/literal.rb', line 200 def emit(token, type, s, e) @lexer.send(:emit, token, type, s, e) end |
#emit_start_tok ⇒ Object (protected)
195 196 197 198 |
# File 'lib/parser/lexer/literal.rb', line 195 def emit_start_tok str_e = @heredoc_e || @str_s + @str_type.length emit(@start_tok, @str_type, @str_s, str_e) end |
#end_interp_brace_and_try_closing ⇒ Object
147 148 149 150 151 |
# File 'lib/parser/lexer/literal.rb', line 147 def end_interp_brace_and_try_closing @interp_braces -= 1 (@interp_braces == 0) end |
#extend_content ⇒ Object
179 180 181 |
# File 'lib/parser/lexer/literal.rb', line 179 def extend_content @space_emitted = false end |
#extend_space(ts, te) ⇒ Object
183 184 185 186 187 188 189 190 191 |
# File 'lib/parser/lexer/literal.rb', line 183 def extend_space(ts, te) flush_string unless @space_emitted emit(:tSPACE, nil, ts, te) @space_emitted = true end end |
#extend_string(string, ts, te) ⇒ Object
153 154 155 156 157 158 159 160 161 |
# File 'lib/parser/lexer/literal.rb', line 153 def extend_string(string, ts, te) if @buffer_s.nil? @buffer_s = ts end @buffer_e = te @buffer << string end |
#flush_string ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/parser/lexer/literal.rb', line 163 def flush_string if @monolithic emit_start_tok @monolithic = false end unless @buffer.empty? emit(:tSTRING_CONTENT, @buffer, @buffer_s, @buffer_e) @buffer = '' @buffer_s = nil @buffer_e = nil extend_content end end |
#heredoc? ⇒ Boolean
92 93 94 |
# File 'lib/parser/lexer/literal.rb', line 92 def heredoc? !!@heredoc_e end |
#interpolate? ⇒ Boolean
79 80 81 |
# File 'lib/parser/lexer/literal.rb', line 79 def interpolate? @interpolate end |
#munge_escape?(character) ⇒ Boolean
100 101 102 103 104 105 106 |
# File 'lib/parser/lexer/literal.rb', line 100 def munge_escape?(character) if words? && character =~ /[ \t\v\r\f\n]/ true else ['\\', @start_delim, @end_delim].include?(character) end end |
#nest_and_try_closing(delimiter, ts, te) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/parser/lexer/literal.rb', line 116 def nest_and_try_closing(delimiter, ts, te) if @start_delim && @start_delim == delimiter @nesting += 1 elsif delimiter?(delimiter) @nesting -= 1 end # Finalize if last matching delimiter is closed. if @nesting == 0 if words? extend_space(ts, ts) end # Emit the string as a single token if it's applicable. if @monolithic emit(MONOLITHIC[@start_tok], @buffer, @str_s, te) else # If this is a heredoc, @buffer contains the sentinel now. # Just throw it out. Lexer flushes the heredoc after each # non-heredoc-terminating \n anyway, so no data will be lost. flush_string unless heredoc? emit(:tSTRING_END, @end_delim, ts, te) end end end |
#regexp? ⇒ Boolean
88 89 90 |
# File 'lib/parser/lexer/literal.rb', line 88 def regexp? type == :tREGEXP_BEG end |
#start_interp_brace ⇒ Object
143 144 145 |
# File 'lib/parser/lexer/literal.rb', line 143 def start_interp_brace @interp_braces += 1 end |
#type ⇒ Object
96 97 98 |
# File 'lib/parser/lexer/literal.rb', line 96 def type @start_tok end |
#words? ⇒ Boolean
83 84 85 86 |
# File 'lib/parser/lexer/literal.rb', line 83 def words? type == :tWORDS_BEG || type == :tQWORDS_BEG || type == :tSYMBOLS_BEG || type == :tQSYMBOLS_BEG end |