Class: Solid::Parser
- Inherits:
-
Object
- Object
- Solid::Parser
- Defined in:
- lib/solid/parser.rb
Defined Under Namespace
Classes: ContextVariable, Literal, LiteralArray, LiteralHash, LiteralRange, MethodCall
Constant Summary collapse
- KEYWORDS =
{ 'true' => Literal.new(true), 'false' => Literal.new(false), 'nil' => Literal.new(nil), }
Class Method Summary collapse
Instance Method Summary collapse
-
#dive_in ⇒ Object
Looks for a structure like [:program, [[:array, [#stuff#]]]] or [:program, [[:array, nil]]].
-
#handle_array(array) ⇒ Object
# [1] [[:@int, “1”, [1, 1]].
-
#handle_bare_assoc_hash(assoc_hash) ⇒ Object
# foo: 42 [[:assoc_new, [:@label, “foo:”, [1, 1]], [:@int, “42”, [1, 5]]]].
-
#handle_binary(left_operand, operator, right_operand) ⇒ Object
# 1 + 2 [:@int, “1”, [1, 0]], :*, [:@int, “2”, [1, 4]].
-
#handle_call(receiver_sexp, method_call, method_sexp) ⇒ Object
# myvar.length.
-
#handle_const(constant, lineno_column) ⇒ Object
# Spam “Spam”, [1, 23].
-
#handle_dot2(start_value, end_value) ⇒ Object
# 1..10 [[:@int, “1”, [1, 0]], [:@int, “10”, [1, 4]]].
-
#handle_dot3(start_value, end_value) ⇒ Object
# 1…10 [[:@int, “1”, [1, 0]], [:@int, “10”, [1, 4]]].
- #handle_dyna_symbol(string_content) ⇒ Object
-
#handle_float(float, lineno_column) ⇒ Object
# 4.2 “4.2”, [1, 2].
-
#handle_hash(hash) ⇒ Object
# 42 [:assoclist_from_args, [[:assoc_new, [:@label, “foo:”, [1, 2]], [:@int, “42”, [1, 7]]]]].
-
#handle_ident(identifier, lineno_column) ⇒ Object
# spam “spam”, [1, 23].
-
#handle_int(int, lineno_column) ⇒ Object
# 42 “42”, [1, 2].
-
#handle_kw(keyword, lineno_column) ⇒ Object
# true “true”, [1, 33].
-
#handle_label(label, lineno_column) ⇒ Object
# foo: “foo:”, [1, 2].
-
#handle_method_add_arg(call_sexp, args_sexp) ⇒ Object
# myvar.split(‘,’, 2).
-
#handle_paren(content) ⇒ Object
# (1) [[:@int, “42”, [1, 2]]].
- #handle_regexp_literal(regexp_literal, lineno_column) ⇒ Object
- #handle_string_content(*parts) ⇒ Object
-
#handle_string_literal(string_content) ⇒ Object
# ‘mystring’ [:string_content, [:@tstring_content, “mystring”, [1, 14]]] TODO: handle string interpolation.
-
#handle_tstring_content(string_content, lineno_column) ⇒ Object
[:@tstring_content, “mystring”, [1, 14]].
-
#handle_unary(operator, operand) ⇒ Object
# !true [:!, [:var_ref, [:@kw, “true”, [1, 1]]]].
-
#handle_var_ref(var_ref) ⇒ Object
# spam [:@ident, “spam”, [1, 33]] or # true [:@kw, “true”, [1, 23]].
-
#handle_vcall(expression) ⇒ Object
# myvar.
-
#initialize(string) ⇒ Parser
constructor
A new instance of Parser.
-
#method_call_args(args_sexp) ⇒ Object
# args list: (‘,’, 2) [:arg_paren, [:args_add_block, [ [:string_literal, [:string_content, [:@tstring_content, “,”, [1, 14]]]], [:@int, “2”, [1, 18]] ], false]].
- #parse ⇒ Object
- #parse_one(argument) ⇒ Object
Constructor Details
#initialize(string) ⇒ Parser
Returns a new instance of Parser.
71 72 73 74 |
# File 'lib/solid/parser.rb', line 71 def initialize(string) @string = string @sexp = nil end |
Class Method Details
.parse(string) ⇒ Object
65 66 67 |
# File 'lib/solid/parser.rb', line 65 def parse(string) new(string).parse end |
Instance Method Details
#dive_in ⇒ Object
Looks for a structure like
- :program, [[:array, [#stuff#]]]
-
or
- :program, [[:array, nil]]
85 86 87 88 |
# File 'lib/solid/parser.rb', line 85 def dive_in @sexp = @sexp[1] @sexp = @sexp.first end |
#handle_array(array) ⇒ Object
# [1]
- [:@int, “1”, [1, 1]
178 179 180 |
# File 'lib/solid/parser.rb', line 178 def handle_array(array) LiteralArray.new((array || []).map(&method(:parse_one))) end |
#handle_bare_assoc_hash(assoc_hash) ⇒ Object
# foo: 42
- [:assoc_new, [:@label, “foo:”, [1, 1]], [:@int, “42”, [1, 5]]]
107 108 109 |
# File 'lib/solid/parser.rb', line 107 def (assoc_hash) LiteralHash.new assoc_hash.map {|(_, *key_value)| key_value.map(&method(:parse_one)) } end |
#handle_binary(left_operand, operator, right_operand) ⇒ Object
# 1 + 2
- :@int, “1”, [1, 0]], :*, [:@int, “2”, [1, 4]
171 172 173 174 |
# File 'lib/solid/parser.rb', line 171 def handle_binary(left_operand, operator, right_operand) receiver = parse_one(left_operand) MethodCall.new(receiver, operator, [parse_one(right_operand)]) end |
#handle_call(receiver_sexp, method_call, method_sexp) ⇒ Object
# myvar.length
- :var_ref, [:@ident, “myvar”, [1, 1]]
-
:“.”
- :@ident, “length”, [1, 7]
122 123 124 125 126 |
# File 'lib/solid/parser.rb', line 122 def handle_call(receiver_sexp, method_call, method_sexp) receiver = parse_one(receiver_sexp) method = method_sexp[1] MethodCall.new receiver, method, [] end |
#handle_const(constant, lineno_column) ⇒ Object
# Spam “Spam”, [1, 23]
247 248 249 |
# File 'lib/solid/parser.rb', line 247 def handle_const(constant, lineno_column) ContextVariable.new constant end |
#handle_dot2(start_value, end_value) ⇒ Object
# 1..10
- [:@int, “1”, [1, 0]], [:@int, “10”, [1, 4]]
190 191 192 |
# File 'lib/solid/parser.rb', line 190 def handle_dot2(start_value, end_value) LiteralRange.new(parse_one(start_value), parse_one(end_value), false) end |
#handle_dot3(start_value, end_value) ⇒ Object
# 1…10
- [:@int, “1”, [1, 0]], [:@int, “10”, [1, 4]]
196 197 198 |
# File 'lib/solid/parser.rb', line 196 def handle_dot3(start_value, end_value) LiteralRange.new(parse_one(start_value), parse_one(end_value), true) end |
#handle_dyna_symbol(string_content) ⇒ Object
216 217 218 |
# File 'lib/solid/parser.rb', line 216 def handle_dyna_symbol(string_content) Literal.new(string_content.first[1]) end |
#handle_float(float, lineno_column) ⇒ Object
# 4.2 “4.2”, [1, 2]
259 260 261 |
# File 'lib/solid/parser.rb', line 259 def handle_float(float, lineno_column) Literal.new float.to_f end |
#handle_hash(hash) ⇒ Object
# 42
- :assoclist_from_args, [[:assoc_new, [:@label, “foo:”, [1, 2]], [:@int, “42”, [1, 7]]]]
113 114 115 |
# File 'lib/solid/parser.rb', line 113 def handle_hash(hash) (hash.last) end |
#handle_ident(identifier, lineno_column) ⇒ Object
# spam “spam”, [1, 23]
241 242 243 |
# File 'lib/solid/parser.rb', line 241 def handle_ident(identifier, lineno_column) ContextVariable.new identifier end |
#handle_int(int, lineno_column) ⇒ Object
# 42 “42”, [1, 2]
253 254 255 |
# File 'lib/solid/parser.rb', line 253 def handle_int(int, lineno_column) Literal.new int.to_i end |
#handle_kw(keyword, lineno_column) ⇒ Object
# true “true”, [1, 33]
234 235 236 237 |
# File 'lib/solid/parser.rb', line 234 def handle_kw(keyword, lineno_column) raise Solid::SyntaxError, 'unknown Ripper sexp' unless KEYWORDS.has_key? keyword KEYWORDS[keyword] end |
#handle_label(label, lineno_column) ⇒ Object
# foo: “foo:”, [1, 2]
265 266 267 |
# File 'lib/solid/parser.rb', line 265 def handle_label(label, lineno_column) Literal.new label[0..-2].to_sym end |
#handle_method_add_arg(call_sexp, args_sexp) ⇒ Object
# myvar.split(‘,’, 2)
- :call, [:var_ref, [:@ident, “myvar”, [1, 1]]], :“.”, [:@ident, “split”, [1, 7]]
-
[:arg_paren, [:args_add_block, [
[:string_literal, [:string_content, [:@tstring_content, ",", [1, 14]]]], [:@int, "2", [1, 18]] ], false]]
143 144 145 146 147 |
# File 'lib/solid/parser.rb', line 143 def handle_method_add_arg(call_sexp, args_sexp) method_call = parse_one(call_sexp) method_call.arguments = method_call_args(args_sexp) method_call end |
#handle_paren(content) ⇒ Object
# (1)
- [:@int, “42”, [1, 2]]
184 185 186 |
# File 'lib/solid/parser.rb', line 184 def handle_paren(content) parse_one(content.first) end |
#handle_regexp_literal(regexp_literal, lineno_column) ⇒ Object
223 224 225 |
# File 'lib/solid/parser.rb', line 223 def handle_regexp_literal(regexp_literal, lineno_column) Literal.new Regexp.new(regexp_literal.first[1]) end |
#handle_string_content(*parts) ⇒ Object
207 208 209 |
# File 'lib/solid/parser.rb', line 207 def handle_string_content(*parts) parts.map(&method(:parse_one)).join end |
#handle_string_literal(string_content) ⇒ Object
# ‘mystring’
- :string_content, [:@tstring_content, “mystring”, [1, 14]]
-
TODO: handle string interpolation
203 204 205 |
# File 'lib/solid/parser.rb', line 203 def handle_string_literal(string_content) Literal.new(parse_one(string_content)) end |
#handle_tstring_content(string_content, lineno_column) ⇒ Object
- :@tstring_content, “mystring”, [1, 14]
212 213 214 |
# File 'lib/solid/parser.rb', line 212 def handle_tstring_content(string_content, lineno_column) string_content end |
#handle_unary(operator, operand) ⇒ Object
# !true
- :!, [:var_ref, [:@kw, “true”, [1, 1]]]
165 166 167 |
# File 'lib/solid/parser.rb', line 165 def handle_unary(operator, operand) MethodCall.new(parse_one(operand), operator, []) end |
#handle_var_ref(var_ref) ⇒ Object
# spam
- :@ident, “spam”, [1, 33]
-
or
# true
- :@kw, “true”, [1, 23]
101 102 103 |
# File 'lib/solid/parser.rb', line 101 def handle_var_ref(var_ref) parse_one(var_ref) end |
#handle_vcall(expression) ⇒ Object
# myvar
since 1.9.3
- :vcall, [:@ident, “myvar”, [1, 0]]
132 133 134 |
# File 'lib/solid/parser.rb', line 132 def handle_vcall(expression) parse_one(expression) end |
#method_call_args(args_sexp) ⇒ Object
# args list: (‘,’, 2) [:arg_paren, [:args_add_block, [
[:string_literal, [:string_content, [:@tstring_content, ",", [1, 14]]]],
[:@int, "2", [1, 18]]
], false]]
1 args list: ()
- :arg_paren, nil
157 158 159 160 161 |
# File 'lib/solid/parser.rb', line 157 def method_call_args(args_sexp) return [] if args_sexp[1].nil? args_sexp = args_sexp.last[1] args_sexp.map(&method(:parse_one)) end |
#parse ⇒ Object
76 77 78 79 80 |
# File 'lib/solid/parser.rb', line 76 def parse @sexp = Ripper.sexp(@string) dive_in or raise 'Ripper changed?' parse_one(@sexp) end |
#parse_one(argument) ⇒ Object
90 91 92 93 94 95 |
# File 'lib/solid/parser.rb', line 90 def parse_one(argument) type = argument.shift handler = "handle_#{type.to_s.sub('@', '')}" raise Solid::SyntaxError, "unknown Ripper type: #{type.inspect}" unless respond_to?(handler) public_send handler, *argument end |