tomlrb 1.2.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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