kumi-parser 0.0.15 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/kumi/parser/direct_parser.rb +54 -0
- data/lib/kumi/parser/smart_tokenizer.rb +30 -21
- data/lib/kumi/parser/token_metadata.rb +13 -3
- data/lib/kumi/parser/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7c82cf28e39c53592ff6acb03772bc9d346716cb1dee414f4d1bce450629b9e
|
4
|
+
data.tar.gz: e9464f66ff1aae2b9d38770bdf1c9fe9d96eef114838eaec532a4408f87b8435
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4902e5502a0298fd6f9f24a9f80701910f641fa8098917d40cf0daa84f0845861c1f97aebd940bd704d213d1bce91fc1ad6971796bef76bfb2f5382aee60840
|
7
|
+
data.tar.gz: 512f5f4b80d7be91c543e1ae4f85c95835f9b52e2eb5768b4b55d4f69f27e17e640392851f3e2ee1b40003254d6160e533559f24a8e7546951b4d507c5d55950
|
@@ -398,6 +398,9 @@ module Kumi
|
|
398
398
|
when :lbracket
|
399
399
|
parse_array_literal
|
400
400
|
|
401
|
+
when :left_brace
|
402
|
+
parse_hash_literal
|
403
|
+
|
401
404
|
when :fn
|
402
405
|
# expect_token(:fn)
|
403
406
|
parse_function_call
|
@@ -520,6 +523,57 @@ module Kumi
|
|
520
523
|
Kumi::Syntax::ArrayExpression.new(elements, loc: start_token.location)
|
521
524
|
end
|
522
525
|
|
526
|
+
def parse_hash_literal
|
527
|
+
start_token = expect_token(:left_brace)
|
528
|
+
skip_comments_and_newlines
|
529
|
+
pairs = []
|
530
|
+
|
531
|
+
# Handle empty hash: {}
|
532
|
+
unless current_token.type == :right_brace
|
533
|
+
pairs << parse_hash_pair
|
534
|
+
skip_comments_and_newlines
|
535
|
+
|
536
|
+
while current_token.type == :comma
|
537
|
+
advance
|
538
|
+
skip_comments_and_newlines
|
539
|
+
# Allow trailing comma
|
540
|
+
break if current_token.type == :right_brace
|
541
|
+
|
542
|
+
pairs << parse_hash_pair
|
543
|
+
skip_comments_and_newlines
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
expect_token(:right_brace)
|
548
|
+
Kumi::Syntax::HashExpression.new(pairs, loc: start_token.location)
|
549
|
+
end
|
550
|
+
|
551
|
+
def parse_hash_pair
|
552
|
+
key_token_type = current_token.type
|
553
|
+
key = case key_token_type
|
554
|
+
when :label, :string
|
555
|
+
value = current_token.value.to_sym if key_token_type == :label
|
556
|
+
advance
|
557
|
+
Kumi::Syntax::Literal.new(value, loc: current_token.location)
|
558
|
+
else
|
559
|
+
raise_parse_error("Hash keys must be symbols (:key) or strings (\"key\"), got #{current_token.type}")
|
560
|
+
end
|
561
|
+
|
562
|
+
skip_comments_and_newlines
|
563
|
+
|
564
|
+
case current_token.type
|
565
|
+
when :arrow
|
566
|
+
advance
|
567
|
+
else
|
568
|
+
raise_parse_error("Expected '=>' in hash pair") unless key_token_type == :label
|
569
|
+
end
|
570
|
+
|
571
|
+
skip_comments_and_newlines
|
572
|
+
value = parse_expression
|
573
|
+
|
574
|
+
[key, value]
|
575
|
+
end
|
576
|
+
|
523
577
|
def convert_literal_value(token)
|
524
578
|
case token.type
|
525
579
|
when :integer then token.value.gsub('_', '').to_i
|
@@ -34,7 +34,7 @@ module Kumi
|
|
34
34
|
else
|
35
35
|
consume_operator_or_punctuation
|
36
36
|
end
|
37
|
-
when /[a-zA-Z_]/ then
|
37
|
+
when /[a-zA-Z_]/ then consume_identifier_or_label_or_keyword
|
38
38
|
when ':' then consume_symbol_or_colon
|
39
39
|
else
|
40
40
|
consume_operator_or_punctuation
|
@@ -158,26 +158,34 @@ module Kumi
|
|
158
158
|
@tokens << Token.new(token_type, number_str, location, Kumi::Parser::TOKEN_METADATA[token_type])
|
159
159
|
end
|
160
160
|
|
161
|
-
def
|
161
|
+
def consume_identifier_or_label_or_keyword
|
162
162
|
start_column = @column
|
163
|
-
|
163
|
+
identifier_or_label_name = consume_while { |c| c.match?(/[a-zA-Z0-9_]/) }
|
164
|
+
location = Kumi::Syntax::Location.new(file: @source_file, line: @line, column: start_column)
|
165
|
+
|
166
|
+
# Check if the next character is a colon
|
167
|
+
if current_char == ':'
|
168
|
+
# It's a hash key or a label (e.g., `name:`)
|
169
|
+
advance # consume the colon
|
170
|
+
add_token(:label, identifier_or_label_name, Kumi::Parser::TOKEN_METADATA[:label])
|
171
|
+
return
|
172
|
+
end
|
173
|
+
|
174
|
+
# If it's not a label, proceed to check for keywords and identifiers
|
175
|
+
# The logic below is adapted from your original `consume_identifier_or_keyword` method
|
164
176
|
|
165
177
|
# Check if it's a constant (e.g., Float::INFINITY)
|
166
|
-
if
|
178
|
+
if identifier_or_label_name == 'Float' && current_char == ':' && peek_char == ':'
|
167
179
|
advance # consume first :
|
168
180
|
advance # consume second :
|
169
181
|
constant_name = consume_while { |c| c.match?(/[a-zA-Z0-9_]/) }
|
170
|
-
full_constant = "#{
|
171
|
-
|
172
|
-
location = Kumi::Syntax::Location.new(file: @source_file, line: @line, column: start_column)
|
173
|
-
@tokens << Token.new(:constant, full_constant, location, Kumi::Parser::TOKEN_METADATA[:constant])
|
182
|
+
full_constant = "#{identifier_or_label_name}::#{constant_name}"
|
183
|
+
add_token(:constant, full_constant, Kumi::Parser::TOKEN_METADATA[:constant])
|
174
184
|
return
|
175
185
|
end
|
176
186
|
|
177
|
-
location = Kumi::Syntax::Location.new(file: @source_file, line: @line, column: start_column)
|
178
|
-
|
179
187
|
# Check if it's a keyword
|
180
|
-
if keyword_type = Kumi::Parser::KEYWORDS[
|
188
|
+
if keyword_type = Kumi::Parser::KEYWORDS[identifier_or_label_name]
|
181
189
|
metadata = Kumi::Parser::TOKEN_METADATA[keyword_type].dup
|
182
190
|
|
183
191
|
# Update context based on keyword
|
@@ -189,30 +197,26 @@ module Kumi
|
|
189
197
|
closed_context = @context_stack.pop if @context_stack.length > 1
|
190
198
|
metadata[:closes_context] = closed_context
|
191
199
|
end
|
192
|
-
|
193
|
-
@tokens << Token.new(keyword_type, identifier, location, metadata)
|
200
|
+
add_token(keyword_type, identifier_or_label_name, metadata)
|
194
201
|
return
|
195
202
|
end
|
196
203
|
|
197
204
|
# Check if its a function sugar
|
198
|
-
if Kumi::Parser::FUNCTION_SUGAR[
|
205
|
+
if Kumi::Parser::FUNCTION_SUGAR[identifier_or_label_name]
|
199
206
|
metadata = Kumi::Parser::TOKEN_METADATA[:function_sugar].dup
|
200
|
-
|
207
|
+
add_token(:function_sugar, identifier_or_label_name, metadata)
|
201
208
|
return
|
202
209
|
end
|
203
210
|
|
204
|
-
# Otherwise is an
|
211
|
+
# Otherwise is an Identifier
|
205
212
|
metadata = Kumi::Parser::TOKEN_METADATA[:identifier].dup
|
206
|
-
|
207
|
-
# Add context-specific metadata
|
208
213
|
case current_context
|
209
214
|
when :input
|
210
215
|
metadata[:context] = :input_declaration
|
211
216
|
when :schema
|
212
217
|
metadata[:context] = :schema_body
|
213
218
|
end
|
214
|
-
|
215
|
-
@tokens << Token.new(:identifier, identifier, location, metadata)
|
219
|
+
add_token(:identifier, identifier_or_label_name, metadata)
|
216
220
|
end
|
217
221
|
|
218
222
|
def consume_symbol_or_colon
|
@@ -240,7 +244,12 @@ module Kumi
|
|
240
244
|
# Handle multi-character operators
|
241
245
|
case char
|
242
246
|
when '='
|
243
|
-
if peek_char == '
|
247
|
+
if peek_char == '>'
|
248
|
+
advance
|
249
|
+
advance
|
250
|
+
location = Kumi::Syntax::Location.new(file: @source_file, line: @line, column: start_column)
|
251
|
+
@tokens << Token.new(:arrow, '=>', location, Kumi::Parser::TOKEN_METADATA[:arrow])
|
252
|
+
elsif peek_char == '='
|
244
253
|
advance
|
245
254
|
advance
|
246
255
|
location = Kumi::Syntax::Location.new(file: @source_file, line: @line, column: start_column)
|
@@ -261,7 +261,6 @@ module Kumi
|
|
261
261
|
arity: :binary,
|
262
262
|
requires_boolean: true
|
263
263
|
},
|
264
|
-
|
265
264
|
# Literals with type information
|
266
265
|
integer: {
|
267
266
|
category: :literal,
|
@@ -283,7 +282,6 @@ module Kumi
|
|
283
282
|
starts_expression: true,
|
284
283
|
ast_class: 'Kumi::Syntax::Literal'
|
285
284
|
},
|
286
|
-
|
287
285
|
# Identifiers and references
|
288
286
|
identifier: {
|
289
287
|
category: :identifier,
|
@@ -344,6 +342,15 @@ module Kumi
|
|
344
342
|
terminates_expression: true
|
345
343
|
},
|
346
344
|
|
345
|
+
left_brace: {
|
346
|
+
category: :punctuation,
|
347
|
+
opens_scope: :hash
|
348
|
+
},
|
349
|
+
right_brace: {
|
350
|
+
category: :punctuation,
|
351
|
+
closes_scope: :hash
|
352
|
+
},
|
353
|
+
|
347
354
|
# Special tokens
|
348
355
|
newline: {
|
349
356
|
category: :whitespace,
|
@@ -365,6 +372,8 @@ module Kumi
|
|
365
372
|
')' => :rparen,
|
366
373
|
'[' => :lbracket,
|
367
374
|
']' => :rbracket,
|
375
|
+
'{' => :left_brace,
|
376
|
+
'}' => :right_brace,
|
368
377
|
',' => :comma,
|
369
378
|
'.' => :dot,
|
370
379
|
':' => :colon,
|
@@ -374,7 +383,8 @@ module Kumi
|
|
374
383
|
'/' => :divide,
|
375
384
|
'%' => :modulo,
|
376
385
|
'&' => :and,
|
377
|
-
'|' => :or
|
386
|
+
'|' => :or,
|
387
|
+
'=>' => :arrow
|
378
388
|
}.freeze
|
379
389
|
|
380
390
|
FUNCTION_SUGAR = {
|
data/lib/kumi/parser/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kumi-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kumi Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-09-
|
11
|
+
date: 2025-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kumi
|