diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2009-09-30 14:32:35 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2009-09-30 14:32:35 -0700 |
commit | 0fdc41a6e3ab790e58db0e0f54affe5d2a8277f2 (patch) | |
tree | 023b528b6e33f4756c03960fccf96b8258ee9790 | |
parent | 211251bab57a5535e47832b75176096e087c89b0 (diff) | |
download | psych-0fdc41a6e3ab790e58db0e0f54affe5d2a8277f2.zip |
using the same logic for string emitting and parsing
-rw-r--r-- | lib/psych/scalar_scanner.rb | 47 | ||||
-rw-r--r-- | lib/psych/visitors/to_ruby.rb | 19 | ||||
-rw-r--r-- | lib/psych/visitors/yast_builder.rb | 6 | ||||
-rw-r--r-- | test/test_scalar_scanner.rb | 51 | ||||
-rw-r--r-- | test/visitors/test_to_ruby.rb | 18 |
5 files changed, 120 insertions, 21 deletions
diff --git a/lib/psych/scalar_scanner.rb b/lib/psych/scalar_scanner.rb new file mode 100644 index 0000000..538edb3 --- /dev/null +++ b/lib/psych/scalar_scanner.rb @@ -0,0 +1,47 @@ +require 'strscan' + +module Psych + ### + # Scan scalars for built in types + class ScalarScanner + def initialize string + @string = string + end + + def tokenize + return [:NULL, nil] if @string.empty? + + case @string + when /^\.inf$/i + [:POSITIVE_INFINITY, 1 / 0.0] + when /^-\.inf$/i + [:NEGATIVE_INFINITY, -1 / 0.0] + when /^\.nan$/i + [:NAN, 0.0 / 0.0] + when /^(null|~)$/i + [:NULL, nil] + when /^:/i + [:SYMBOL, @string.sub(/^:/, '').to_sym] + when /^[-+]?[0-9][0-9_]*(:[0-5]?[0-9])+\.[0-9_]*$/ + i = 0 + @string.split(':').each_with_index do |n,e| + i += (n.to_f * 60 ** (e - 2).abs) + end + + [:FLOAT, i] + when /^[-+]?[1-9][0-9_]*(:[0-5]?[0-9])+$/ + i = 0 + @string.split(':').each_with_index do |n,e| + i += (n.to_i * 60 ** (e - 2).abs) + end + + [:INTEGER, i] + else + return [:FLOAT, Float(@string.gsub(/[,_]/, ''))] rescue ArgumentError + return [:INTEGER, Integer(@string.gsub(/[,_]/, ''))] rescue ArgumentError + + [:SCALAR, @string] + end + end + end +end diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb index c0ee101..84813ed 100644 --- a/lib/psych/visitors/to_ruby.rb +++ b/lib/psych/visitors/to_ruby.rb @@ -1,3 +1,5 @@ +require 'psych/scalar_scanner' + module Psych module Visitors ### @@ -11,22 +13,7 @@ module Psych def visit_Psych_Nodes_Scalar o @st[o.anchor] = o.value if o.anchor - return nil if o.tag == 'tag:yaml.org,2002:null' - return Integer(o.value) if o.tag == 'tag:yaml.org,2002:int' - - unless o.quoted - - return 0.0 / 0.0 if o.value =~ /^\.nan$/i - return 1 / 0.0 if o.value =~ /^\.inf$/i - return -1 / 0.0 if o.value =~ /^\-\.inf$/i - return Float(o.value) if o.tag == 'tag:yaml.org,2002:float' - - return Integer(o.value) rescue ArgumentError - return Float(o.value) rescue ArgumentError - - return nil if o.value =~ /^(null|~)$/i or o.value.empty? - return o.value.sub(/^:/,'').to_sym if o.value =~ /^:/ - end + return ScalarScanner.new(o.value).tokenize.last unless o.quoted o.value end diff --git a/lib/psych/visitors/yast_builder.rb b/lib/psych/visitors/yast_builder.rb index c88cc49..5de56ae 100644 --- a/lib/psych/visitors/yast_builder.rb +++ b/lib/psych/visitors/yast_builder.rb @@ -35,11 +35,7 @@ module Psych end def visit_String o - quote = false - - quote = true if Integer(o) rescue ArgumentError - quote = true if Float(o) rescue ArgumentError - quote = true if(o =~ /^(null|~|[\d.]+)$/i or o =~ /^:/ or o.empty?) + quote = ScalarScanner.new(o).tokenize.first != :SCALAR scalar = Nodes::Scalar.new(o, nil, nil, !quote, quote) @stack.last.children << scalar diff --git a/test/test_scalar_scanner.rb b/test/test_scalar_scanner.rb new file mode 100644 index 0000000..5311249 --- /dev/null +++ b/test/test_scalar_scanner.rb @@ -0,0 +1,51 @@ +require 'minitest/autorun' +require 'psych' + +class TestScalarScanner < MiniTest::Unit::TestCase + def test_scan_inf + ss = Psych::ScalarScanner.new('.inf') + assert_equal [:POSITIVE_INFINITY, 1 / 0.0], ss.tokenize + end + + def test_scan_minus_inf + ss = Psych::ScalarScanner.new('-.inf') + assert_equal [:NEGATIVE_INFINITY, -1 / 0.0], ss.tokenize + end + + def test_scan_nan + ss = Psych::ScalarScanner.new('.nan') + assert_equal :NAN, ss.tokenize.first + assert ss.tokenize.last.nan? + end + + def test_scan_null + ss = Psych::ScalarScanner.new('null') + assert_equal [:NULL, nil], ss.tokenize + + ss = Psych::ScalarScanner.new('~') + assert_equal [:NULL, nil], ss.tokenize + + ss = Psych::ScalarScanner.new('') + assert_equal [:NULL, nil], ss.tokenize + end + + def test_scan_symbol + ss = Psych::ScalarScanner.new(':foo') + assert_equal [:SYMBOL, :foo], ss.tokenize + end + + def test_scan_sexagesimal_float + ss = Psych::ScalarScanner.new('190:20:30.15') + assert_equal [:FLOAT, 685230.15], ss.tokenize + end + + def test_scan_sexagesimal_int + ss = Psych::ScalarScanner.new('190:20:30') + assert_equal [:INTEGER, 685230], ss.tokenize + end + + def test_scan_float + ss = Psych::ScalarScanner.new('1.2') + assert_equal [:FLOAT, 1.2], ss.tokenize + end +end diff --git a/test/visitors/test_to_ruby.rb b/test/visitors/test_to_ruby.rb index 6facc68..0dafbd8 100644 --- a/test/visitors/test_to_ruby.rb +++ b/test/visitors/test_to_ruby.rb @@ -21,6 +21,24 @@ module Psych assert_equal 1, Nodes::Scalar.new('+1').to_ruby end + def test_int_ignore + ['1,000', '1_000'].each do |num| + i = Nodes::Scalar.new(num, nil, 'tag:yaml.org,2002:int') + assert_equal 1000, i.to_ruby + + assert_equal 1000, Nodes::Scalar.new(num).to_ruby + end + end + + def test_float_ignore + ['1,000.3', '1_000.3'].each do |num| + i = Nodes::Scalar.new(num, nil, 'tag:yaml.org,2002:float') + assert_equal 1000.3, i.to_ruby + + assert_equal 1000.3, Nodes::Scalar.new(num).to_ruby + end + end + def test_float i = Nodes::Scalar.new('1.2', nil, 'tag:yaml.org,2002:float') assert_equal 1.2, i.to_ruby |