kumi-parser 0.0.11 → 0.0.13
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/README.md +9 -3
- data/lib/kumi/parser/direct_parser.rb +41 -13
- data/lib/kumi/parser/smart_tokenizer.rb +5 -3
- data/lib/kumi/parser/token_metadata.rb +8 -1
- 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: 7dbd29c99827160178d8ebaebc68ada7b754f2ecdbc99d5c204dc6396431e18f
|
4
|
+
data.tar.gz: cef86a4ebd6b3398d70255a9111832ad9094626da74936e3d858fcba41999efa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af373812dec2bc63ffa5279d5f7adbd2c852f272969dcec65196ddca750d965dbe8b37496f99004975e1a2dbbabac3e7f5cfc5e348bd16b51b2a1261315b97eb
|
7
|
+
data.tar.gz: b3faf218a65da205f4f20651e808dcbfc32bd8ace3a63a479aa576909bcb0f0e9ea066fab04d8013a4046faaa0332a8cf5e223f8f785d8652518d7b89134168e
|
data/README.md
CHANGED
@@ -58,7 +58,15 @@ end
|
|
58
58
|
|
59
59
|
**Function calls**: `fn(:name, arg1, arg2, ...)`
|
60
60
|
**Operators**: `+` `-` `*` `/` `%` `>` `<` `>=` `<=` `==` `!=` `&` `|`
|
61
|
-
**References**: `input.field`, `value_name`, `array[index]`
|
61
|
+
**References**: `input.field`, `value_name`, `array[index]`
|
62
|
+
**Strings**: Both `"double"` and `'single'` quotes supported
|
63
|
+
**Element syntax**: `element :type, :name` for array element specifications
|
64
|
+
|
65
|
+
## Ruby DSL Differences
|
66
|
+
|
67
|
+
**String concatenation**: Ruby DSL evaluates `"Hello" + "World"` → `Literal("HelloWorld")`, text parser → `CallExpression(:add, [...])`.
|
68
|
+
|
69
|
+
**Semantically equivalent** - both should execute identically.
|
62
70
|
|
63
71
|
## Architecture
|
64
72
|
|
@@ -66,8 +74,6 @@ end
|
|
66
74
|
- `direct_ast_parser.rb` - Recursive descent parser, direct AST construction
|
67
75
|
- `token_metadata.rb` - Token types, precedence, and semantic hints
|
68
76
|
|
69
|
-
See `docs/` for technical details.
|
70
|
-
|
71
77
|
## License
|
72
78
|
|
73
79
|
MIT
|
@@ -110,7 +110,17 @@ module Kumi
|
|
110
110
|
end
|
111
111
|
|
112
112
|
advance
|
113
|
-
|
113
|
+
|
114
|
+
# Handle element syntax: element :type, :name
|
115
|
+
if type_token.metadata[:type_name] == :element
|
116
|
+
element_type_token = expect_token(:symbol)
|
117
|
+
expect_token(:comma)
|
118
|
+
name_token = expect_token(:symbol)
|
119
|
+
actual_type = element_type_token.value
|
120
|
+
else
|
121
|
+
name_token = expect_token(:symbol)
|
122
|
+
actual_type = type_token.metadata[:type_name]
|
123
|
+
end
|
114
124
|
|
115
125
|
# Handle domain specification: ', domain: [...]'
|
116
126
|
domain = nil
|
@@ -126,9 +136,9 @@ module Kumi
|
|
126
136
|
end
|
127
137
|
end
|
128
138
|
|
129
|
-
# Handle nested array and
|
139
|
+
# Handle nested array, hash, and element declarations
|
130
140
|
children = []
|
131
|
-
if %i[array hash].include?(
|
141
|
+
if %i[array hash element].include?(actual_type) && current_token.type == :do
|
132
142
|
advance # consume 'do'
|
133
143
|
skip_comments_and_newlines
|
134
144
|
|
@@ -147,7 +157,7 @@ module Kumi
|
|
147
157
|
Kumi::Syntax::InputDeclaration.new(
|
148
158
|
name_token.value,
|
149
159
|
domain,
|
150
|
-
|
160
|
+
actual_type,
|
151
161
|
children,
|
152
162
|
loc: type_token.location
|
153
163
|
)
|
@@ -155,7 +165,7 @@ module Kumi
|
|
155
165
|
Kumi::Syntax::InputDeclaration.new(
|
156
166
|
name_token.value,
|
157
167
|
domain,
|
158
|
-
|
168
|
+
actual_type,
|
159
169
|
children,
|
160
170
|
:field,
|
161
171
|
loc: type_token.location
|
@@ -273,18 +283,35 @@ module Kumi
|
|
273
283
|
Kumi::Syntax::CascadeExpression.new(cases, loc: start_token.location)
|
274
284
|
end
|
275
285
|
|
276
|
-
# Case expression: 'on
|
286
|
+
# Case expression: 'on condition1, condition2, ..., result' or 'base result'
|
277
287
|
def parse_case_expression
|
278
288
|
case current_token.type
|
279
289
|
when :on
|
280
290
|
on_token = advance_and_return_token
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
291
|
+
|
292
|
+
# Parse all comma-separated expressions
|
293
|
+
expressions = []
|
294
|
+
expressions << parse_expression
|
295
|
+
|
296
|
+
# Continue parsing comma-separated expressions until end of case
|
297
|
+
while current_token.type == :comma
|
298
|
+
advance # consume comma
|
299
|
+
expressions << parse_expression
|
300
|
+
end
|
301
|
+
|
302
|
+
# Last expression is the result, all others are conditions
|
303
|
+
result = expressions.pop
|
304
|
+
conditions = expressions
|
305
|
+
|
306
|
+
# Combine conditions appropriately
|
307
|
+
if conditions.length == 1
|
308
|
+
condition = conditions[0]
|
309
|
+
# Wrap simple trait references in cascade_and to match Ruby DSL behavior
|
310
|
+
condition = wrap_condition_in_all(condition) if simple_trait_reference?(condition)
|
311
|
+
else
|
312
|
+
# Multiple conditions: combine with cascade_and
|
313
|
+
condition = Kumi::Syntax::CallExpression.new(:cascade_and, conditions, loc: on_token.location)
|
314
|
+
end
|
288
315
|
|
289
316
|
Kumi::Syntax::CaseExpression.new(condition, result, loc: on_token.location)
|
290
317
|
|
@@ -570,6 +597,7 @@ module Kumi
|
|
570
597
|
condition.is_a?(Kumi::Syntax::DeclarationReference)
|
571
598
|
end
|
572
599
|
|
600
|
+
|
573
601
|
# Helper method to wrap condition in cascade_and function call
|
574
602
|
def wrap_condition_in_all(condition)
|
575
603
|
Kumi::Syntax::CallExpression.new(:cascade_and, [condition], loc: condition.loc)
|
@@ -26,7 +26,7 @@ module Kumi
|
|
26
26
|
when nil then break
|
27
27
|
when "\n" then handle_newline
|
28
28
|
when '#' then consume_comment
|
29
|
-
when '"' then consume_string
|
29
|
+
when '"', "'" then consume_string
|
30
30
|
when /\d/ then consume_number
|
31
31
|
when '-'
|
32
32
|
if peek_char && peek_char.match?(/\d/)
|
@@ -95,10 +95,11 @@ module Kumi
|
|
95
95
|
|
96
96
|
def consume_string
|
97
97
|
start_column = @column
|
98
|
+
quote_char = current_char # Remember which quote type we're using
|
98
99
|
advance # skip opening quote
|
99
100
|
|
100
101
|
string_content = ''
|
101
|
-
while current_char && current_char !=
|
102
|
+
while current_char && current_char != quote_char
|
102
103
|
if current_char == '\\'
|
103
104
|
advance
|
104
105
|
# Handle escape sequences
|
@@ -108,6 +109,7 @@ module Kumi
|
|
108
109
|
when 'r' then string_content += "\r"
|
109
110
|
when '\\' then string_content += '\\'
|
110
111
|
when '"' then string_content += '"'
|
112
|
+
when "'" then string_content += "'"
|
111
113
|
else
|
112
114
|
string_content += current_char if current_char
|
113
115
|
end
|
@@ -117,7 +119,7 @@ module Kumi
|
|
117
119
|
advance
|
118
120
|
end
|
119
121
|
|
120
|
-
raise_tokenizer_error('Unterminated string literal') if current_char !=
|
122
|
+
raise_tokenizer_error('Unterminated string literal') if current_char != quote_char
|
121
123
|
|
122
124
|
advance # skip closing quote
|
123
125
|
|
@@ -32,6 +32,7 @@ module Kumi
|
|
32
32
|
BOOLEAN_TYPE = :boolean_type # boolean
|
33
33
|
ANY_TYPE = :any_type # any
|
34
34
|
ARRAY_TYPE = :array_type # array
|
35
|
+
ELEMENT_TYPE = :element_type # element
|
35
36
|
|
36
37
|
# Function keywords
|
37
38
|
FN = :fn
|
@@ -149,6 +150,11 @@ module Kumi
|
|
149
150
|
starts_declaration: true,
|
150
151
|
type_name: :hash
|
151
152
|
},
|
153
|
+
element_type: {
|
154
|
+
category: :type_keyword,
|
155
|
+
starts_declaration: true,
|
156
|
+
type_name: :element
|
157
|
+
},
|
152
158
|
|
153
159
|
# Function keyword
|
154
160
|
fn: {
|
@@ -385,7 +391,8 @@ module Kumi
|
|
385
391
|
'boolean' => :boolean_type,
|
386
392
|
'any' => :any_type,
|
387
393
|
'array' => :array_type,
|
388
|
-
'hash' => :hash_type
|
394
|
+
'hash' => :hash_type,
|
395
|
+
'element' => :element_type
|
389
396
|
}.freeze
|
390
397
|
|
391
398
|
# Opener to closer mappings for error recovery
|
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.13
|
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-08-
|
11
|
+
date: 2025-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kumi
|