tomlrb 1.2.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,53 +2,91 @@ require 'strscan'
2
2
 
3
3
  module Tomlrb
4
4
  class Scanner
5
- COMMENT = /#.*/
5
+ COMMENT = /#[^\u0000-\u0008\u000A-\u001F\u007F]*/
6
6
  IDENTIFIER = /[A-Za-z0-9_-]+/
7
- SPACE = /[ \t\r\n]/
8
- STRING_BASIC = /(["])(?:\\?.)*?\1/
9
- STRING_MULTI = /"{3}([\s\S]*?"{3,4})/m
10
- STRING_LITERAL = /(['])(?:\\?.)*?\1/
11
- STRING_LITERAL_MULTI = /'{3}([\s\S]*?'{3})/m
12
- DATETIME = /(-?\d{4})-(\d{2})-(\d{2})(?:(?:t|\s)(\d{2}):(\d{2}):(\d{2}(?:\.\d+)?))?(z|[-+]\d{2}:\d{2})?/i
13
- FLOAT = /[+-]?(?:[0-9_]+\.[0-9_]*|\.[0-9_]+|\d+(?=[eE]))(?:[eE][+-]?[0-9_]+)?/
14
- INTEGER = /[+-]?\d(_?\d)*(?![A-Za-z0-9_-]+)/
7
+ SPACE = /[ \t]/
8
+ NEWLINE = /(\r?\n)/
9
+ STRING_BASIC = /(["])(?:\\?[^\u0000-\u0008\u000A-\u001F\u007F])*?\1/
10
+ STRING_MULTI = /"{3}([^\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]*?(?<!\\)"{3,5})/m
11
+ STRING_LITERAL = /(['])(?:\\?[^\u0000-\u0008\u000A-\u001F\u007F])*?\1/
12
+ STRING_LITERAL_MULTI = /'{3}([^\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]*?'{3,5})/m
13
+ DATETIME = /(-?\d{4})-(\d{2})-(\d{2})(?:(?:t|\s)(\d{2}):(\d{2}):(\d{2}(?:\.\d+)?))?(z|[-+]\d{2}:\d{2})/i
14
+ LOCAL_DATETIME = /(-?\d{4})-(\d{2})-(\d{2})(?:t|\s)(\d{2}):(\d{2}):(\d{2}(?:\.\d+)?)/i
15
+ LOCAL_DATE = /(-?\d{4})-(\d{2})-(\d{2})/
16
+ LOCAL_TIME = /(\d{2}):(\d{2}):(\d{2}(?:\.\d+)?)/
17
+ FLOAT = /[+-]?(?:(?:\d|[1-9](?:_?\d)*)\.\d(?:_?\d)*|\d+(?=[eE]))(?:[eE][+-]?[0-9_]+)?(?!\w)/
18
+ FLOAT_INF = /[+-]?inf\b/
19
+ FLOAT_NAN = /[+-]?nan\b/
20
+ INTEGER = /[+-]?([1-9](_?\d)*|0)(?![A-Za-z0-9_-]+)/
21
+ HEX_INTEGER = /0x[0-9A-Fa-f][0-9A-Fa-f_]*/
22
+ OCT_INTEGER = /0o[0-7][0-7_]*/
23
+ BIN_INTEGER = /0b[01][01_]*/
15
24
  TRUE = /true/
16
25
  FALSE = /false/
17
26
 
18
27
  def initialize(io)
19
28
  @ss = StringScanner.new(io.read)
29
+ @eos = false
20
30
  end
21
31
 
22
32
  def next_token
23
- return if @ss.eos?
24
-
25
33
  case
34
+ when @ss.eos? then process_eos
26
35
  when @ss.scan(SPACE) then next_token
27
36
  when @ss.scan(COMMENT) then next_token
28
37
  when @ss.scan(DATETIME) then process_datetime
38
+ when @ss.scan(LOCAL_DATETIME) then process_local_datetime
39
+ when @ss.scan(LOCAL_DATE) then process_local_date
40
+ when @ss.scan(LOCAL_TIME) then process_local_time
29
41
  when text = @ss.scan(STRING_MULTI) then [:STRING_MULTI, text[3..-4]]
30
42
  when text = @ss.scan(STRING_BASIC) then [:STRING_BASIC, text[1..-2]]
31
43
  when text = @ss.scan(STRING_LITERAL_MULTI) then [:STRING_LITERAL_MULTI, text[3..-4]]
32
44
  when text = @ss.scan(STRING_LITERAL) then [:STRING_LITERAL, text[1..-2]]
33
45
  when text = @ss.scan(FLOAT) then [:FLOAT, text]
46
+ when text = @ss.scan(FLOAT_INF) then [:FLOAT_INF, text]
47
+ when text = @ss.scan(FLOAT_NAN) then [:FLOAT_NAN, text]
34
48
  when text = @ss.scan(INTEGER) then [:INTEGER, text]
49
+ when text = @ss.scan(HEX_INTEGER) then [:HEX_INTEGER, text]
50
+ when text = @ss.scan(OCT_INTEGER) then [:OCT_INTEGER, text]
51
+ when text = @ss.scan(BIN_INTEGER) then [:BIN_INTEGER, text]
35
52
  when text = @ss.scan(TRUE) then [:TRUE, text]
36
53
  when text = @ss.scan(FALSE) then [:FALSE, text]
54
+ when text = @ss.scan(NEWLINE) then [:NEWLINE, text]
37
55
  when text = @ss.scan(IDENTIFIER) then [:IDENTIFIER, text]
38
- else
39
- x = @ss.getch
40
- [x, x]
56
+ else x = @ss.getch; [x, x]
41
57
  end
42
58
  end
43
59
 
44
60
  def process_datetime
45
61
  if @ss[7].nil?
46
- offset = Time.now.utc_offset
62
+ offset = '+00:00'
47
63
  else
48
64
  offset = @ss[7].gsub('Z', '+00:00')
49
65
  end
50
- args = [ @ss[1], @ss[2], @ss[3], @ss[4] || 0, @ss[5] || 0, @ss[6].to_f, offset ]
66
+ args = [@ss[1], @ss[2], @ss[3], @ss[4] || 0, @ss[5] || 0, @ss[6].to_f, offset]
51
67
  [:DATETIME, args]
52
68
  end
69
+
70
+ def process_local_datetime
71
+ args = [@ss[1], @ss[2], @ss[3], @ss[4] || 0, @ss[5] || 0, @ss[6].to_f]
72
+ [:LOCAL_DATETIME, args]
73
+ end
74
+
75
+ def process_local_date
76
+ args = [@ss[1], @ss[2], @ss[3]]
77
+ [:LOCAL_DATE, args]
78
+ end
79
+
80
+ def process_local_time
81
+ args = [@ss[1], @ss[2], @ss[3].to_f]
82
+ [:LOCAL_TIME, args]
83
+ end
84
+
85
+ def process_eos
86
+ return if @eos
87
+
88
+ @eos = true
89
+ [:EOS, nil]
90
+ end
53
91
  end
54
92
  end
@@ -12,7 +12,13 @@ module Tomlrb
12
12
  }.freeze
13
13
 
14
14
  def self.multiline_replacements(str)
15
- strip_spaces(str).gsub(/\\\n\s+/, '')
15
+ strip_spaces(str).gsub(/\\+\s*\n\s*/) {|matched|
16
+ if matched.match(/\\+/)[0].length.odd?
17
+ matched.gsub(/\\\s*\n\s*/, '')
18
+ else
19
+ matched
20
+ end
21
+ }
16
22
  end
17
23
 
18
24
  def self.replace_escaped_chars(str)
@@ -1,3 +1,3 @@
1
1
  module Tomlrb
2
- VERSION = "1.2.6"
2
+ VERSION = '2.0.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tomlrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.6
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francois Bernier
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-23 00:00:00.000000000 Z
11
+ date: 2020-11-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A racc based toml parser
14
14
  email:
@@ -17,25 +17,18 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - ".gitignore"
21
- - ".travis.yml"
22
- - CHANGELOG.md
23
- - Gemfile
24
20
  - LICENSE.txt
25
- - README.md
26
- - Rakefile
27
- - benchmarks/bench.rb
28
- - bin/console
29
- - bin/setup
30
21
  - lib/tomlrb.rb
31
22
  - lib/tomlrb/generated_parser.rb
32
23
  - lib/tomlrb/handler.rb
24
+ - lib/tomlrb/local_date.rb
25
+ - lib/tomlrb/local_date_time.rb
26
+ - lib/tomlrb/local_time.rb
33
27
  - lib/tomlrb/parser.rb
34
28
  - lib/tomlrb/parser.y
35
29
  - lib/tomlrb/scanner.rb
36
30
  - lib/tomlrb/string_utils.rb
37
31
  - lib/tomlrb/version.rb
38
- - tomlrb.gemspec
39
32
  homepage: https://github.com/fbernier/tomlrb
40
33
  licenses:
41
34
  - MIT
@@ -55,8 +48,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
48
  - !ruby/object:Gem::Version
56
49
  version: '0'
57
50
  requirements: []
58
- rubyforge_project:
59
- rubygems_version: 2.5.2.1
51
+ rubygems_version: 3.1.4
60
52
  signing_key:
61
53
  specification_version: 4
62
54
  summary: A racc based toml parser
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
@@ -1,5 +0,0 @@
1
- language: ruby
2
- before_install:
3
- - gem install bundler
4
- rvm:
5
- - 2.2.1
@@ -1,8 +0,0 @@
1
- ### 1.2.6 - 2017-10-23
2
-
3
- * Fix issue where an unclosed table could make the parsing loop infinitely.
4
- * Proper string escaping
5
-
6
- ### 1.1.3 - 2015-11-24
7
-
8
- * Bare integers can be used as keys as per the spec
data/Gemfile DELETED
@@ -1,13 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- group :development do
4
- gem "bundler"
5
- gem "rake"
6
- gem "byebug"
7
- gem "racc"
8
- gem "minitest"
9
- gem "minitest-reporters"
10
- gem "benchmark-ips"
11
- end
12
-
13
- gemspec
data/README.md DELETED
@@ -1,80 +0,0 @@
1
- # Tomlrb
2
-
3
- [![Code Climate](https://codeclimate.com/github/fbernier/tomlrb/badges/gpa.svg)](https://codeclimate.com/github/fbernier/tomlrb) [![Build Status](https://travis-ci.org/fbernier/tomlrb.svg)](https://travis-ci.org/fbernier/tomlrb) [![Gem Version](https://badge.fury.io/rb/tomlrb.svg)](http://badge.fury.io/rb/tomlrb)
4
-
5
- A Racc based [TOML](https://github.com/toml-lang/toml) Ruby parser supporting the 0.4.0 version of the spec.
6
-
7
-
8
- ## TODO
9
-
10
- * Better tests
11
- * Dumper
12
-
13
- ## Installation
14
-
15
- Add this line to your application's Gemfile:
16
-
17
- ```ruby
18
- gem 'tomlrb'
19
- ```
20
-
21
- And then execute:
22
-
23
- $ bundle
24
-
25
- Or install it yourself as:
26
-
27
- $ gem install tomlrb
28
-
29
- ## Usage
30
-
31
- ```ruby
32
- Tomlrb.parse("[toml]\na = [\"array\", 123]")
33
- ```
34
-
35
- or
36
-
37
- ```ruby
38
- Tomlrb.load_file('my_file', symbolize_keys: true)
39
- ```
40
-
41
- ## Benchmark
42
-
43
- You can run the benchmark against the only other v0.4.0 compliant parser to my knowledge with `ruby benchmarks/bench.rb`.
44
-
45
- Here are the results on my machine:
46
-
47
- ```
48
- Warming up --------------------------------------
49
- emancu/toml-rb 1.000 i/100ms
50
- fbernier/tomlrb 65.000 i/100ms
51
- Calculating -------------------------------------
52
- emancu/toml-rb 19.199 (± 5.2%) i/s - 96.000 in 5.034377s
53
- fbernier/tomlrb 653.650 (± 4.0%) i/s - 3.315k in 5.081117s
54
-
55
- Comparison:
56
- fbernier/tomlrb: 653.6 i/s
57
- emancu/toml-rb: 19.2 i/s - 34.05x slower
58
- ```
59
-
60
- ## Development
61
-
62
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
63
-
64
- Do not forget to regenerate the parser when you modify rules in the `parser.y` file using `rake compile`.
65
-
66
- Run the tests using `rake test`.
67
-
68
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
69
-
70
- ## Contributing
71
-
72
- 1. Fork it ( https://github.com/[my-github-username]/tomlrb/fork )
73
- 2. Create your feature branch (`git checkout -b my-new-feature`)
74
- 3. Commit your changes (`git commit -am 'Add some feature'`)
75
- 4. Push to the branch (`git push origin my-new-feature`)
76
- 5. Create a new Pull Request
77
-
78
- ## Thanks
79
-
80
- Thanks to [@jpbougie](https://github.com/jpbougie) for the crash course on the Chomsky hierarchy and general tips.
data/Rakefile DELETED
@@ -1,14 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require 'rake/testtask'
3
-
4
- Rake::TestTask.new do |t|
5
- t.libs << "test"
6
- t.test_files = FileList['test/test*.rb']
7
- t.verbose = true
8
- end
9
-
10
- task default: [:test]
11
-
12
- task :compile do
13
- sh 'racc lib/tomlrb/parser.y -o lib/tomlrb/generated_parser.rb'
14
- end
@@ -1,22 +0,0 @@
1
- require 'benchmark/ips'
2
- require_relative '../lib/tomlrb'
3
- begin
4
- require 'toml-rb'
5
- rescue LoadError
6
- puts "Install toml-rb using 'gem install toml-rb' first."
7
- end
8
-
9
- data = File.read(File.join(__dir__, '../test/example-v0.4.0.toml'))
10
-
11
- Benchmark.ips do |x|
12
-
13
- x.report("emancu/toml-rb") do
14
- TomlRB.parse(data)
15
- end
16
-
17
- x.report("fbernier/tomlrb") do
18
- Tomlrb.parse(data)
19
- end
20
-
21
- x.compare!
22
- end
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "tomlrb"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- require "byebug"
data/bin/setup DELETED
@@ -1,6 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
-
5
- bundle install
6
- rake compile
@@ -1,22 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'tomlrb/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "tomlrb"
8
- spec.version = Tomlrb::VERSION
9
- spec.authors = ["Francois Bernier"]
10
- spec.email = ["frankbernier@gmail.com"]
11
-
12
- spec.summary = %q{A racc based toml parser}
13
- spec.description = %q{A racc based toml parser}
14
- spec.homepage = "https://github.com/fbernier/tomlrb"
15
- spec.license = "MIT"
16
-
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
- spec.bindir = "exe"
19
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
- spec.require_paths = ["lib"]
21
- spec.required_ruby_version = '>= 2.0'
22
- end