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, :tSYMBEG => :tSYMBOL }
- 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 ], ":'" => [ :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
- #end_interp_brace_and_try_closing ⇒ 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.
32 33 34 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 |
# File 'lib/parser/lexer/literal.rb', line 32 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 # Monolithic strings are glued into a single token, e.g. # tSTRING_BEG tSTRING_CONTENT tSTRING_END -> tSTRING. @monolithic = ( [:tSTRING_BEG, :tSYMBEG].include?(type) && !heredoc? ) # Also capture delimiter in %w() style 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.
29 30 31 |
# File 'lib/parser/lexer/literal.rb', line 29 def heredoc_e @heredoc_e end |
#saved_herebody_s ⇒ Object
Returns the value of attribute saved_herebody_s.
30 31 32 |
# File 'lib/parser/lexer/literal.rb', line 30 def saved_herebody_s @saved_herebody_s end |
#str_s ⇒ Object (readonly)
Returns the value of attribute str_s.
29 30 31 |
# File 'lib/parser/lexer/literal.rb', line 29 def str_s @str_s end |
Instance Method Details
#delimiter?(delimiter) ⇒ Boolean
103 104 105 106 107 108 109 |
# File 'lib/parser/lexer/literal.rb', line 103 def delimiter?(delimiter) if @indent @end_delim == delimiter.lstrip else @end_delim == delimiter end end |
#end_interp_brace_and_try_closing ⇒ Object
138 139 140 141 142 |
# File 'lib/parser/lexer/literal.rb', line 138 def end_interp_brace_and_try_closing @interp_braces -= 1 (@interp_braces == 0) end |
#extend_string(string, ts, te) ⇒ Object
144 145 146 147 148 149 150 151 152 |
# File 'lib/parser/lexer/literal.rb', line 144 def extend_string(string, ts, te) if @buffer_s.nil? @buffer_s = ts end @buffer_e = te @buffer << string end |
#flush_string ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/parser/lexer/literal.rb', line 154 def flush_string if @monolithic emit_start_tok @monolithic = false end unless @buffer.empty? emit(:tSTRING_CONTENT, @buffer, @buffer_s, @buffer_e) if words? emit(:tSPACE, nil, @buffer_e, @buffer_e + 1) end @buffer = '' @buffer_s = nil @buffer_e = nil end end |
#heredoc? ⇒ Boolean
87 88 89 |
# File 'lib/parser/lexer/literal.rb', line 87 def heredoc? !!@heredoc_e end |
#interpolate? ⇒ Boolean
75 76 77 |
# File 'lib/parser/lexer/literal.rb', line 75 def interpolate? @interpolate end |
#munge_escape?(character) ⇒ Boolean
95 96 97 98 99 100 101 |
# File 'lib/parser/lexer/literal.rb', line 95 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
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/parser/lexer/literal.rb', line 111 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 # 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
83 84 85 |
# File 'lib/parser/lexer/literal.rb', line 83 def regexp? type == :tREGEXP_BEG end |
#start_interp_brace ⇒ Object
134 135 136 |
# File 'lib/parser/lexer/literal.rb', line 134 def start_interp_brace @interp_braces += 1 end |
#type ⇒ Object
91 92 93 |
# File 'lib/parser/lexer/literal.rb', line 91 def type @start_tok end |
#words? ⇒ Boolean
79 80 81 |
# File 'lib/parser/lexer/literal.rb', line 79 def words? type == :tWORDS_BEG || type == :tQWORDS_BEG end |