From 6969163ccf9d11ea846c64588c286e3ba000ade9 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 30 Oct 2025 02:05:07 +0900 Subject: [PATCH 01/29] Update toml-test --- toml-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml-test b/toml-test index 4634fdf..8be0db7 160000 --- a/toml-test +++ b/toml-test @@ -1 +1 @@ -Subproject commit 4634fdf3a6ecd6aaea5f4cdcd98b2733c2694993 +Subproject commit 8be0db7469af2d97449e0a06075a1a6ecdc60231 From 38e4a31d483134d78af223b4fb9ac761dbf03415 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 30 Oct 2025 02:08:28 +0900 Subject: [PATCH 02/29] Update toml-test to v1.6.0 --- toml-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml-test b/toml-test index 8be0db7..369cc3a 160000 --- a/toml-test +++ b/toml-test @@ -1 +1 @@ -Subproject commit 8be0db7469af2d97449e0a06075a1a6ecdc60231 +Subproject commit 369cc3ae275fd76b6e21780ebf87609e5b2a951a From 714337636d8b4aaf252d34a70f5a63654da3b9d9 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 30 Oct 2025 03:44:31 +0900 Subject: [PATCH 03/29] Fix a bug of process_json --- test/test_compliance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_compliance.rb b/test/test_compliance.rb index 89c7f0e..ebdcbdd 100644 --- a/test/test_compliance.rb +++ b/test/test_compliance.rb @@ -119,7 +119,7 @@ def process_json_leaf(node) def process_json(node) case node when Hash - if node['type'] + if node.keys == ['type', 'value'] process_json_leaf(node) else node.each_with_object({}) {|(key, value), table| From 5bf8aeb7c9c38da72af85943b9be70a3e1abfdeb Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 30 Oct 2025 04:54:58 +0900 Subject: [PATCH 04/29] Increase possible error for invalid TOML --- test/test_compliance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_compliance.rb b/test/test_compliance.rb index ebdcbdd..b28b827 100644 --- a/test/test_compliance.rb +++ b/test/test_compliance.rb @@ -53,7 +53,7 @@ local_path = toml_path.relative_path_from(Pathname.new(File.join(__dir__, '..'))) it "raises an error on parsing #{local_path}" do - _{ Tomlrb.load_file(toml_path.to_path) }.must_raise Tomlrb::ParseError, RangeError, ArgumentError + _{ Tomlrb.load_file(toml_path.to_path) }.must_raise Tomlrb::ParseError, RangeError, ArgumentError, IndexError, TypeError end end end From 214d8ae64dae8e9e0e803e4ba692afcb48e841da Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 30 Oct 2025 05:17:46 +0900 Subject: [PATCH 05/29] Don't TOML valid only for 1.1 --- test/test_compliance.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/test_compliance.rb b/test/test_compliance.rb index b28b827..dd25d9c 100644 --- a/test/test_compliance.rb +++ b/test/test_compliance.rb @@ -25,6 +25,10 @@ ] describe Tomlrb::Parser do + toml_test_list_file = File.join(__dir__, '../toml-test/tests/files-toml-1.0.0') + toml_test_list = File.readlines(toml_test_list_file, chomp: true) + toml_test_list_base = Pathname.new("toml-test/tests") + tests_dirs = [ File.join(__dir__, '../toml-spec-tests'), File.join(__dir__, '../toml-test/tests') @@ -34,6 +38,11 @@ toml_path = toml_path.expand_path local_path = toml_path.relative_path_from(Pathname.new(File.join(__dir__, '..'))) + if tests_dir == File.join(__dir__, '../toml-test/tests') + path_in_list = local_path.relative_path_from(toml_test_list_base) + next unless toml_test_list.include?(path_in_list.to_path) + end + it "parses #{local_path}" do actual = Tomlrb.load_file(toml_path.to_path) json_path = toml_path.sub_ext('.json') @@ -52,6 +61,11 @@ toml_path = toml_path.expand_path local_path = toml_path.relative_path_from(Pathname.new(File.join(__dir__, '..'))) + if tests_dir == File.join(__dir__, '../toml-test/tests') + path_in_list = local_path.relative_path_from(toml_test_list_base) + next unless toml_test_list.include?(path_in_list.to_path) + end + it "raises an error on parsing #{local_path}" do _{ Tomlrb.load_file(toml_path.to_path) }.must_raise Tomlrb::ParseError, RangeError, ArgumentError, IndexError, TypeError end From c59ee281b8ea533d2bb9abd995aef28d66e9ccce Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 30 Oct 2025 06:00:04 +0900 Subject: [PATCH 06/29] Raise error when duplicate key declaration after implicite key generation compliant with toml-test/tests/invalid/table/super-twice.toml --- lib/tomlrb/handler.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/tomlrb/handler.rb b/lib/tomlrb/handler.rb index a7a0f3e..d8b6fd9 100644 --- a/lib/tomlrb/handler.rb +++ b/lib/tomlrb/handler.rb @@ -175,6 +175,7 @@ def find_or_create_first_table_key(current, key, declared, is_array_of_tables) raise Key::KeyConflict, "Key #{key} is already used" end k = existed || Key.new(key, :table, declared) + k.declared = k.declared? || declared current[key] = k k end @@ -206,6 +207,7 @@ class Key class KeyConflict < ParseError; end attr_reader :key, :type + attr_writer :declared def initialize(key, type, declared = false) @key = key From 3b01645fcb15747bf7c91e8c5ab32b031abe92c3 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Thu, 30 Oct 2025 06:55:31 +0900 Subject: [PATCH 07/29] Raise error for invalid date time --- lib/tomlrb/local_date.rb | 3 ++- lib/tomlrb/local_date_time.rb | 4 +++- lib/tomlrb/local_time.rb | 3 ++- lib/tomlrb/parser.y | 5 ++++- test/test_local_date_time.rb | 6 ++++++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/tomlrb/local_date.rb b/lib/tomlrb/local_date.rb index 8c8d786..d2201bd 100644 --- a/lib/tomlrb/local_date.rb +++ b/lib/tomlrb/local_date.rb @@ -9,7 +9,8 @@ class LocalDate def_delegators :@time, :year, :month, :day def initialize(year, month, day) - @time = Time.new(year, month, day, 0, 0, 0, '-00:00') + @time = Time.utc(year, month, day, 0, 0, 0) + raise ArgumentError, "Invalid Local Date: #{year}-#{month}-#{day}" unless day.to_i == @time.day && month.to_i == @time.month && year.to_i == @time.year end # @param offset see {LocalDateTime#to_time} diff --git a/lib/tomlrb/local_date_time.rb b/lib/tomlrb/local_date_time.rb index 2bbd373..27ef91b 100644 --- a/lib/tomlrb/local_date_time.rb +++ b/lib/tomlrb/local_date_time.rb @@ -9,7 +9,9 @@ class LocalDateTime def_delegators :@time, :year, :month, :day, :hour, :min, :sec, :usec, :nsec def initialize(year, month, day, hour, min, sec) # rubocop:disable Metrics/ParameterLists - @time = Time.new(year, month, day, hour, min, sec, '-00:00') + @time = Time.utc(year, month, day, hour, min, sec) + raise ArgumentError, "Invalid Local Date-Time: #{year}-#{month}-#{day}T#{hour}:#{min}:#{sec}" unless min.to_i == @time.min && hour.to_i == @time.hour && day.to_i == @time.day && month.to_i == @time.month && year.to_i == @time.year + @sec = sec end diff --git a/lib/tomlrb/local_time.rb b/lib/tomlrb/local_time.rb index 95f9922..e240e2b 100644 --- a/lib/tomlrb/local_time.rb +++ b/lib/tomlrb/local_time.rb @@ -9,7 +9,8 @@ class LocalTime def_delegators :@time, :hour, :min, :sec, :usec, :nsec def initialize(hour, min, sec) - @time = Time.new(0, 1, 1, hour, min, sec, '-00:00') + @time = Time.utc(0, 1, 1, hour, min, sec) + raise ArgumentError, "Invalid Local Time: #{hour}-#{min}-#{sec}" unless min.to_i == @time.min && hour.to_i == @time.hour @sec = sec end diff --git a/lib/tomlrb/parser.y b/lib/tomlrb/parser.y index 579afe1..6029bde 100644 --- a/lib/tomlrb/parser.y +++ b/lib/tomlrb/parser.y @@ -183,7 +183,10 @@ rule v[3] = (v[3].to_i + 1).to_s end - Time.new(v[0], v[1], v[2], v[3] || 0, v[4] || 0, v[5].to_f, v[6]) + time = Time.new(v[0], v[1], v[2], v[3] || 0, v[4] || 0, v[5].to_f, v[6]) + # Should be out of parser.y? + raise ArgumentError, "Invalid Offset Date-Time: #{v[0]}-#{v[1]}-#{v[2]}T#{v[3]}:#{v[4]}:#{v[5]}#{v[6]}" unless v[4].to_i == time.min && v[3].to_i == time.hour && v[2].to_i == time.day && v[1].to_i == time.month && v[0].to_i == time.year + time end } | LOCAL_TIME { result = LocalTime.new(*val[0]) } diff --git a/test/test_local_date_time.rb b/test/test_local_date_time.rb index 4d483ed..c057509 100644 --- a/test/test_local_date_time.rb +++ b/test/test_local_date_time.rb @@ -44,6 +44,12 @@ def time_knows_zone_names? _(d.to_s).must_equal '1979-05-27' end + it 'raises error for invalid date' do + assert_raises ArgumentError do + Tomlrb::LocalDate.new('2100', '02', '29') + end + end + describe '#to_time' do subject { Tomlrb::LocalDate.new('1979', '05', '27') } From fb9a8722378ae2cfbee9e90b5ea75feea0d2132a Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 1 Nov 2025 22:48:39 +0900 Subject: [PATCH 08/29] Prevent double comma --- lib/tomlrb/generated_parser.rb | 419 +++++++++++++++++++++------------ lib/tomlrb/parser.y | 55 ++++- lib/tomlrb/scanner.rb | 2 + 3 files changed, 309 insertions(+), 167 deletions(-) diff --git a/lib/tomlrb/generated_parser.rb b/lib/tomlrb/generated_parser.rb index 70ab368..4352755 100644 --- a/lib/tomlrb/generated_parser.rb +++ b/lib/tomlrb/generated_parser.rb @@ -10,100 +10,118 @@ class GeneratedParser < Racc::Parser ##### State transition tables begin ### racc_action_table = [ - 2, 45, 16, 56, 17, 44, 18, 55, 23, 19, - 20, 14, 21, 22, 8, 4, 10, 36, 16, 12, - 17, 48, 18, 46, 47, 19, 20, 42, 21, 22, - 50, 51, 87, 86, 39, 54, 39, 72, 73, 74, - 75, 70, 71, 67, 68, 65, 66, 69, 78, nil, - 59, nil, nil, 12, 72, 73, 74, 75, 70, 71, - 67, 68, 65, 66, 69, nil, nil, 59, nil, nil, - 12, 72, 73, 74, 75, 70, 71, 67, 68, 65, - 66, 69, 91, nil, 59, 89, nil, 12, 72, 73, - 74, 75, 70, 71, 67, 68, 65, 66, 69, 91, - nil, 59, 89, nil, 12, 72, 73, 74, 75, 70, - 71, 67, 68, 65, 66, 69, 91, nil, 59, 89, - nil, 12, 72, 73, 74, 75, 70, 71, 67, 68, - 65, 66, 69, 91, nil, 59, 89, 29, 12, 30, - nil, 31, nil, nil, 32, 33, 27, 34, 35, 29, - nil, 30, 25, 31, nil, nil, 32, 33, 81, 34, - 35, 16, nil, 17, 25, 18, nil, nil, 19, 20, - 77, 21, 22, 16, nil, 17, nil, 18, nil, nil, - 19, 20, 42, 21, 22, 16, nil, 17, nil, 18, - nil, nil, 19, 20, 85, 21, 22, 95, nil, nil, - 93, nil, nil, nil, 94 ] + 2, 95, 16, 95, 17, 111, 18, 118, 23, 19, + 20, 14, 21, 22, 8, 36, 4, 10, 109, 16, + 12, 17, 119, 18, 50, 51, 19, 20, 42, 21, + 22, 95, 105, 95, 105, 94, 48, 94, 39, 73, + 74, 75, 76, 71, 72, 68, 69, 66, 67, 70, + 109, 114, 45, 59, 108, 44, 12, 73, 74, 75, + 76, 71, 72, 68, 69, 66, 67, 70, 109, 39, + 56, 59, 123, 55, 12, 73, 74, 75, 76, 71, + 72, 68, 69, 66, 67, 70, 95, 93, 54, 59, + 94, 79, 12, 73, 74, 75, 76, 71, 72, 68, + 69, 66, 67, 70, 109, 107, nil, 59, 108, nil, + 12, 73, 74, 75, 76, 71, 72, 68, 69, 66, + 67, 70, 95, nil, nil, 59, 111, nil, 12, 73, + 74, 75, 76, 71, 72, 68, 69, 66, 67, 70, + 95, nil, nil, 59, 118, nil, 12, 73, 74, 75, + 76, 71, 72, 68, 69, 66, 67, 70, 109, nil, + nil, 59, 119, nil, 12, 73, 74, 75, 76, 71, + 72, 68, 69, 66, 67, 70, 109, nil, nil, 59, + 123, 29, 12, 30, 46, 31, 47, nil, 32, 33, + 27, 34, 35, 88, 29, 87, 30, 25, 31, nil, + nil, 32, 33, 82, 34, 35, nil, 16, nil, 17, + 25, 18, nil, nil, 19, 20, 78, 21, 22, 16, + nil, 17, nil, 18, nil, nil, 19, 20, 42, 21, + 22, 16, nil, 17, nil, 18, nil, nil, 19, 20, + 86, 21, 22 ] racc_action_check = [ - 1, 13, 1, 41, 1, 13, 1, 41, 2, 1, - 1, 1, 1, 1, 1, 1, 1, 10, 11, 1, - 11, 25, 11, 24, 24, 11, 11, 11, 11, 11, - 26, 26, 57, 57, 38, 40, 11, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 50, nil, - 44, nil, nil, 44, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, nil, nil, 55, nil, nil, - 55, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, nil, 58, 58, nil, 58, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - nil, 91, 91, nil, 91, 94, 94, 94, 94, 94, - 94, 94, 94, 94, 94, 94, 94, nil, 94, 94, - nil, 94, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, nil, 95, 95, 9, 95, 9, - nil, 9, nil, nil, 9, 9, 9, 9, 9, 51, - nil, 51, 9, 51, nil, nil, 51, 51, 51, 51, - 51, 45, nil, 45, 51, 45, nil, nil, 45, 45, - 45, 45, 45, 54, nil, 54, nil, 54, nil, nil, - 54, 54, 54, 54, 54, 56, nil, 56, nil, 56, - nil, nil, 56, 56, 56, 56, 56, 90, nil, nil, - 90, nil, nil, nil, 90 ] + 1, 93, 1, 107, 1, 93, 1, 107, 2, 1, + 1, 1, 1, 1, 1, 10, 1, 1, 110, 11, + 1, 11, 110, 11, 26, 26, 11, 11, 11, 11, + 11, 89, 89, 101, 101, 89, 25, 101, 11, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 104, 104, 13, 44, 104, 13, 44, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 117, 38, + 41, 55, 117, 41, 55, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 40, 58, + 58, 50, 58, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, nil, 91, 91, nil, + 91, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, nil, nil, 105, 105, nil, 105, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, nil, nil, 114, 114, nil, 114, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, nil, + nil, 115, 115, nil, 115, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, nil, nil, 120, + 120, 9, 120, 9, 24, 9, 24, nil, 9, 9, + 9, 9, 9, 57, 51, 57, 51, 9, 51, nil, + nil, 51, 51, 51, 51, 51, nil, 45, nil, 45, + 51, 45, nil, nil, 45, 45, 45, 45, 45, 54, + nil, 54, nil, 54, nil, nil, 54, 54, 54, 54, + 54, 56, nil, 56, nil, 56, nil, nil, 56, 56, + 56, 56, 56 ] racc_action_pointer = [ - nil, 0, 8, nil, nil, nil, nil, nil, nil, 135, - 1, 16, nil, -17, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 9, 4, 13, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 14, nil, - 14, -15, nil, nil, 34, 159, nil, nil, nil, nil, - 31, 147, nil, nil, 171, 51, 183, 18, 68, nil, + nil, 0, 8, nil, nil, nil, nil, nil, nil, 179, + -2, 17, nil, 33, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 170, 18, 6, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 48, nil, + 73, 51, nil, nil, 36, 205, nil, nil, nil, nil, + 73, 192, nil, nil, 217, 54, 229, 179, 72, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - 183, 85, nil, nil, 102, 119, nil, nil, nil ] + nil, nil, nil, nil, nil, nil, nil, nil, nil, 17, + nil, 90, nil, -13, nil, nil, nil, nil, nil, nil, + nil, 19, nil, nil, 36, 108, nil, -11, nil, nil, + 4, nil, nil, nil, 126, 144, nil, 54, nil, nil, + 162, nil, nil, nil, nil ] racc_action_default = [ - -1, -79, -79, -2, -3, -4, -5, -6, -7, -79, - -11, -79, -31, -79, -45, -46, -47, -48, -49, -50, - -51, -52, -53, 99, -79, -13, -79, -20, -21, -22, - -23, -24, -25, -26, -27, -28, -10, -29, -79, -32, - -33, -79, -39, -40, -67, -79, -8, -9, -12, -14, - -16, -79, -30, -34, -79, -67, -79, -79, -67, -61, - -62, -63, -64, -65, -66, -68, -69, -70, -71, -72, - -73, -74, -75, -76, -77, -78, -43, -44, -15, -17, - -18, -19, -35, -36, -37, -38, -41, -42, -54, -55, - -79, -67, -56, -58, -67, -67, -57, -59, -60 ] + -1, -98, -98, -2, -3, -4, -5, -6, -7, -98, + -11, -98, -31, -98, -45, -46, -47, -48, -49, -50, + -51, -52, -53, 125, -98, -13, -98, -20, -21, -22, + -23, -24, -25, -26, -27, -28, -10, -29, -98, -32, + -33, -98, -39, -40, -85, -98, -8, -9, -12, -14, + -16, -98, -30, -34, -98, -85, -98, -98, -98, -66, + -75, -76, -77, -81, -82, -86, -87, -88, -89, -90, + -91, -92, -93, -94, -95, -96, -97, -43, -44, -15, + -17, -18, -19, -35, -36, -37, -38, -41, -42, -98, + -56, -98, -59, -98, -72, -74, -78, -79, -80, -83, + -84, -98, -55, -61, -98, -98, -58, -98, -71, -73, + -98, -70, -54, -60, -98, -98, -65, -98, -68, -69, + -98, -63, -64, -67, -62 ] racc_goto_table = [ - 15, 24, 38, 88, 28, 37, 57, 1, 3, 5, - 6, 7, 9, 49, 53, 13, 92, 83, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 52, nil, nil, nil, 96, nil, nil, 97, - 98, nil, nil, 79, 76, 82, 80, nil, nil, nil, - nil, nil, nil, nil, nil, 84 ] + 92, 7, 91, 38, 15, 37, 103, 90, 57, 61, + 24, 28, 63, 65, 1, 3, 5, 6, 113, 84, + 61, 9, 49, 63, 65, 53, 13, 89, 101, nil, + nil, nil, 52, 106, nil, nil, nil, 110, 102, nil, + nil, nil, nil, nil, 62, nil, 83, 116, 77, 115, + 112, 117, 80, 81, nil, 62, 121, 122, 120, 85, + nil, nil, 124 ] racc_goto_check = [ - 18, 7, 13, 22, 10, 12, 17, 1, 2, 3, - 4, 5, 6, 9, 15, 19, 23, 17, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 12, nil, nil, nil, 22, nil, nil, 22, - 22, nil, nil, 7, 18, 13, 10, nil, nil, nil, - nil, nil, nil, nil, nil, 18 ] + 26, 5, 25, 13, 18, 12, 27, 24, 17, 20, + 7, 10, 30, 32, 1, 2, 3, 4, 27, 17, + 20, 6, 9, 30, 32, 15, 19, 22, 23, nil, + nil, nil, 12, 26, nil, nil, nil, 25, 24, nil, + nil, nil, nil, nil, 5, nil, 13, 26, 18, 25, + 24, 25, 7, 10, nil, 5, 26, 26, 25, 18, + nil, nil, 26 ] racc_goto_pointer = [ - nil, 7, 7, 8, 9, 10, 11, -8, nil, -13, - -5, nil, -6, -9, nil, -26, nil, -38, -1, 14, - nil, nil, -55, -74, nil, nil, nil ] + nil, 14, 14, 15, 16, 0, 20, 1, nil, -4, + 2, nil, -6, -8, nil, -15, nil, -36, 3, 25, + -35, nil, -31, -61, -51, -56, -58, -83, nil, nil, + -32, nil, -31 ] racc_goto_default = [ - nil, nil, nil, nil, nil, 62, nil, nil, 26, nil, - nil, 11, nil, nil, 40, nil, 41, 90, 43, nil, - 61, 58, nil, nil, 60, 63, 64 ] + nil, nil, nil, nil, nil, 98, nil, nil, 26, nil, + nil, 11, nil, nil, 40, nil, 41, nil, 43, nil, + 97, 58, nil, nil, nil, 104, nil, nil, 60, 96, + 99, 64, 100 ] racc_reduce_table = [ 0, 0, :racc_error, @@ -160,35 +178,54 @@ class GeneratedParser < Racc::Parser 1, 41, :_reduce_none, 1, 41, :_reduce_none, 1, 41, :_reduce_none, + 4, 43, :_reduce_none, + 3, 43, :_reduce_none, 2, 43, :_reduce_none, - 1, 45, :_reduce_55, + 0, 45, :_reduce_none, 2, 45, :_reduce_none, - 2, 45, :_reduce_none, - 1, 46, :_reduce_58, - 2, 46, :_reduce_none, + 1, 45, :_reduce_none, 2, 46, :_reduce_none, - 1, 44, :_reduce_61, - 1, 40, :_reduce_62, + 1, 46, :_reduce_none, + 4, 50, :_reduce_none, + 3, 50, :_reduce_none, + 3, 50, :_reduce_none, + 2, 50, :_reduce_none, + 1, 44, :_reduce_66, + 4, 47, :_reduce_67, + 3, 47, :_reduce_68, + 3, 47, :_reduce_69, + 2, 47, :_reduce_70, + 2, 47, :_reduce_71, + 1, 47, :_reduce_72, + 2, 48, :_reduce_none, + 1, 48, :_reduce_none, + 1, 40, :_reduce_75, 1, 40, :_reduce_none, 1, 40, :_reduce_none, - 1, 47, :_reduce_none, - 1, 47, :_reduce_none, - 0, 49, :_reduce_none, - 1, 49, :_reduce_68, - 1, 49, :_reduce_69, - 1, 49, :_reduce_70, - 1, 49, :_reduce_71, - 1, 49, :_reduce_72, - 1, 49, :_reduce_73, - 1, 49, :_reduce_74, - 1, 48, :_reduce_75, - 1, 48, :_reduce_76, - 1, 48, :_reduce_77, - 1, 48, :_reduce_78 ] - -racc_reduce_n = 79 - -racc_shift_n = 99 + 1, 49, :_reduce_78, + 1, 49, :_reduce_none, + 1, 49, :_reduce_none, + 1, 51, :_reduce_none, + 1, 51, :_reduce_none, + 1, 52, :_reduce_none, + 1, 52, :_reduce_none, + 0, 54, :_reduce_none, + 1, 54, :_reduce_none, + 1, 55, :_reduce_87, + 1, 55, :_reduce_88, + 1, 55, :_reduce_89, + 1, 55, :_reduce_90, + 1, 55, :_reduce_91, + 1, 55, :_reduce_92, + 1, 55, :_reduce_93, + 1, 53, :_reduce_94, + 1, 53, :_reduce_95, + 1, 53, :_reduce_96, + 1, 53, :_reduce_97 ] + +racc_reduce_n = 98 + +racc_shift_n = 125 racc_token_table = { false => 0, @@ -206,13 +243,13 @@ class GeneratedParser < Racc::Parser :FLOAT_KEYWORD => 12, :BOOLEAN => 13, :NEWLINE => 14, - :EOS => 15, - "[" => 16, - "]" => 17, - "." => 18, - "{" => 19, - "}" => 20, - "," => 21, + :COMMA => 15, + :EOS => 16, + "[" => 17, + "]" => 18, + "." => 19, + "{" => 20, + "}" => 21, "=" => 22 } racc_nt_base = 23 @@ -252,13 +289,13 @@ class GeneratedParser < Racc::Parser "FLOAT_KEYWORD", "BOOLEAN", "NEWLINE", + "COMMA", "EOS", "\"[\"", "\"]\"", "\".\"", "\"{\"", "\"}\"", - "\",\"", "\"=\"", "$start", "expressions", @@ -282,14 +319,20 @@ class GeneratedParser < Racc::Parser "assignment_key", "array", "start_array", - "array_continued", - "array_next", + "array_first_value", + "array_values", + "end_array", + "newlines", + "non_nil_value", + "array_value", "scalar", + "non_nil_scalar", "string", - "literal" ] + "literal", + "non_nil_literal" ] Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) -Racc_debug_parser = false +Racc_debug_parser = true ##### State transition tables end ##### @@ -554,61 +597,124 @@ def _reduce_48(val, _values, result) # reduce 54 omitted -module_eval(<<'.,.,', 'parser.y', 130) - def _reduce_55(val, _values, result) +# reduce 55 omitted + +# reduce 56 omitted + +# reduce 57 omitted + +# reduce 58 omitted + +# reduce 59 omitted + +# reduce 60 omitted + +# reduce 61 omitted + +# reduce 62 omitted + +# reduce 63 omitted + +# reduce 64 omitted + +# reduce 65 omitted + +module_eval(<<'.,.,', 'parser.y', 147) + def _reduce_66(val, _values, result) + @handler.start_(:array) + result + end +.,., + +module_eval(<<'.,.,', 'parser.y', 150) + def _reduce_67(val, _values, result) array = @handler.end_(:array); @handler.push(array.compact) result end .,., -# reduce 56 omitted +module_eval(<<'.,.,', 'parser.y', 151) + def _reduce_68(val, _values, result) + array = @handler.end_(:array); @handler.push(array.compact) + result + end +.,., -# reduce 57 omitted +module_eval(<<'.,.,', 'parser.y', 152) + def _reduce_69(val, _values, result) + array = @handler.end_(:array); @handler.push(array.compact) + result + end +.,., -module_eval(<<'.,.,', 'parser.y', 135) - def _reduce_58(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 153) + def _reduce_70(val, _values, result) array = @handler.end_(:array); @handler.push(array.compact) result end .,., -# reduce 59 omitted +module_eval(<<'.,.,', 'parser.y', 154) + def _reduce_71(val, _values, result) + array = @handler.end_(:array); @handler.push(array.compact) + result + end +.,., -# reduce 60 omitted +module_eval(<<'.,.,', 'parser.y', 155) + def _reduce_72(val, _values, result) + array = @handler.end_(:array); @handler.push(array.compact) + result + end +.,., -module_eval(<<'.,.,', 'parser.y', 140) - def _reduce_61(val, _values, result) - @handler.start_(:array) +# reduce 73 omitted + +# reduce 74 omitted + +module_eval(<<'.,.,', 'parser.y', 162) + def _reduce_75(val, _values, result) + @handler.push(val[0]) result end .,., -module_eval(<<'.,.,', 'parser.y', 143) - def _reduce_62(val, _values, result) +# reduce 76 omitted + +# reduce 77 omitted + +module_eval(<<'.,.,', 'parser.y', 167) + def _reduce_78(val, _values, result) @handler.push(val[0]) result end .,., -# reduce 63 omitted +# reduce 79 omitted -# reduce 64 omitted +# reduce 80 omitted -# reduce 65 omitted +# reduce 81 omitted -# reduce 66 omitted +# reduce 82 omitted -# reduce 67 omitted +# reduce 83 omitted -module_eval(<<'.,.,', 'parser.y', 152) - def _reduce_68(val, _values, result) +# reduce 84 omitted + +# reduce 85 omitted + +# reduce 86 omitted + +module_eval(<<'.,.,', 'parser.y', 183) + def _reduce_87(val, _values, result) result = val[0].to_f result end .,., -module_eval(<<'.,.,', 'parser.y', 154) - def _reduce_69(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 185) + def _reduce_88(val, _values, result) v = val[0] result = if v.end_with?('nan') Float::NAN @@ -620,15 +726,15 @@ def _reduce_69(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 161) - def _reduce_70(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 192) + def _reduce_89(val, _values, result) result = val[0].to_i result end .,., -module_eval(<<'.,.,', 'parser.y', 163) - def _reduce_71(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 194) + def _reduce_90(val, _values, result) base = case val[0][1] when 'x' then 16 when 'o' then 8 @@ -640,15 +746,15 @@ def _reduce_71(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 170) - def _reduce_72(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 201) + def _reduce_91(val, _values, result) result = val[0] == 'true' ? true : false result end .,., -module_eval(<<'.,.,', 'parser.y', 172) - def _reduce_73(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 203) + def _reduce_92(val, _values, result) v = val[0] result = if v[6].nil? if v[4].nil? @@ -662,43 +768,46 @@ def _reduce_73(val, _values, result) v[3] = (v[3].to_i + 1).to_s end - Time.new(v[0], v[1], v[2], v[3] || 0, v[4] || 0, v[5].to_f, v[6]) + time = Time.new(v[0], v[1], v[2], v[3] || 0, v[4] || 0, v[5].to_f, v[6]) + # Should be out of parser.y? + raise ArgumentError, "Invalid Offset Date-Time: #{v[0]}-#{v[1]}-#{v[2]}T#{v[3]}:#{v[4]}:#{v[5]}#{v[6]}" unless v[4].to_i == time.min && v[3].to_i == time.hour && v[2].to_i == time.day && v[1].to_i == time.month && v[0].to_i == time.year + time end result end .,., -module_eval(<<'.,.,', 'parser.y', 188) - def _reduce_74(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 222) + def _reduce_93(val, _values, result) result = LocalTime.new(*val[0]) result end .,., -module_eval(<<'.,.,', 'parser.y', 191) - def _reduce_75(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 225) + def _reduce_94(val, _values, result) result = StringUtils.replace_escaped_chars(StringUtils.multiline_replacements(val[0])) result end .,., -module_eval(<<'.,.,', 'parser.y', 192) - def _reduce_76(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 226) + def _reduce_95(val, _values, result) result = StringUtils.replace_escaped_chars(val[0]) result end .,., -module_eval(<<'.,.,', 'parser.y', 193) - def _reduce_77(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 227) + def _reduce_96(val, _values, result) result = StringUtils.strip_spaces(val[0]) result end .,., -module_eval(<<'.,.,', 'parser.y', 194) - def _reduce_78(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 228) + def _reduce_97(val, _values, result) result = val[0] result end diff --git a/lib/tomlrb/parser.y b/lib/tomlrb/parser.y index 6029bde..8757339 100644 --- a/lib/tomlrb/parser.y +++ b/lib/tomlrb/parser.y @@ -1,5 +1,5 @@ class Tomlrb::GeneratedParser -token IDENTIFIER STRING_MULTI STRING_BASIC STRING_LITERAL_MULTI STRING_LITERAL DATETIME LOCAL_TIME INTEGER NON_DEC_INTEGER FLOAT FLOAT_KEYWORD BOOLEAN NEWLINE EOS +token IDENTIFIER STRING_MULTI STRING_BASIC STRING_LITERAL_MULTI STRING_LITERAL DATETIME LOCAL_TIME INTEGER NON_DEC_INTEGER FLOAT FLOAT_KEYWORD BOOLEAN NEWLINE COMMA EOS rule expressions | expressions expression @@ -66,7 +66,7 @@ rule | inline_assignment inline_next ; inline_next - : ',' inline_continued + : COMMA inline_continued ; inline_assignment : inline_assignment_key '=' value { @@ -125,32 +125,63 @@ rule | BOOLEAN ; array - : start_array array_continued + : start_array array_first_value array_values end_array + | start_array array_first_value end_array + | start_array end_array ; - array_continued - : ']' { array = @handler.end_(:array); @handler.push(array.compact) } - | value array_next - | NEWLINE array_continued + array_first_value + : + | newlines non_nil_value + | non_nil_value ; - array_next - : ']' { array = @handler.end_(:array); @handler.push(array.compact) } - | ',' array_continued - | NEWLINE array_continued + array_values + : array_values array_value + | array_value + ; + array_value + : comma newlines non_nil_value + | comma non_nil_value ; start_array : '[' { @handler.start_(:array) } ; + end_array + : comma newlines ']' { array = @handler.end_(:array); @handler.push(array.compact) } + | comma ']' { array = @handler.end_(:array); @handler.push(array.compact) } + | newlines ']' { array = @handler.end_(:array); @handler.push(array.compact) } + | ']' { array = @handler.end_(:array); @handler.push(array.compact) } + ; + comma + : newlines COMMA + | COMMA + ; + newlines + : newlines NEWLINE + | NEWLINE + ; value : scalar { @handler.push(val[0]) } | array | inline_table ; + non_nil_value + : non_nil_scalar { @handler.push(val[0]) } + | array + | inline_table + ; scalar : string | literal ; + non_nil_scalar + : string + | non_nil_literal + ; literal - | FLOAT { result = val[0].to_f } + | non_nil_literal + ; + non_nil_literal + : FLOAT { result = val[0].to_f } | FLOAT_KEYWORD { v = val[0] result = if v.end_with?('nan') diff --git a/lib/tomlrb/scanner.rb b/lib/tomlrb/scanner.rb index 4171f68..ade3d99 100644 --- a/lib/tomlrb/scanner.rb +++ b/lib/tomlrb/scanner.rb @@ -12,6 +12,7 @@ class Scanner /[ \t]/.freeze NEWLINE = /(?:[ \t]*(?:\r?\n)[ \t]*)+/.freeze + COMMA = /,/.freeze STRING_BASIC = /(")(?:\\?[^\u0000-\u0008\u000A-\u001F\u007F])*?\1/.freeze STRING_MULTI = @@ -49,6 +50,7 @@ def initialize(io) def next_token case when @ss.scan(NEWLINE) then [:NEWLINE, nil] + when @ss.scan(COMMA) then [:COMMA, nil] when @ss.scan(SPACED_ARRAY_OF_TABLES_START) then raise ParseError.new('Array of tables has spaces in starting brackets') when @ss.scan(SPACED_ARRAY_OF_TABLES_END) then raise ParseError.new('Array of tables has spaces in ending brackets') when @ss.scan(SPACED_ARRAY_OF_TABLES_BOTH) then raise ParseError.new('Array of tables has spaces in starting and ending brackets') From 8c3592d0208ca6ce6f24c1b064adb032eb0b43c0 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 1 Nov 2025 23:11:13 +0900 Subject: [PATCH 09/29] Restrict date time format on scanning --- lib/tomlrb/scanner.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tomlrb/scanner.rb b/lib/tomlrb/scanner.rb index ade3d99..85432ab 100644 --- a/lib/tomlrb/scanner.rb +++ b/lib/tomlrb/scanner.rb @@ -22,9 +22,9 @@ class Scanner STRING_LITERAL_MULTI = /'{3}([^\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]*?'{3,5})/m.freeze DATETIME = - /(-?\d{4})-(\d{2})-(\d{2})(?:(?:t|\s)(\d{2}):(\d{2}):(\d{2}(?:\.\d+)?))?(z|[-+]\d{2}:\d{2})?/i.freeze + /(-?\d{4})-([01]\d)-([0-3]\d)(?:(?:t|\s)([0-2]\d):([0-5]\d):([0-6]\d(?:\.\d+)?))?(z|[-+][01]\d:\d{2})?/i.freeze LOCAL_TIME = - /(\d{2}):(\d{2}):(\d{2}(?:\.\d+)?)/.freeze + /([0-2]\d):([0-5]\d):([0-6]\d(?:\.\d+)?)/.freeze FLOAT = /[+-]?(?:(?:\d|[1-9](?:_?\d)*)\.\d(?:_?\d)*|\d+(?=[eE]))(?:[eE][+-]?[0-9]+(_[0-9])*[0-9]*)?(?!\w)/.freeze FLOAT_KEYWORD = From 15e931d3a20506e7b5b269267590641b3e38892b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 1 Nov 2025 23:27:03 +0900 Subject: [PATCH 10/29] Prevent comma-only array --- lib/tomlrb/parser.y | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/tomlrb/parser.y b/lib/tomlrb/parser.y index 8757339..b706e62 100644 --- a/lib/tomlrb/parser.y +++ b/lib/tomlrb/parser.y @@ -125,13 +125,14 @@ rule | BOOLEAN ; array - : start_array array_first_value array_values end_array + : start_array array_first_value array_values comma end_array + | start_array array_first_value array_values end_array + | start_array array_first_value comma end_array | start_array array_first_value end_array | start_array end_array ; array_first_value - : - | newlines non_nil_value + : newlines non_nil_value | non_nil_value ; array_values @@ -146,9 +147,7 @@ rule : '[' { @handler.start_(:array) } ; end_array - : comma newlines ']' { array = @handler.end_(:array); @handler.push(array.compact) } - | comma ']' { array = @handler.end_(:array); @handler.push(array.compact) } - | newlines ']' { array = @handler.end_(:array); @handler.push(array.compact) } + : newlines ']' { array = @handler.end_(:array); @handler.push(array.compact) } | ']' { array = @handler.end_(:array); @handler.push(array.compact) } ; comma From b566f78f6af00719ec18d8b84f9226aeb94a943e Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sat, 1 Nov 2025 23:30:13 +0900 Subject: [PATCH 11/29] [skip ci]Update generated parser --- lib/tomlrb/generated_parser.rb | 344 +++++++++++++++------------------ 1 file changed, 154 insertions(+), 190 deletions(-) diff --git a/lib/tomlrb/generated_parser.rb b/lib/tomlrb/generated_parser.rb index 4352755..8e68aaa 100644 --- a/lib/tomlrb/generated_parser.rb +++ b/lib/tomlrb/generated_parser.rb @@ -10,118 +10,110 @@ class GeneratedParser < Racc::Parser ##### State transition tables begin ### racc_action_table = [ - 2, 95, 16, 95, 17, 111, 18, 118, 23, 19, - 20, 14, 21, 22, 8, 36, 4, 10, 109, 16, - 12, 17, 119, 18, 50, 51, 19, 20, 42, 21, - 22, 95, 105, 95, 105, 94, 48, 94, 39, 73, + 2, 46, 16, 47, 17, 45, 18, 23, 44, 19, + 20, 14, 21, 22, 8, 56, 4, 10, 55, 16, + 12, 17, 88, 18, 87, 36, 19, 20, 42, 21, + 22, 94, 105, 94, 105, 93, 48, 93, 39, 73, 74, 75, 76, 71, 72, 68, 69, 66, 67, 70, - 109, 114, 45, 59, 108, 44, 12, 73, 74, 75, - 76, 71, 72, 68, 69, 66, 67, 70, 109, 39, - 56, 59, 123, 55, 12, 73, 74, 75, 76, 71, - 72, 68, 69, 66, 67, 70, 95, 93, 54, 59, - 94, 79, 12, 73, 74, 75, 76, 71, 72, 68, - 69, 66, 67, 70, 109, 107, nil, 59, 108, nil, + 108, 115, 39, 59, 107, 54, 12, 73, 74, 75, + 76, 71, 72, 68, 69, 66, 67, 70, 50, 51, + 79, 59, nil, nil, 12, 73, 74, 75, 76, 71, + 72, 68, 69, 66, 67, 70, 94, nil, nil, 59, + 93, nil, 12, 73, 74, 75, 76, 71, 72, 68, + 69, 66, 67, 70, 108, nil, nil, 59, 107, nil, 12, 73, 74, 75, 76, 71, 72, 68, 69, 66, - 67, 70, 95, nil, nil, 59, 111, nil, 12, 73, + 67, 70, 94, nil, nil, 59, 93, nil, 12, 73, 74, 75, 76, 71, 72, 68, 69, 66, 67, 70, - 95, nil, nil, 59, 118, nil, 12, 73, 74, 75, - 76, 71, 72, 68, 69, 66, 67, 70, 109, nil, - nil, 59, 119, nil, 12, 73, 74, 75, 76, 71, - 72, 68, 69, 66, 67, 70, 109, nil, nil, 59, - 123, 29, 12, 30, 46, 31, 47, nil, 32, 33, - 27, 34, 35, 88, 29, 87, 30, 25, 31, nil, - nil, 32, 33, 82, 34, 35, nil, 16, nil, 17, - 25, 18, nil, nil, 19, 20, 78, 21, 22, 16, - nil, 17, nil, 18, nil, nil, 19, 20, 42, 21, + 94, nil, nil, 59, 93, nil, 12, 73, 74, 75, + 76, 71, 72, 68, 69, 66, 67, 70, 108, nil, + nil, 59, 107, 29, 12, 30, nil, 31, nil, nil, + 32, 33, 27, 34, 35, nil, 29, nil, 30, 25, + 31, nil, nil, 32, 33, 82, 34, 35, nil, 16, + nil, 17, 25, 18, nil, nil, 19, 20, 78, 21, 22, 16, nil, 17, nil, 18, nil, nil, 19, 20, - 86, 21, 22 ] + 42, 21, 22, 16, nil, 17, nil, 18, nil, nil, + 19, 20, 86, 21, 22 ] racc_action_check = [ - 1, 93, 1, 107, 1, 93, 1, 107, 2, 1, - 1, 1, 1, 1, 1, 10, 1, 1, 110, 11, - 1, 11, 110, 11, 26, 26, 11, 11, 11, 11, - 11, 89, 89, 101, 101, 89, 25, 101, 11, 44, + 1, 24, 1, 24, 1, 13, 1, 2, 13, 1, + 1, 1, 1, 1, 1, 41, 1, 1, 41, 11, + 1, 11, 57, 11, 57, 10, 11, 11, 11, 11, + 11, 89, 89, 100, 100, 89, 25, 100, 11, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 104, 104, 13, 44, 104, 13, 44, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 117, 38, - 41, 55, 117, 41, 55, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 40, 58, - 58, 50, 58, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, nil, 91, 91, nil, - 91, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, nil, nil, 105, 105, nil, 105, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, nil, nil, 114, 114, nil, 114, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, nil, - nil, 115, 115, nil, 115, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, nil, nil, 120, - 120, 9, 120, 9, 24, 9, 24, nil, 9, 9, - 9, 9, 9, 57, 51, 57, 51, 9, 51, nil, - nil, 51, 51, 51, 51, 51, nil, 45, nil, 45, - 51, 45, nil, nil, 45, 45, 45, 45, 45, 54, - nil, 54, nil, 54, nil, nil, 54, 54, 54, 54, - 54, 56, nil, 56, nil, 56, nil, nil, 56, 56, - 56, 56, 56 ] + 104, 104, 38, 44, 104, 40, 44, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 26, 26, + 50, 55, nil, nil, 55, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, nil, nil, 58, + 58, nil, 58, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, nil, nil, 91, 91, nil, + 91, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, nil, nil, 101, 101, nil, 101, 109, + 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, + 109, nil, nil, 109, 109, nil, 109, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, nil, + nil, 113, 113, 9, 113, 9, nil, 9, nil, nil, + 9, 9, 9, 9, 9, nil, 51, nil, 51, 9, + 51, nil, nil, 51, 51, 51, 51, 51, nil, 45, + nil, 45, 51, 45, nil, nil, 45, 45, 45, 45, + 45, 54, nil, 54, nil, 54, nil, nil, 54, 54, + 54, 54, 54, 56, nil, 56, nil, 56, nil, nil, + 56, 56, 56, 56, 56 ] racc_action_pointer = [ - nil, 0, 8, nil, nil, nil, nil, nil, nil, 179, - -2, 17, nil, 33, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 170, 18, 6, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 48, nil, - 73, 51, nil, nil, 36, 205, nil, nil, nil, nil, - 73, 192, nil, nil, 217, 54, 229, 179, 72, nil, + nil, 0, 7, nil, nil, nil, nil, nil, nil, 161, + 8, 17, nil, -14, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -13, 18, 50, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 31, nil, + 40, -4, nil, nil, 36, 187, nil, nil, nil, nil, + 52, 174, nil, nil, 199, 54, 211, 8, 72, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 17, - nil, 90, nil, -13, nil, nil, nil, nil, nil, nil, - nil, 19, nil, nil, 36, 108, nil, -11, nil, nil, - 4, nil, nil, nil, 126, 144, nil, 54, nil, nil, - 162, nil, nil, nil, nil ] + nil, 90, nil, nil, nil, nil, nil, nil, nil, nil, + 19, 108, nil, nil, 36, nil, nil, nil, nil, 126, + nil, nil, nil, 144, nil, nil, nil, nil ] racc_action_default = [ - -1, -98, -98, -2, -3, -4, -5, -6, -7, -98, - -11, -98, -31, -98, -45, -46, -47, -48, -49, -50, - -51, -52, -53, 125, -98, -13, -98, -20, -21, -22, - -23, -24, -25, -26, -27, -28, -10, -29, -98, -32, - -33, -98, -39, -40, -85, -98, -8, -9, -12, -14, - -16, -98, -30, -34, -98, -85, -98, -98, -98, -66, - -75, -76, -77, -81, -82, -86, -87, -88, -89, -90, - -91, -92, -93, -94, -95, -96, -97, -43, -44, -15, - -17, -18, -19, -35, -36, -37, -38, -41, -42, -98, - -56, -98, -59, -98, -72, -74, -78, -79, -80, -83, - -84, -98, -55, -61, -98, -98, -58, -98, -71, -73, - -98, -70, -54, -60, -98, -98, -65, -98, -68, -69, - -98, -63, -64, -67, -62 ] + -1, -95, -95, -2, -3, -4, -5, -6, -7, -95, + -11, -95, -31, -95, -45, -46, -47, -48, -49, -50, + -51, -52, -53, 118, -95, -13, -95, -20, -21, -22, + -23, -24, -25, -26, -27, -28, -10, -29, -95, -32, + -33, -95, -39, -40, -82, -95, -8, -9, -12, -14, + -16, -95, -30, -34, -95, -82, -95, -95, -95, -65, + -72, -73, -74, -78, -79, -83, -84, -85, -86, -87, + -88, -89, -90, -91, -92, -93, -94, -43, -44, -15, + -17, -18, -19, -35, -36, -37, -38, -41, -42, -95, + -58, -95, -60, -67, -71, -75, -76, -77, -80, -81, + -95, -95, -57, -62, -95, -69, -59, -66, -70, -95, + -55, -61, -56, -95, -64, -68, -54, -63 ] racc_goto_table = [ - 92, 7, 91, 38, 15, 37, 103, 90, 57, 61, - 24, 28, 63, 65, 1, 3, 5, 6, 113, 84, - 61, 9, 49, 63, 65, 53, 13, 89, 101, nil, - nil, nil, 52, 106, nil, nil, nil, 110, 102, nil, - nil, nil, nil, nil, 62, nil, 83, 116, 77, 115, - 112, 117, 80, 81, nil, 62, 121, 122, 120, 85, - nil, nil, 124 ] + 15, 92, 91, 7, 38, 37, 24, 90, 57, 28, + 61, 101, 103, 63, 65, 1, 3, 5, 6, 84, + 9, 61, 109, 111, 63, 65, 49, 53, 13, 89, + 100, nil, 52, nil, 106, nil, nil, nil, 102, nil, + nil, nil, nil, nil, 77, 113, 62, 83, 80, 110, + 112, 81, nil, 113, nil, 85, 117, 62, 116 ] racc_goto_check = [ - 26, 5, 25, 13, 18, 12, 27, 24, 17, 20, - 7, 10, 30, 32, 1, 2, 3, 4, 27, 17, - 20, 6, 9, 30, 32, 15, 19, 22, 23, nil, - nil, nil, 12, 26, nil, nil, nil, 25, 24, nil, - nil, nil, nil, nil, 5, nil, 13, 26, 18, 25, - 24, 25, 7, 10, nil, 5, 26, 26, 25, 18, - nil, nil, 26 ] + 18, 27, 26, 5, 13, 12, 7, 25, 17, 10, + 20, 24, 28, 31, 33, 1, 2, 3, 4, 17, + 6, 20, 24, 28, 31, 33, 9, 15, 19, 22, + 23, nil, 12, nil, 27, nil, nil, nil, 25, nil, + nil, nil, nil, nil, 18, 26, 5, 13, 7, 25, + 25, 10, nil, 26, nil, 18, 27, 5, 25 ] racc_goto_pointer = [ - nil, 14, 14, 15, 16, 0, 20, 1, nil, -4, - 2, nil, -6, -8, nil, -15, nil, -36, 3, 25, - -35, nil, -31, -61, -51, -56, -58, -83, nil, nil, - -32, nil, -31 ] + nil, 15, 15, 16, 17, 2, 19, -3, nil, 0, + 0, nil, -6, -7, nil, -13, nil, -36, -1, 27, + -34, nil, -29, -59, -78, -51, -56, -57, -77, nil, + nil, -31, nil, -30 ] racc_goto_default = [ - nil, nil, nil, nil, nil, 98, nil, nil, 26, nil, + nil, nil, nil, nil, nil, 97, nil, nil, 26, nil, nil, 11, nil, nil, 40, nil, 41, nil, 43, nil, - 97, 58, nil, nil, nil, 104, nil, nil, 60, 96, - 99, 64, 100 ] + 96, 58, nil, nil, nil, nil, 104, 114, nil, 60, + 95, 98, 64, 99 ] racc_reduce_table = [ 0, 0, :racc_error, @@ -178,54 +170,51 @@ class GeneratedParser < Racc::Parser 1, 41, :_reduce_none, 1, 41, :_reduce_none, 1, 41, :_reduce_none, + 5, 43, :_reduce_none, + 4, 43, :_reduce_none, 4, 43, :_reduce_none, 3, 43, :_reduce_none, 2, 43, :_reduce_none, - 0, 45, :_reduce_none, 2, 45, :_reduce_none, 1, 45, :_reduce_none, 2, 46, :_reduce_none, 1, 46, :_reduce_none, - 4, 50, :_reduce_none, - 3, 50, :_reduce_none, - 3, 50, :_reduce_none, - 2, 50, :_reduce_none, - 1, 44, :_reduce_66, - 4, 47, :_reduce_67, - 3, 47, :_reduce_68, - 3, 47, :_reduce_69, - 2, 47, :_reduce_70, - 2, 47, :_reduce_71, - 1, 47, :_reduce_72, - 2, 48, :_reduce_none, - 1, 48, :_reduce_none, - 1, 40, :_reduce_75, + 3, 51, :_reduce_none, + 2, 51, :_reduce_none, + 1, 44, :_reduce_65, + 2, 48, :_reduce_66, + 1, 48, :_reduce_67, + 2, 47, :_reduce_none, + 1, 47, :_reduce_none, + 2, 49, :_reduce_none, + 1, 49, :_reduce_none, + 1, 40, :_reduce_72, 1, 40, :_reduce_none, 1, 40, :_reduce_none, - 1, 49, :_reduce_78, - 1, 49, :_reduce_none, - 1, 49, :_reduce_none, - 1, 51, :_reduce_none, - 1, 51, :_reduce_none, + 1, 50, :_reduce_75, + 1, 50, :_reduce_none, + 1, 50, :_reduce_none, 1, 52, :_reduce_none, 1, 52, :_reduce_none, - 0, 54, :_reduce_none, - 1, 54, :_reduce_none, - 1, 55, :_reduce_87, - 1, 55, :_reduce_88, - 1, 55, :_reduce_89, - 1, 55, :_reduce_90, - 1, 55, :_reduce_91, - 1, 55, :_reduce_92, - 1, 55, :_reduce_93, - 1, 53, :_reduce_94, - 1, 53, :_reduce_95, - 1, 53, :_reduce_96, - 1, 53, :_reduce_97 ] - -racc_reduce_n = 98 - -racc_shift_n = 125 + 1, 53, :_reduce_none, + 1, 53, :_reduce_none, + 0, 55, :_reduce_none, + 1, 55, :_reduce_none, + 1, 56, :_reduce_84, + 1, 56, :_reduce_85, + 1, 56, :_reduce_86, + 1, 56, :_reduce_87, + 1, 56, :_reduce_88, + 1, 56, :_reduce_89, + 1, 56, :_reduce_90, + 1, 54, :_reduce_91, + 1, 54, :_reduce_92, + 1, 54, :_reduce_93, + 1, 54, :_reduce_94 ] + +racc_reduce_n = 95 + +racc_shift_n = 118 racc_token_table = { false => 0, @@ -321,6 +310,7 @@ class GeneratedParser < Racc::Parser "start_array", "array_first_value", "array_values", + "comma", "end_array", "newlines", "non_nil_value", @@ -332,7 +322,7 @@ class GeneratedParser < Racc::Parser "non_nil_literal" ] Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) -Racc_debug_parser = true +Racc_debug_parser = false ##### State transition tables end ##### @@ -617,53 +607,38 @@ def _reduce_48(val, _values, result) # reduce 64 omitted -# reduce 65 omitted - -module_eval(<<'.,.,', 'parser.y', 147) - def _reduce_66(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 146) + def _reduce_65(val, _values, result) @handler.start_(:array) result end .,., -module_eval(<<'.,.,', 'parser.y', 150) - def _reduce_67(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 149) + def _reduce_66(val, _values, result) array = @handler.end_(:array); @handler.push(array.compact) result end .,., -module_eval(<<'.,.,', 'parser.y', 151) - def _reduce_68(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 150) + def _reduce_67(val, _values, result) array = @handler.end_(:array); @handler.push(array.compact) result end .,., -module_eval(<<'.,.,', 'parser.y', 152) - def _reduce_69(val, _values, result) - array = @handler.end_(:array); @handler.push(array.compact) - result - end -.,., +# reduce 68 omitted -module_eval(<<'.,.,', 'parser.y', 153) - def _reduce_70(val, _values, result) - array = @handler.end_(:array); @handler.push(array.compact) - result - end -.,., +# reduce 69 omitted -module_eval(<<'.,.,', 'parser.y', 154) - def _reduce_71(val, _values, result) - array = @handler.end_(:array); @handler.push(array.compact) - result - end -.,., +# reduce 70 omitted -module_eval(<<'.,.,', 'parser.y', 155) +# reduce 71 omitted + +module_eval(<<'.,.,', 'parser.y', 161) def _reduce_72(val, _values, result) - array = @handler.end_(:array); @handler.push(array.compact) + @handler.push(val[0]) result end .,., @@ -672,7 +647,7 @@ def _reduce_72(val, _values, result) # reduce 74 omitted -module_eval(<<'.,.,', 'parser.y', 162) +module_eval(<<'.,.,', 'parser.y', 166) def _reduce_75(val, _values, result) @handler.push(val[0]) result @@ -683,12 +658,7 @@ def _reduce_75(val, _values, result) # reduce 77 omitted -module_eval(<<'.,.,', 'parser.y', 167) - def _reduce_78(val, _values, result) - @handler.push(val[0]) - result - end -.,., +# reduce 78 omitted # reduce 79 omitted @@ -700,21 +670,15 @@ def _reduce_78(val, _values, result) # reduce 83 omitted -# reduce 84 omitted - -# reduce 85 omitted - -# reduce 86 omitted - -module_eval(<<'.,.,', 'parser.y', 183) - def _reduce_87(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 182) + def _reduce_84(val, _values, result) result = val[0].to_f result end .,., -module_eval(<<'.,.,', 'parser.y', 185) - def _reduce_88(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 184) + def _reduce_85(val, _values, result) v = val[0] result = if v.end_with?('nan') Float::NAN @@ -726,15 +690,15 @@ def _reduce_88(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 192) - def _reduce_89(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 191) + def _reduce_86(val, _values, result) result = val[0].to_i result end .,., -module_eval(<<'.,.,', 'parser.y', 194) - def _reduce_90(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 193) + def _reduce_87(val, _values, result) base = case val[0][1] when 'x' then 16 when 'o' then 8 @@ -746,15 +710,15 @@ def _reduce_90(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 201) - def _reduce_91(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 200) + def _reduce_88(val, _values, result) result = val[0] == 'true' ? true : false result end .,., -module_eval(<<'.,.,', 'parser.y', 203) - def _reduce_92(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 202) + def _reduce_89(val, _values, result) v = val[0] result = if v[6].nil? if v[4].nil? @@ -778,36 +742,36 @@ def _reduce_92(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 222) - def _reduce_93(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 221) + def _reduce_90(val, _values, result) result = LocalTime.new(*val[0]) result end .,., -module_eval(<<'.,.,', 'parser.y', 225) - def _reduce_94(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 224) + def _reduce_91(val, _values, result) result = StringUtils.replace_escaped_chars(StringUtils.multiline_replacements(val[0])) result end .,., -module_eval(<<'.,.,', 'parser.y', 226) - def _reduce_95(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 225) + def _reduce_92(val, _values, result) result = StringUtils.replace_escaped_chars(val[0]) result end .,., -module_eval(<<'.,.,', 'parser.y', 227) - def _reduce_96(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 226) + def _reduce_93(val, _values, result) result = StringUtils.strip_spaces(val[0]) result end .,., -module_eval(<<'.,.,', 'parser.y', 228) - def _reduce_97(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 227) + def _reduce_94(val, _values, result) result = val[0] result end From b595e865a039d4b7f45cb0fa4ab3b9d46aed1d6b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 2 Nov 2025 01:03:06 +0900 Subject: [PATCH 12/29] Prevent redefinition of dotted table --- lib/tomlrb/handler.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/tomlrb/handler.rb b/lib/tomlrb/handler.rb index d8b6fd9..857b939 100644 --- a/lib/tomlrb/handler.rb +++ b/lib/tomlrb/handler.rb @@ -119,6 +119,8 @@ def validate_value(value) private def assign_key_path(current, key, key_emptied) + existed = current.key?(key) + raise ParseError, "Cannot overwrite value with key #{key}" if existed && !current[key].is_a?(Hash) if key_emptied raise ParseError, "Cannot overwrite value with key #{key}" unless current.is_a?(Hash) From 6132cb1d3a0f1bae2f79318f8239069830111a21 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Sun, 2 Nov 2025 04:58:29 +0900 Subject: [PATCH 13/29] Prevent unclosed string basic --- lib/tomlrb/scanner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tomlrb/scanner.rb b/lib/tomlrb/scanner.rb index 85432ab..f3a8ac1 100644 --- a/lib/tomlrb/scanner.rb +++ b/lib/tomlrb/scanner.rb @@ -14,7 +14,7 @@ class Scanner /(?:[ \t]*(?:\r?\n)[ \t]*)+/.freeze COMMA = /,/.freeze STRING_BASIC = - /(")(?:\\?[^\u0000-\u0008\u000A-\u001F\u007F])*?\1/.freeze + /(")(?:\\?[^\u0000-\u0008\u000A-\u001F\u007F\\]|(?:\\[^\u0000-\u0008\u000A-\u001F\u007F]))*?\1/.freeze STRING_MULTI = /"{3}([^\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]*?(? Date: Mon, 3 Nov 2025 05:54:04 +0900 Subject: [PATCH 14/29] Check of dup keys for inline tables --- lib/tomlrb/handler.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/tomlrb/handler.rb b/lib/tomlrb/handler.rb index 857b939..bd98dc3 100644 --- a/lib/tomlrb/handler.rb +++ b/lib/tomlrb/handler.rb @@ -72,16 +72,21 @@ def push(o) def push_inline(inline_arrays) merged_inline = {} + keys = Keys.new inline_arrays.each do |inline_array| current = merged_inline value = inline_array.pop + keys.add_table_key inline_array, value.is_a?(Array) + inline_array.each_with_index do |inline_key, inline_index| inline_key = inline_key.to_sym if @symbolize_keys last_key = inline_index == inline_array.size - 1 if last_key if current[inline_key].nil? + keys.add_pair_key [inline_key], [] + current[inline_key] = value else raise Key::KeyConflict, "Inline key #{inline_key} is already used" From a4461e0d686b71dc76b3d5d178de80176aa0124b Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 3 Nov 2025 06:00:23 +0900 Subject: [PATCH 15/29] Use patched toml-test --- toml-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml-test b/toml-test index 369cc3a..ddd1933 160000 --- a/toml-test +++ b/toml-test @@ -1 +1 @@ -Subproject commit 369cc3ae275fd76b6e21780ebf87609e5b2a951a +Subproject commit ddd19332f411a03b58ef022b1807ef33df68ae70 From caaece29fa642f060a230f47ecf90591e15b0483 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 3 Nov 2025 11:20:08 +0900 Subject: [PATCH 16/29] Assign array to variables for readability --- lib/tomlrb/parser.y | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/tomlrb/parser.y b/lib/tomlrb/parser.y index b706e62..67da95d 100644 --- a/lib/tomlrb/parser.y +++ b/lib/tomlrb/parser.y @@ -200,22 +200,22 @@ rule } | BOOLEAN { result = val[0] == 'true' ? true : false } | DATETIME { - v = val[0] - result = if v[6].nil? - if v[4].nil? - LocalDate.new(v[0], v[1], v[2]) + year, month, day, hour, min, sec, offset = val[0] + result = if offset.nil? + if hour.nil? + LocalDate.new(year, month, day) else - LocalDateTime.new(v[0], v[1], v[2], v[3] || 0, v[4] || 0, v[5].to_f) + LocalDateTime.new(year, month, day, hour, min || 0, sec.to_f) end else # Patch for 24:00:00 which Ruby parses - if v[3].to_i == 24 && v[4].to_i == 0 && v[5].to_i == 0 - v[3] = (v[3].to_i + 1).to_s + if hour.to_i == 24 && month.to_i == 0 && day.to_i == 0 + hour = (hour.to_i + 1).to_s end - time = Time.new(v[0], v[1], v[2], v[3] || 0, v[4] || 0, v[5].to_f, v[6]) + time = Time.new(year, month, day, hour || 0, min || 0, sec.to_f, offset) # Should be out of parser.y? - raise ArgumentError, "Invalid Offset Date-Time: #{v[0]}-#{v[1]}-#{v[2]}T#{v[3]}:#{v[4]}:#{v[5]}#{v[6]}" unless v[4].to_i == time.min && v[3].to_i == time.hour && v[2].to_i == time.day && v[1].to_i == time.month && v[0].to_i == time.year + raise ArgumentError, "Invalid Offset Date-Time: #{year}-#{month}-#{day}T#{hour}:#{min}:#{sec}#{offset}" unless min.to_i == time.min && hour.to_i == time.hour && day.to_i == time.day && month.to_i == time.month && year.to_i == time.year time end } From b168a3bd10f6e561c70fb9667f449d4e05c635cb Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 3 Nov 2025 11:24:52 +0900 Subject: [PATCH 17/29] Pass matched string of date times to parser --- lib/tomlrb/parser.y | 4 ++-- lib/tomlrb/scanner.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/tomlrb/parser.y b/lib/tomlrb/parser.y index 67da95d..dfc66df 100644 --- a/lib/tomlrb/parser.y +++ b/lib/tomlrb/parser.y @@ -200,7 +200,7 @@ rule } | BOOLEAN { result = val[0] == 'true' ? true : false } | DATETIME { - year, month, day, hour, min, sec, offset = val[0] + _str, year, month, day, hour, min, sec, offset = val[0] result = if offset.nil? if hour.nil? LocalDate.new(year, month, day) @@ -219,7 +219,7 @@ rule time end } - | LOCAL_TIME { result = LocalTime.new(*val[0]) } + | LOCAL_TIME { result = LocalTime.new(*val[0][1..]) } ; string : STRING_MULTI { result = StringUtils.replace_escaped_chars(StringUtils.multiline_replacements(val[0])) } diff --git a/lib/tomlrb/scanner.rb b/lib/tomlrb/scanner.rb index f3a8ac1..81c21a0 100644 --- a/lib/tomlrb/scanner.rb +++ b/lib/tomlrb/scanner.rb @@ -75,12 +75,12 @@ def next_token def process_datetime offset = @ss[7].gsub(/[zZ]/, '+00:00') if @ss[7] - args = [@ss[1], @ss[2], @ss[3], @ss[4], @ss[5], @ss[6], offset] + args = [@ss[0], @ss[1], @ss[2], @ss[3], @ss[4], @ss[5], @ss[6], offset] [:DATETIME, args] end def process_local_time - args = [@ss[1], @ss[2], @ss[3].to_f] + args = [@ss[0], @ss[1], @ss[2], @ss[3].to_f] [:LOCAL_TIME, args] end From 42a835d14c942a7afa2038b4d373efcb79b76099 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 3 Nov 2025 11:25:56 +0900 Subject: [PATCH 18/29] Allow date-like key for tables --- lib/tomlrb/parser.y | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/tomlrb/parser.y b/lib/tomlrb/parser.y index dfc66df..657c2f8 100644 --- a/lib/tomlrb/parser.y +++ b/lib/tomlrb/parser.y @@ -47,6 +47,8 @@ rule | NON_DEC_INTEGER | FLOAT_KEYWORD | BOOLEAN + | DATETIME { result = val[0][0] } + | LOCAL_TIME { result = val[0][0] } ; inline_table : inline_table_start inline_table_end @@ -123,6 +125,8 @@ rule | NON_DEC_INTEGER | FLOAT_KEYWORD | BOOLEAN + | DATETIME { result = val[0][0] } + | LOCAL_TIME { result = val[0][0] } ; array : start_array array_first_value array_values comma end_array From 43d8df8a01944aec6cd75a99759092ec2638c794 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Mon, 3 Nov 2025 11:37:37 +0900 Subject: [PATCH 19/29] Prevent dot at end of table keys --- lib/tomlrb/parser.y | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/tomlrb/parser.y b/lib/tomlrb/parser.y index 657c2f8..7c9051a 100644 --- a/lib/tomlrb/parser.y +++ b/lib/tomlrb/parser.y @@ -12,22 +12,19 @@ rule | NEWLINE ; table - : table_start table_continued NEWLINE - | table_start table_continued EOS + : table_start table_identifier table_end newlines + | table_start table_identifier table_end EOS + | table_start table_end newlines + | table_start table_end EOS ; table_start : '[' '[' { @handler.start_(:array_of_tables) } | '[' { @handler.start_(:table) } ; - table_continued - : ']' ']' { array = @handler.end_(:array_of_tables); @handler.set_context(array, is_array_of_tables: true) } - | ']' { array = @handler.end_(:table); @handler.set_context(array) } - | table_identifier table_next ; - table_next + table_end : ']' ']' { array = @handler.end_(:array_of_tables); @handler.set_context(array, is_array_of_tables: true) } | ']' { array = @handler.end_(:table); @handler.set_context(array) } - | '.' table_continued ; table_identifier : table_identifier '.' table_identifier_component { @handler.push(val[2]) } From 648be54a0bfbfb181599b5a323e358f3f1cf9ddf Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 4 Nov 2025 01:43:08 +0900 Subject: [PATCH 20/29] Prevent overwriting key --- lib/tomlrb/handler.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/tomlrb/handler.rb b/lib/tomlrb/handler.rb index bd98dc3..c6959ea 100644 --- a/lib/tomlrb/handler.rb +++ b/lib/tomlrb/handler.rb @@ -129,7 +129,9 @@ def assign_key_path(current, key, key_emptied) if key_emptied raise ParseError, "Cannot overwrite value with key #{key}" unless current.is_a?(Hash) - current[key] = @stack.pop + value = @stack.pop + raise ParseError, "Cannot overwrite value with key #{key}" if current[key].is_a?(Hash) && !value.is_a?(Hash) + current[key] = value return current end current[key] ||= {} From 501d48096a5540426187d78fb3f149999379da68 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 4 Nov 2025 01:43:39 +0900 Subject: [PATCH 21/29] Update generated parser --- lib/tomlrb/generated_parser.rb | 501 +++++++++++++++++---------------- 1 file changed, 262 insertions(+), 239 deletions(-) diff --git a/lib/tomlrb/generated_parser.rb b/lib/tomlrb/generated_parser.rb index 8e68aaa..11e5829 100644 --- a/lib/tomlrb/generated_parser.rb +++ b/lib/tomlrb/generated_parser.rb @@ -10,110 +10,118 @@ class GeneratedParser < Racc::Parser ##### State transition tables begin ### racc_action_table = [ - 2, 46, 16, 47, 17, 45, 18, 23, 44, 19, - 20, 14, 21, 22, 8, 56, 4, 10, 55, 16, - 12, 17, 88, 18, 87, 36, 19, 20, 42, 21, - 22, 94, 105, 94, 105, 93, 48, 93, 39, 73, - 74, 75, 76, 71, 72, 68, 69, 66, 67, 70, - 108, 115, 39, 59, 107, 54, 12, 73, 74, 75, - 76, 71, 72, 68, 69, 66, 67, 70, 50, 51, - 79, 59, nil, nil, 12, 73, 74, 75, 76, 71, - 72, 68, 69, 66, 67, 70, 94, nil, nil, 59, - 93, nil, 12, 73, 74, 75, 76, 71, 72, 68, - 69, 66, 67, 70, 108, nil, nil, 59, 107, nil, - 12, 73, 74, 75, 76, 71, 72, 68, 69, 66, - 67, 70, 94, nil, nil, 59, 93, nil, 12, 73, - 74, 75, 76, 71, 72, 68, 69, 66, 67, 70, - 94, nil, nil, 59, 93, nil, 12, 73, 74, 75, - 76, 71, 72, 68, 69, 66, 67, 70, 108, nil, - nil, 59, 107, 29, 12, 30, nil, 31, nil, nil, - 32, 33, 27, 34, 35, nil, 29, nil, 30, 25, - 31, nil, nil, 32, 33, 82, 34, 35, nil, 16, - nil, 17, 25, 18, nil, nil, 19, 20, 78, 21, - 22, 16, nil, 17, nil, 18, nil, nil, 19, 20, - 42, 21, 22, 16, nil, 17, nil, 18, nil, nil, - 19, 20, 86, 21, 22 ] + 2, 54, 16, 53, 17, 25, 18, 23, 24, 19, + 20, 14, 21, 22, 8, 49, 4, 10, 48, 16, + 12, 17, 40, 18, 23, 24, 19, 20, 46, 21, + 22, 54, 109, 54, 109, 98, 55, 98, 43, 77, + 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, + 87, 118, 60, 63, 111, 59, 12, 77, 78, 79, + 80, 75, 76, 72, 73, 70, 71, 74, 54, 43, + 84, 63, 28, 51, 12, 77, 78, 79, 80, 75, + 76, 72, 73, 70, 71, 74, 54, 58, 87, 63, + 98, 87, 12, 77, 78, 79, 80, 75, 76, 72, + 73, 70, 71, 74, 87, nil, nil, 63, 111, nil, + 12, 77, 78, 79, 80, 75, 76, 72, 73, 70, + 71, 74, 54, nil, nil, 63, 98, nil, 12, 77, + 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, + 54, nil, nil, 63, 98, nil, 12, 77, 78, 79, + 80, 75, 76, 72, 73, 70, 71, 74, 87, nil, + nil, 63, 111, 31, 12, 32, nil, 33, 38, 39, + 34, 35, 29, 36, 37, 93, 16, 92, 17, 28, + 18, 23, 24, 19, 20, 82, 21, 22, 31, nil, + 32, nil, 33, 38, 39, 34, 35, 86, 36, 37, + 16, nil, 17, nil, 18, 23, 24, 19, 20, 46, + 21, 22, 16, nil, 17, nil, 18, 23, 24, 19, + 20, 91, 21, 22 ] racc_action_check = [ - 1, 24, 1, 24, 1, 13, 1, 2, 13, 1, - 1, 1, 1, 1, 1, 41, 1, 1, 41, 11, - 1, 11, 57, 11, 57, 10, 11, 11, 11, 11, - 11, 89, 89, 100, 100, 89, 25, 100, 11, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 104, 104, 38, 44, 104, 40, 44, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 26, 26, - 50, 55, nil, nil, 55, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, nil, nil, 58, - 58, nil, 58, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, nil, nil, 91, 91, nil, - 91, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, nil, nil, 101, 101, nil, 101, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, nil, nil, 109, 109, nil, 109, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, nil, - nil, 113, 113, 9, 113, 9, nil, 9, nil, nil, - 9, 9, 9, 9, 9, nil, 51, nil, 51, 9, - 51, nil, nil, 51, 51, 51, 51, 51, nil, 45, - nil, 45, 51, 45, nil, nil, 45, 45, 45, 45, - 45, 54, nil, 54, nil, 54, nil, nil, 54, 54, - 54, 54, 54, 56, nil, 56, nil, 56, nil, nil, - 56, 56, 56, 56, 56 ] + 1, 27, 1, 27, 1, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 13, 1, 1, 13, 11, + 1, 11, 10, 11, 11, 11, 11, 11, 11, 11, + 11, 94, 94, 104, 104, 94, 28, 104, 11, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 108, 108, 45, 48, 108, 45, 48, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 50, 42, + 50, 59, 26, 26, 59, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 44, 52, 62, + 62, 83, 62, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, nil, nil, 96, 96, nil, + 96, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, nil, nil, 105, 105, nil, 105, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, nil, nil, 112, 112, nil, 112, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, nil, + nil, 116, 116, 9, 116, 9, nil, 9, 9, 9, + 9, 9, 9, 9, 9, 61, 49, 61, 49, 9, + 49, 49, 49, 49, 49, 49, 49, 49, 51, nil, + 51, nil, 51, 51, 51, 51, 51, 51, 51, 51, + 58, nil, 58, nil, 58, 58, 58, 58, 58, 58, + 58, 58, 60, nil, 60, nil, 60, 60, 60, 60, + 60, 60, 60, 60 ] racc_action_pointer = [ - nil, 0, 7, nil, nil, nil, nil, nil, nil, 161, - 8, 17, nil, -14, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, -13, 18, 50, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, 31, nil, - 40, -4, nil, nil, 36, 187, nil, nil, nil, nil, - 52, 174, nil, nil, 199, 54, 211, 8, 72, nil, + nil, 0, 5, nil, nil, nil, nil, nil, nil, 161, + 5, 17, nil, -4, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 54, -13, 18, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 48, nil, 72, 33, nil, nil, 36, 174, + 54, 186, 74, nil, nil, nil, nil, nil, 198, 54, + 210, 161, 72, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, nil, nil, nil, 17, - nil, 90, nil, nil, nil, nil, nil, nil, nil, nil, - 19, 108, nil, nil, 36, nil, nil, nil, nil, 126, - nil, nil, nil, 144, nil, nil, nil, nil ] + nil, nil, nil, 77, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 17, nil, 90, nil, nil, nil, + nil, nil, nil, nil, 19, 108, nil, nil, 36, nil, + nil, nil, 126, nil, nil, nil, 144, nil, nil, nil, + nil ] racc_action_default = [ - -1, -95, -95, -2, -3, -4, -5, -6, -7, -95, - -11, -95, -31, -95, -45, -46, -47, -48, -49, -50, - -51, -52, -53, 118, -95, -13, -95, -20, -21, -22, - -23, -24, -25, -26, -27, -28, -10, -29, -95, -32, - -33, -95, -39, -40, -82, -95, -8, -9, -12, -14, - -16, -95, -30, -34, -95, -82, -95, -95, -95, -65, - -72, -73, -74, -78, -79, -83, -84, -85, -86, -87, - -88, -89, -90, -91, -92, -93, -94, -43, -44, -15, - -17, -18, -19, -35, -36, -37, -38, -41, -42, -95, - -58, -95, -60, -67, -71, -75, -76, -77, -80, -81, - -95, -95, -57, -62, -95, -69, -59, -66, -70, -95, - -55, -61, -56, -95, -64, -68, -54, -63 ] + -1, -97, -97, -2, -3, -4, -5, -6, -7, -97, + -13, -97, -31, -97, -45, -46, -47, -48, -49, -50, + -51, -52, -53, -54, -55, 121, -97, -97, -15, -18, + -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, + -12, -29, -97, -32, -33, -97, -39, -40, -84, -97, + -97, -97, -10, -11, -73, -14, -30, -34, -97, -84, + -97, -97, -97, -67, -74, -75, -76, -80, -81, -85, + -86, -87, -88, -89, -90, -91, -92, -93, -94, -95, + -96, -43, -44, -8, -9, -16, -17, -72, -35, -36, + -37, -38, -41, -42, -97, -60, -97, -62, -69, -77, + -78, -79, -82, -83, -97, -97, -59, -64, -97, -71, + -61, -68, -97, -57, -63, -58, -97, -66, -70, -56, + -65 ] racc_goto_table = [ - 15, 92, 91, 7, 38, 37, 24, 90, 57, 28, - 61, 101, 103, 63, 65, 1, 3, 5, 6, 84, - 9, 61, 109, 111, 63, 65, 49, 53, 13, 89, - 100, nil, 52, nil, 106, nil, nil, nil, 102, nil, - nil, nil, nil, nil, 77, 113, 62, 83, 80, 110, - 112, 81, nil, 113, nil, 85, 117, 62, 116 ] + 52, 15, 97, 7, 42, 95, 61, 41, 27, 65, + 30, 67, 1, 69, 3, 5, 105, 89, 107, 6, + 65, 9, 67, 83, 69, 50, 112, 26, 114, 57, + 13, 94, 104, nil, nil, 96, 110, 106, 56, nil, + nil, nil, nil, nil, nil, nil, nil, 113, 115, 81, + 66, 88, 85, nil, nil, 119, 120, nil, nil, nil, + 90, 66, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 116, nil, + nil, nil, nil, nil, nil, 116 ] racc_goto_check = [ - 18, 27, 26, 5, 13, 12, 7, 25, 17, 10, - 20, 24, 28, 31, 33, 1, 2, 3, 4, 17, - 6, 20, 24, 28, 31, 33, 9, 15, 19, 22, - 23, nil, 12, nil, 27, nil, nil, nil, 25, nil, - nil, nil, nil, nil, 18, 26, 5, 13, 7, 25, - 25, 10, nil, 26, nil, 18, 27, 5, 25 ] + 9, 18, 26, 5, 13, 25, 17, 12, 8, 20, + 10, 30, 1, 32, 2, 3, 24, 17, 27, 4, + 20, 6, 30, 9, 32, 8, 24, 7, 27, 15, + 19, 22, 23, nil, nil, 9, 26, 25, 12, nil, + nil, nil, nil, nil, nil, nil, nil, 25, 25, 18, + 5, 13, 10, nil, nil, 25, 26, nil, nil, nil, + 18, 5, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 9, nil, + nil, nil, nil, nil, nil, 9 ] racc_goto_pointer = [ - nil, 15, 15, 16, 17, 2, 19, -3, nil, 0, - 0, nil, -6, -7, nil, -13, nil, -36, -1, 27, - -34, nil, -29, -59, -78, -51, -56, -57, -77, nil, - nil, -31, nil, -30 ] + nil, 12, 13, 14, 18, 2, 20, 18, -1, -27, + 1, nil, -4, -7, nil, -15, nil, -42, 0, 29, + -39, nil, -31, -62, -78, -57, -60, -76, nil, nil, + -37, nil, -35 ] racc_goto_default = [ - nil, nil, nil, nil, nil, 97, nil, nil, 26, nil, - nil, 11, nil, nil, 40, nil, 41, nil, 43, nil, - 96, 58, nil, nil, nil, nil, 104, 114, nil, 60, - 95, 98, 64, 99 ] + nil, nil, nil, nil, nil, 101, nil, nil, nil, 108, + nil, 11, nil, nil, 44, nil, 45, nil, 47, nil, + 100, 62, nil, nil, nil, nil, 117, nil, 64, 99, + 102, 68, 103 ] racc_reduce_table = [ 0, 0, :racc_error, @@ -124,27 +132,27 @@ class GeneratedParser < Racc::Parser 1, 25, :_reduce_none, 1, 25, :_reduce_none, 1, 25, :_reduce_none, + 4, 26, :_reduce_none, + 4, 26, :_reduce_none, 3, 26, :_reduce_none, 3, 26, :_reduce_none, - 2, 29, :_reduce_10, - 1, 29, :_reduce_11, - 2, 30, :_reduce_12, - 1, 30, :_reduce_13, - 2, 30, :_reduce_none, - 2, 32, :_reduce_15, - 1, 32, :_reduce_16, - 2, 32, :_reduce_none, - 3, 31, :_reduce_18, - 3, 31, :_reduce_19, - 1, 31, :_reduce_20, - 1, 31, :_reduce_21, + 2, 29, :_reduce_12, + 1, 29, :_reduce_13, + 2, 31, :_reduce_14, + 1, 31, :_reduce_15, + 3, 30, :_reduce_16, + 3, 30, :_reduce_17, + 1, 30, :_reduce_18, + 1, 30, :_reduce_19, 1, 33, :_reduce_none, - 1, 33, :_reduce_23, + 1, 33, :_reduce_21, 1, 33, :_reduce_none, 1, 33, :_reduce_none, 1, 33, :_reduce_none, 1, 33, :_reduce_none, 1, 33, :_reduce_none, + 1, 33, :_reduce_27, + 1, 33, :_reduce_28, 2, 28, :_reduce_none, 3, 28, :_reduce_none, 1, 34, :_reduce_31, @@ -170,6 +178,8 @@ class GeneratedParser < Racc::Parser 1, 41, :_reduce_none, 1, 41, :_reduce_none, 1, 41, :_reduce_none, + 1, 41, :_reduce_54, + 1, 41, :_reduce_55, 5, 43, :_reduce_none, 4, 43, :_reduce_none, 4, 43, :_reduce_none, @@ -179,42 +189,42 @@ class GeneratedParser < Racc::Parser 1, 45, :_reduce_none, 2, 46, :_reduce_none, 1, 46, :_reduce_none, - 3, 51, :_reduce_none, - 2, 51, :_reduce_none, - 1, 44, :_reduce_65, - 2, 48, :_reduce_66, - 1, 48, :_reduce_67, + 3, 50, :_reduce_none, + 2, 50, :_reduce_none, + 1, 44, :_reduce_67, + 2, 48, :_reduce_68, + 1, 48, :_reduce_69, 2, 47, :_reduce_none, 1, 47, :_reduce_none, - 2, 49, :_reduce_none, - 1, 49, :_reduce_none, - 1, 40, :_reduce_72, + 2, 32, :_reduce_none, + 1, 32, :_reduce_none, + 1, 40, :_reduce_74, 1, 40, :_reduce_none, 1, 40, :_reduce_none, - 1, 50, :_reduce_75, - 1, 50, :_reduce_none, - 1, 50, :_reduce_none, + 1, 49, :_reduce_77, + 1, 49, :_reduce_none, + 1, 49, :_reduce_none, + 1, 51, :_reduce_none, + 1, 51, :_reduce_none, 1, 52, :_reduce_none, 1, 52, :_reduce_none, - 1, 53, :_reduce_none, - 1, 53, :_reduce_none, - 0, 55, :_reduce_none, - 1, 55, :_reduce_none, - 1, 56, :_reduce_84, - 1, 56, :_reduce_85, - 1, 56, :_reduce_86, - 1, 56, :_reduce_87, - 1, 56, :_reduce_88, - 1, 56, :_reduce_89, - 1, 56, :_reduce_90, - 1, 54, :_reduce_91, - 1, 54, :_reduce_92, - 1, 54, :_reduce_93, - 1, 54, :_reduce_94 ] - -racc_reduce_n = 95 - -racc_shift_n = 118 + 0, 54, :_reduce_none, + 1, 54, :_reduce_none, + 1, 55, :_reduce_86, + 1, 55, :_reduce_87, + 1, 55, :_reduce_88, + 1, 55, :_reduce_89, + 1, 55, :_reduce_90, + 1, 55, :_reduce_91, + 1, 55, :_reduce_92, + 1, 53, :_reduce_93, + 1, 53, :_reduce_94, + 1, 53, :_reduce_95, + 1, 53, :_reduce_96 ] + +racc_reduce_n = 97 + +racc_shift_n = 121 racc_token_table = { false => 0, @@ -293,9 +303,9 @@ class GeneratedParser < Racc::Parser "assignment", "inline_table", "table_start", - "table_continued", "table_identifier", - "table_next", + "table_end", + "newlines", "table_identifier_component", "inline_table_start", "inline_table_end", @@ -312,7 +322,6 @@ class GeneratedParser < Racc::Parser "array_values", "comma", "end_array", - "newlines", "non_nil_value", "array_value", "scalar", @@ -346,68 +355,54 @@ class GeneratedParser < Racc::Parser # reduce 9 omitted -module_eval(<<'.,.,', 'parser.y', 18) - def _reduce_10(val, _values, result) - @handler.start_(:array_of_tables) - result - end -.,., +# reduce 10 omitted -module_eval(<<'.,.,', 'parser.y', 19) - def _reduce_11(val, _values, result) - @handler.start_(:table) - result - end -.,., +# reduce 11 omitted -module_eval(<<'.,.,', 'parser.y', 22) +module_eval(<<'.,.,', 'parser.y', 20) def _reduce_12(val, _values, result) - array = @handler.end_(:array_of_tables); @handler.set_context(array, is_array_of_tables: true) + @handler.start_(:array_of_tables) result end .,., -module_eval(<<'.,.,', 'parser.y', 23) +module_eval(<<'.,.,', 'parser.y', 21) def _reduce_13(val, _values, result) - array = @handler.end_(:table); @handler.set_context(array) + @handler.start_(:table) result end .,., -# reduce 14 omitted - -module_eval(<<'.,.,', 'parser.y', 27) - def _reduce_15(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 25) + def _reduce_14(val, _values, result) array = @handler.end_(:array_of_tables); @handler.set_context(array, is_array_of_tables: true) result end .,., -module_eval(<<'.,.,', 'parser.y', 28) - def _reduce_16(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 26) + def _reduce_15(val, _values, result) array = @handler.end_(:table); @handler.set_context(array) result end .,., -# reduce 17 omitted - -module_eval(<<'.,.,', 'parser.y', 32) - def _reduce_18(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 29) + def _reduce_16(val, _values, result) @handler.push(val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 33) - def _reduce_19(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 30) + def _reduce_17(val, _values, result) val[2].split('.').each { |k| @handler.push(k) } result end .,., -module_eval(<<'.,.,', 'parser.y', 35) - def _reduce_20(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 32) + def _reduce_18(val, _values, result) keys = val[0].split('.') @handler.start_(:table) keys.each { |key| @handler.push(key) } @@ -416,44 +411,58 @@ def _reduce_20(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 39) - def _reduce_21(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 36) + def _reduce_19(val, _values, result) @handler.push(val[0]) result end .,., -# reduce 22 omitted +# reduce 20 omitted -module_eval(<<'.,.,', 'parser.y', 43) - def _reduce_23(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 40) + def _reduce_21(val, _values, result) result = StringUtils.replace_escaped_chars(val[0]) result end .,., +# reduce 22 omitted + +# reduce 23 omitted + # reduce 24 omitted # reduce 25 omitted # reduce 26 omitted -# reduce 27 omitted +module_eval(<<'.,.,', 'parser.y', 46) + def _reduce_27(val, _values, result) + result = val[0][0] + result + end +.,., -# reduce 28 omitted +module_eval(<<'.,.,', 'parser.y', 47) + def _reduce_28(val, _values, result) + result = val[0][0] + result + end +.,., # reduce 29 omitted # reduce 30 omitted -module_eval(<<'.,.,', 'parser.y', 55) +module_eval(<<'.,.,', 'parser.y', 54) def _reduce_31(val, _values, result) @handler.start_(:inline) result end .,., -module_eval(<<'.,.,', 'parser.y', 59) +module_eval(<<'.,.,', 'parser.y', 58) def _reduce_32(val, _values, result) array = @handler.end_(:inline) @handler.push_inline(array) @@ -468,7 +477,7 @@ def _reduce_32(val, _values, result) # reduce 35 omitted -module_eval(<<'.,.,', 'parser.y', 72) +module_eval(<<'.,.,', 'parser.y', 71) def _reduce_36(val, _values, result) keys = @handler.end_(:inline_keys) @handler.push(keys) @@ -477,7 +486,7 @@ def _reduce_36(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 78) +module_eval(<<'.,.,', 'parser.y', 77) def _reduce_37(val, _values, result) @handler.push(val[2]) @@ -485,14 +494,14 @@ def _reduce_37(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 80) +module_eval(<<'.,.,', 'parser.y', 79) def _reduce_38(val, _values, result) val[2].split('.').each { |k| @handler.push(k) } result end .,., -module_eval(<<'.,.,', 'parser.y', 82) +module_eval(<<'.,.,', 'parser.y', 81) def _reduce_39(val, _values, result) keys = val[0].split('.') @handler.start_(:inline_keys) @@ -502,7 +511,7 @@ def _reduce_39(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 87) +module_eval(<<'.,.,', 'parser.y', 86) def _reduce_40(val, _values, result) @handler.start_(:inline_keys) @handler.push(val[0]) @@ -511,7 +520,7 @@ def _reduce_40(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 93) +module_eval(<<'.,.,', 'parser.y', 92) def _reduce_41(val, _values, result) keys = @handler.end_(:keys) value = keys.pop @@ -523,7 +532,7 @@ def _reduce_41(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 100) +module_eval(<<'.,.,', 'parser.y', 99) def _reduce_42(val, _values, result) keys = @handler.end_(:keys) value = keys.pop @@ -535,21 +544,21 @@ def _reduce_42(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 108) +module_eval(<<'.,.,', 'parser.y', 107) def _reduce_43(val, _values, result) @handler.push(val[2]) result end .,., -module_eval(<<'.,.,', 'parser.y', 109) +module_eval(<<'.,.,', 'parser.y', 108) def _reduce_44(val, _values, result) val[2].split('.').each { |k| @handler.push(k) } result end .,., -module_eval(<<'.,.,', 'parser.y', 111) +module_eval(<<'.,.,', 'parser.y', 110) def _reduce_45(val, _values, result) keys = val[0].split('.') @handler.start_(:keys) @@ -559,7 +568,7 @@ def _reduce_45(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 115) +module_eval(<<'.,.,', 'parser.y', 114) def _reduce_46(val, _values, result) @handler.start_(:keys); @handler.push(val[0]) result @@ -568,7 +577,7 @@ def _reduce_46(val, _values, result) # reduce 47 omitted -module_eval(<<'.,.,', 'parser.y', 119) +module_eval(<<'.,.,', 'parser.y', 118) def _reduce_48(val, _values, result) result = StringUtils.replace_escaped_chars(val[0]) result @@ -585,9 +594,19 @@ def _reduce_48(val, _values, result) # reduce 53 omitted -# reduce 54 omitted +module_eval(<<'.,.,', 'parser.y', 124) + def _reduce_54(val, _values, result) + result = val[0][0] + result + end +.,., -# reduce 55 omitted +module_eval(<<'.,.,', 'parser.y', 125) + def _reduce_55(val, _values, result) + result = val[0][0] + result + end +.,., # reduce 56 omitted @@ -607,57 +626,57 @@ def _reduce_48(val, _values, result) # reduce 64 omitted -module_eval(<<'.,.,', 'parser.y', 146) - def _reduce_65(val, _values, result) +# reduce 65 omitted + +# reduce 66 omitted + +module_eval(<<'.,.,', 'parser.y', 147) + def _reduce_67(val, _values, result) @handler.start_(:array) result end .,., -module_eval(<<'.,.,', 'parser.y', 149) - def _reduce_66(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 150) + def _reduce_68(val, _values, result) array = @handler.end_(:array); @handler.push(array.compact) result end .,., -module_eval(<<'.,.,', 'parser.y', 150) - def _reduce_67(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 151) + def _reduce_69(val, _values, result) array = @handler.end_(:array); @handler.push(array.compact) result end .,., -# reduce 68 omitted - -# reduce 69 omitted - # reduce 70 omitted # reduce 71 omitted -module_eval(<<'.,.,', 'parser.y', 161) - def _reduce_72(val, _values, result) +# reduce 72 omitted + +# reduce 73 omitted + +module_eval(<<'.,.,', 'parser.y', 162) + def _reduce_74(val, _values, result) @handler.push(val[0]) result end .,., -# reduce 73 omitted +# reduce 75 omitted -# reduce 74 omitted +# reduce 76 omitted -module_eval(<<'.,.,', 'parser.y', 166) - def _reduce_75(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 167) + def _reduce_77(val, _values, result) @handler.push(val[0]) result end .,., -# reduce 76 omitted - -# reduce 77 omitted - # reduce 78 omitted # reduce 79 omitted @@ -670,15 +689,19 @@ def _reduce_75(val, _values, result) # reduce 83 omitted -module_eval(<<'.,.,', 'parser.y', 182) - def _reduce_84(val, _values, result) +# reduce 84 omitted + +# reduce 85 omitted + +module_eval(<<'.,.,', 'parser.y', 183) + def _reduce_86(val, _values, result) result = val[0].to_f result end .,., -module_eval(<<'.,.,', 'parser.y', 184) - def _reduce_85(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 185) + def _reduce_87(val, _values, result) v = val[0] result = if v.end_with?('nan') Float::NAN @@ -690,15 +713,15 @@ def _reduce_85(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 191) - def _reduce_86(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 192) + def _reduce_88(val, _values, result) result = val[0].to_i result end .,., -module_eval(<<'.,.,', 'parser.y', 193) - def _reduce_87(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 194) + def _reduce_89(val, _values, result) base = case val[0][1] when 'x' then 16 when 'o' then 8 @@ -710,31 +733,31 @@ def _reduce_87(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 200) - def _reduce_88(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 201) + def _reduce_90(val, _values, result) result = val[0] == 'true' ? true : false result end .,., -module_eval(<<'.,.,', 'parser.y', 202) - def _reduce_89(val, _values, result) - v = val[0] - result = if v[6].nil? - if v[4].nil? - LocalDate.new(v[0], v[1], v[2]) +module_eval(<<'.,.,', 'parser.y', 203) + def _reduce_91(val, _values, result) + _str, year, month, day, hour, min, sec, offset = val[0] + result = if offset.nil? + if hour.nil? + LocalDate.new(year, month, day) else - LocalDateTime.new(v[0], v[1], v[2], v[3] || 0, v[4] || 0, v[5].to_f) + LocalDateTime.new(year, month, day, hour, min || 0, sec.to_f) end else # Patch for 24:00:00 which Ruby parses - if v[3].to_i == 24 && v[4].to_i == 0 && v[5].to_i == 0 - v[3] = (v[3].to_i + 1).to_s + if hour.to_i == 24 && month.to_i == 0 && day.to_i == 0 + hour = (hour.to_i + 1).to_s end - time = Time.new(v[0], v[1], v[2], v[3] || 0, v[4] || 0, v[5].to_f, v[6]) + time = Time.new(year, month, day, hour || 0, min || 0, sec.to_f, offset) # Should be out of parser.y? - raise ArgumentError, "Invalid Offset Date-Time: #{v[0]}-#{v[1]}-#{v[2]}T#{v[3]}:#{v[4]}:#{v[5]}#{v[6]}" unless v[4].to_i == time.min && v[3].to_i == time.hour && v[2].to_i == time.day && v[1].to_i == time.month && v[0].to_i == time.year + raise ArgumentError, "Invalid Offset Date-Time: #{year}-#{month}-#{day}T#{hour}:#{min}:#{sec}#{offset}" unless min.to_i == time.min && hour.to_i == time.hour && day.to_i == time.day && month.to_i == time.month && year.to_i == time.year time end @@ -742,36 +765,36 @@ def _reduce_89(val, _values, result) end .,., -module_eval(<<'.,.,', 'parser.y', 221) - def _reduce_90(val, _values, result) - result = LocalTime.new(*val[0]) +module_eval(<<'.,.,', 'parser.y', 222) + def _reduce_92(val, _values, result) + result = LocalTime.new(*val[0][1..]) result end .,., -module_eval(<<'.,.,', 'parser.y', 224) - def _reduce_91(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 225) + def _reduce_93(val, _values, result) result = StringUtils.replace_escaped_chars(StringUtils.multiline_replacements(val[0])) result end .,., -module_eval(<<'.,.,', 'parser.y', 225) - def _reduce_92(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 226) + def _reduce_94(val, _values, result) result = StringUtils.replace_escaped_chars(val[0]) result end .,., -module_eval(<<'.,.,', 'parser.y', 226) - def _reduce_93(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 227) + def _reduce_95(val, _values, result) result = StringUtils.strip_spaces(val[0]) result end .,., -module_eval(<<'.,.,', 'parser.y', 227) - def _reduce_94(val, _values, result) +module_eval(<<'.,.,', 'parser.y', 228) + def _reduce_96(val, _values, result) result = val[0] result end From 3c4f00e2b81b25166d2d6ee634f7ffb529d0c422 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 4 Nov 2025 01:45:22 +0900 Subject: [PATCH 22/29] Don't use unsupported notation for older Rubies --- lib/tomlrb/parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tomlrb/parser.y b/lib/tomlrb/parser.y index 7c9051a..5dcc254 100644 --- a/lib/tomlrb/parser.y +++ b/lib/tomlrb/parser.y @@ -220,7 +220,7 @@ rule time end } - | LOCAL_TIME { result = LocalTime.new(*val[0][1..]) } + | LOCAL_TIME { result = LocalTime.new(*val[0][1..-1]) } ; string : STRING_MULTI { result = StringUtils.replace_escaped_chars(StringUtils.multiline_replacements(val[0])) } From 16cbb541763baf5069ec3535a4f6135c0a9479ce Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 4 Nov 2025 01:45:26 +0900 Subject: [PATCH 23/29] Update generated parser --- lib/tomlrb/generated_parser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tomlrb/generated_parser.rb b/lib/tomlrb/generated_parser.rb index 11e5829..5461368 100644 --- a/lib/tomlrb/generated_parser.rb +++ b/lib/tomlrb/generated_parser.rb @@ -767,7 +767,7 @@ def _reduce_91(val, _values, result) module_eval(<<'.,.,', 'parser.y', 222) def _reduce_92(val, _values, result) - result = LocalTime.new(*val[0][1..]) + result = LocalTime.new(*val[0][1..-1]) result end .,., From bd7d7ad02e3f82d9486fab46eb8b52baa7a36af9 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 4 Nov 2025 03:04:47 +0900 Subject: [PATCH 24/29] Skip test which causes stack overflow for TruffleRuby --- test/test_compliance.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/test_compliance.rb b/test/test_compliance.rb index dd25d9c..41ceda0 100644 --- a/test/test_compliance.rb +++ b/test/test_compliance.rb @@ -38,6 +38,12 @@ toml_path = toml_path.expand_path local_path = toml_path.relative_path_from(Pathname.new(File.join(__dir__, '..'))) + if ENV['CI'] == 'true' && RUBY_ENGINE == 'truffleruby' && + local_path.to_path == "toml-spec-tests/values/qa-table-inline-nested-1000.toml" + warn "Skipping #{local_path} on TruffleRuby CI due to stack size limitations" + next + end + if tests_dir == File.join(__dir__, '../toml-test/tests') path_in_list = local_path.relative_path_from(toml_test_list_base) next unless toml_test_list.include?(path_in_list.to_path) From 4f49008abd7cfc924dca9ed6bf36f5ae1bdc02eb Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 4 Nov 2025 03:11:40 +0900 Subject: [PATCH 25/29] Use literaral comma --- lib/tomlrb/parser.y | 8 ++++---- lib/tomlrb/scanner.rb | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/tomlrb/parser.y b/lib/tomlrb/parser.y index 5dcc254..85e1cc8 100644 --- a/lib/tomlrb/parser.y +++ b/lib/tomlrb/parser.y @@ -1,5 +1,5 @@ class Tomlrb::GeneratedParser -token IDENTIFIER STRING_MULTI STRING_BASIC STRING_LITERAL_MULTI STRING_LITERAL DATETIME LOCAL_TIME INTEGER NON_DEC_INTEGER FLOAT FLOAT_KEYWORD BOOLEAN NEWLINE COMMA EOS +token IDENTIFIER STRING_MULTI STRING_BASIC STRING_LITERAL_MULTI STRING_LITERAL DATETIME LOCAL_TIME INTEGER NON_DEC_INTEGER FLOAT FLOAT_KEYWORD BOOLEAN NEWLINE EOS rule expressions | expressions expression @@ -65,7 +65,7 @@ rule | inline_assignment inline_next ; inline_next - : COMMA inline_continued + : ',' inline_continued ; inline_assignment : inline_assignment_key '=' value { @@ -152,8 +152,8 @@ rule | ']' { array = @handler.end_(:array); @handler.push(array.compact) } ; comma - : newlines COMMA - | COMMA + : newlines ',' + | ',' ; newlines : newlines NEWLINE diff --git a/lib/tomlrb/scanner.rb b/lib/tomlrb/scanner.rb index 81c21a0..9951756 100644 --- a/lib/tomlrb/scanner.rb +++ b/lib/tomlrb/scanner.rb @@ -12,7 +12,6 @@ class Scanner /[ \t]/.freeze NEWLINE = /(?:[ \t]*(?:\r?\n)[ \t]*)+/.freeze - COMMA = /,/.freeze STRING_BASIC = /(")(?:\\?[^\u0000-\u0008\u000A-\u001F\u007F\\]|(?:\\[^\u0000-\u0008\u000A-\u001F\u007F]))*?\1/.freeze STRING_MULTI = @@ -50,7 +49,6 @@ def initialize(io) def next_token case when @ss.scan(NEWLINE) then [:NEWLINE, nil] - when @ss.scan(COMMA) then [:COMMA, nil] when @ss.scan(SPACED_ARRAY_OF_TABLES_START) then raise ParseError.new('Array of tables has spaces in starting brackets') when @ss.scan(SPACED_ARRAY_OF_TABLES_END) then raise ParseError.new('Array of tables has spaces in ending brackets') when @ss.scan(SPACED_ARRAY_OF_TABLES_BOTH) then raise ParseError.new('Array of tables has spaces in starting and ending brackets') From 8db4d412f006d86f6cabbbaec2a46221a3768a27 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 4 Nov 2025 03:13:25 +0900 Subject: [PATCH 26/29] Update generated parser --- lib/tomlrb/generated_parser.rb | 108 ++++++++++++++++----------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/lib/tomlrb/generated_parser.rb b/lib/tomlrb/generated_parser.rb index 5461368..416bd26 100644 --- a/lib/tomlrb/generated_parser.rb +++ b/lib/tomlrb/generated_parser.rb @@ -10,68 +10,68 @@ class GeneratedParser < Racc::Parser ##### State transition tables begin ### racc_action_table = [ - 2, 54, 16, 53, 17, 25, 18, 23, 24, 19, - 20, 14, 21, 22, 8, 49, 4, 10, 48, 16, - 12, 17, 40, 18, 23, 24, 19, 20, 46, 21, - 22, 54, 109, 54, 109, 98, 55, 98, 43, 77, - 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, - 87, 118, 60, 63, 111, 59, 12, 77, 78, 79, - 80, 75, 76, 72, 73, 70, 71, 74, 54, 43, - 84, 63, 28, 51, 12, 77, 78, 79, 80, 75, - 76, 72, 73, 70, 71, 74, 54, 58, 87, 63, - 98, 87, 12, 77, 78, 79, 80, 75, 76, 72, - 73, 70, 71, 74, 87, nil, nil, 63, 111, nil, + 2, 49, 16, 25, 17, 48, 18, 23, 24, 19, + 20, 14, 21, 22, 8, 4, 10, 60, 16, 12, + 17, 59, 18, 23, 24, 19, 20, 46, 21, 22, + 28, 51, 54, 53, 54, 84, 43, 77, 78, 79, + 80, 75, 76, 72, 73, 70, 71, 74, 93, 92, + 63, 40, 55, 12, 77, 78, 79, 80, 75, 76, + 72, 73, 70, 71, 74, 43, 58, 63, 87, 87, 12, 77, 78, 79, 80, 75, 76, 72, 73, 70, - 71, 74, 54, nil, nil, 63, 98, nil, 12, 77, + 71, 74, 54, nil, 63, 98, nil, 12, 77, 78, + 79, 80, 75, 76, 72, 73, 70, 71, 74, 87, + nil, 63, 111, nil, 12, 77, 78, 79, 80, 75, + 76, 72, 73, 70, 71, 74, 54, nil, 63, 98, + nil, 12, 77, 78, 79, 80, 75, 76, 72, 73, + 70, 71, 74, 54, nil, 63, 98, nil, 12, 77, 78, 79, 80, 75, 76, 72, 73, 70, 71, 74, - 54, nil, nil, 63, 98, nil, 12, 77, 78, 79, - 80, 75, 76, 72, 73, 70, 71, 74, 87, nil, - nil, 63, 111, 31, 12, 32, nil, 33, 38, 39, - 34, 35, 29, 36, 37, 93, 16, 92, 17, 28, + 87, nil, 63, 111, 31, 12, 32, nil, 33, 38, + 39, 34, 35, 29, 36, 37, 16, nil, 17, 28, 18, 23, 24, 19, 20, 82, 21, 22, 31, nil, 32, nil, 33, 38, 39, 34, 35, 86, 36, 37, 16, nil, 17, nil, 18, 23, 24, 19, 20, 46, 21, 22, 16, nil, 17, nil, 18, 23, 24, 19, - 20, 91, 21, 22 ] + 20, 91, 21, 22, 54, 54, 87, 98, 98, 111, + nil, 109, 109, 118 ] racc_action_check = [ - 1, 27, 1, 27, 1, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 13, 1, 1, 13, 11, - 1, 11, 10, 11, 11, 11, 11, 11, 11, 11, - 11, 94, 94, 104, 104, 94, 28, 104, 11, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 108, 108, 45, 48, 108, 45, 48, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 50, 42, - 50, 59, 26, 26, 59, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 44, 52, 62, - 62, 83, 62, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, nil, nil, 96, 96, nil, - 96, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, nil, nil, 105, 105, nil, 105, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, nil, nil, 112, 112, nil, 112, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, nil, - nil, 116, 116, 9, 116, 9, nil, 9, 9, 9, - 9, 9, 9, 9, 9, 61, 49, 61, 49, 9, + 1, 13, 1, 2, 1, 13, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 45, 11, 1, + 11, 45, 11, 11, 11, 11, 11, 11, 11, 11, + 26, 26, 27, 27, 50, 50, 11, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 61, 61, + 48, 10, 28, 48, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 42, 44, 59, 52, 83, + 59, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, nil, 62, 62, nil, 62, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + nil, 96, 96, nil, 96, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, nil, 105, 105, + nil, 105, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, nil, 112, 112, nil, 112, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 116, nil, 116, 116, 9, 116, 9, nil, 9, 9, + 9, 9, 9, 9, 9, 9, 49, nil, 49, 9, 49, 49, 49, 49, 49, 49, 49, 49, 51, nil, 51, nil, 51, 51, 51, 51, 51, 51, 51, 51, 58, nil, 58, nil, 58, 58, 58, 58, 58, 58, 58, 58, 60, nil, 60, nil, 60, 60, 60, 60, - 60, 60, 60, 60 ] + 60, 60, 60, 60, 94, 104, 108, 94, 104, 108, + nil, 94, 104, 108 ] racc_action_pointer = [ - nil, 0, 5, nil, nil, nil, nil, nil, nil, 161, - 5, 17, nil, -4, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, nil, nil, 54, -13, 18, nil, + nil, 0, 3, nil, nil, nil, nil, nil, nil, 152, + 35, 16, nil, -17, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 13, 18, 35, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, 48, nil, 72, 33, nil, nil, 36, 174, - 54, 186, 74, nil, nil, nil, nil, nil, 198, 54, - 210, 161, 72, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 45, nil, 45, -1, nil, nil, 34, 164, + 20, 176, 54, nil, nil, nil, nil, nil, 188, 51, + 200, 34, 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - nil, nil, nil, 77, nil, nil, nil, nil, nil, nil, - nil, nil, nil, nil, 17, nil, 90, nil, nil, nil, - nil, nil, nil, nil, 19, 108, nil, nil, 36, nil, - nil, nil, 126, nil, nil, nil, 144, nil, nil, nil, + nil, nil, nil, 55, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 200, nil, 85, nil, nil, nil, + nil, nil, nil, nil, 201, 102, nil, nil, 202, nil, + nil, nil, 119, nil, nil, nil, 136, nil, nil, nil, nil ] racc_action_default = [ @@ -242,13 +242,13 @@ class GeneratedParser < Racc::Parser :FLOAT_KEYWORD => 12, :BOOLEAN => 13, :NEWLINE => 14, - :COMMA => 15, - :EOS => 16, - "[" => 17, - "]" => 18, - "." => 19, - "{" => 20, - "}" => 21, + :EOS => 15, + "[" => 16, + "]" => 17, + "." => 18, + "{" => 19, + "}" => 20, + "," => 21, "=" => 22 } racc_nt_base = 23 @@ -288,13 +288,13 @@ class GeneratedParser < Racc::Parser "FLOAT_KEYWORD", "BOOLEAN", "NEWLINE", - "COMMA", "EOS", "\"[\"", "\"]\"", "\".\"", "\"{\"", "\"}\"", + "\",\"", "\"=\"", "$start", "expressions", From bf481e036d0fcf46ccf21f464cc954c4335e1fa5 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 4 Nov 2025 03:19:50 +0900 Subject: [PATCH 27/29] Use skip method for skipped tests --- test/test_compliance.rb | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/test/test_compliance.rb b/test/test_compliance.rb index 41ceda0..477e754 100644 --- a/test/test_compliance.rb +++ b/test/test_compliance.rb @@ -38,18 +38,17 @@ toml_path = toml_path.expand_path local_path = toml_path.relative_path_from(Pathname.new(File.join(__dir__, '..'))) - if ENV['CI'] == 'true' && RUBY_ENGINE == 'truffleruby' && - local_path.to_path == "toml-spec-tests/values/qa-table-inline-nested-1000.toml" - warn "Skipping #{local_path} on TruffleRuby CI due to stack size limitations" - next - end + it "parses #{local_path}" do + if ENV['CI'] == 'true' && RUBY_ENGINE == 'truffleruby' && + local_path.to_path == 'toml-spec-tests/values/qa-table-inline-nested-1000.toml' + skip 'Skipping #{local_path} on TruffleRuby CI due to stack size limitations' + end - if tests_dir == File.join(__dir__, '../toml-test/tests') - path_in_list = local_path.relative_path_from(toml_test_list_base) - next unless toml_test_list.include?(path_in_list.to_path) - end + if tests_dir == File.join(__dir__, '../toml-test/tests') + path_in_list = local_path.relative_path_from(toml_test_list_base) + skip 'Skipping test for Toml 1.1' unless toml_test_list.include?(path_in_list.to_path) + end - it "parses #{local_path}" do actual = Tomlrb.load_file(toml_path.to_path) json_path = toml_path.sub_ext('.json') yaml_path = toml_path.sub_ext('.yaml') From a97ffb766c16c6528c5b59b25891877de13286a6 Mon Sep 17 00:00:00 2001 From: KITAITI Makoto Date: Tue, 4 Nov 2025 04:08:40 +0900 Subject: [PATCH 28/29] Update lib/tomlrb/parser.y MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: François Bernier --- lib/tomlrb/parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tomlrb/parser.y b/lib/tomlrb/parser.y index 85e1cc8..a4b6fd4 100644 --- a/lib/tomlrb/parser.y +++ b/lib/tomlrb/parser.y @@ -210,7 +210,7 @@ rule end else # Patch for 24:00:00 which Ruby parses - if hour.to_i == 24 && month.to_i == 0 && day.to_i == 0 + if hour.to_i == 24 && min.to_i == 0 && sec.to_i == 0 hour = (hour.to_i + 1).to_s end From 87fef240151647811fb1fd78523394bb2f998243 Mon Sep 17 00:00:00 2001 From: Kitaiti Makoto Date: Tue, 4 Nov 2025 22:26:11 +0900 Subject: [PATCH 29/29] Update generated parser --- lib/tomlrb/generated_parser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tomlrb/generated_parser.rb b/lib/tomlrb/generated_parser.rb index 416bd26..bb665af 100644 --- a/lib/tomlrb/generated_parser.rb +++ b/lib/tomlrb/generated_parser.rb @@ -751,7 +751,7 @@ def _reduce_91(val, _values, result) end else # Patch for 24:00:00 which Ruby parses - if hour.to_i == 24 && month.to_i == 0 && day.to_i == 0 + if hour.to_i == 24 && min.to_i == 0 && sec.to_i == 0 hour = (hour.to_i + 1).to_s end