From 753120f27ee806d1d2d703df93718d7ba51887a6 Mon Sep 17 00:00:00 2001 From: Dan Hirsch <thequux@upstandinghackers.com> Date: Fri, 10 Jan 2014 22:30:57 +0100 Subject: [PATCH] All of the main test suite works --- lib/test-suite | 28 +-- lib/tsgenruby.pl | 5 +- src/bindings/ruby/lib/hammer/internal.rb | 35 +++- src/bindings/ruby/lib/hammer/parser.rb | 48 ++++- .../ruby/lib/minitest/hamer-parser_plugin.rb | 5 +- src/bindings/ruby/test/autogen_test.rb | 178 ++++++++---------- 6 files changed, 169 insertions(+), 130 deletions(-) diff --git a/lib/test-suite b/lib/test-suite index 6c15b3d6..7f00b8e3 100644 --- a/lib/test-suite +++ b/lib/test-suite @@ -19,7 +19,7 @@ token { parser token("95\xa2"); test "95\xa2" --> "95\xa2"; - test "95\xa2" --> fail; + test "95\xa3" --> fail; } ch { @@ -87,7 +87,7 @@ uint8 { } int_range { - parser int_range(uint8(), 0x3, 0x10); + parser int_range(uint8(), 0x3, 0xa); test <05> --> u0x05; test <0b> --> fail; } @@ -299,17 +299,17 @@ rightrec { test "aa" --> ['a',['a']]; test "aaa" --> ['a',['a',['a']]]; } - -ambiguous { - subparser $d = ch('d'); - subparser $p = ch('+'); - subparser $e = choice(sequence($e, $p, $e), $d); - # TODO: implement action/h_act_flatten - parser $e; - - test "d" --> 'd'; - test "d+d" --> ['d','+','d']; - test "d+d+d" --> [['d','+','d'],'+','d']; -} +## Only for GLR +#ambiguous { +# subparser $d = ch('d'); +# subparser $p = ch('+'); +# subparser $e = choice(sequence($e, $p, $e), $d); +# # TODO: implement action/h_act_flatten +# parser $e; +# +# test "d" --> 'd'; +# test "d+d" --> ['d','+','d']; +# test "d+d+d" --> [['d','+','d'],'+','d']; +#} diff --git a/lib/tsgenruby.pl b/lib/tsgenruby.pl index ebcc86a7..ad83cf16 100644 --- a/lib/tsgenruby.pl +++ b/lib/tsgenruby.pl @@ -96,7 +96,8 @@ pp_parser(num(Num)) --> !, "-0x", {RNum is -Num}; "0x", {RNum = Num} ), pp_hexnum_guts(RNum). pp_parser(char(C)) --> !, - "'", pp_char_guts(C), "'", !. + pp_parser(num(C)). + %"'", pp_char_guts(C), "'", !. pp_parser(ref(Name)) --> {atom_codes(Name,CName)}, @@ -198,7 +199,7 @@ pp_parse_result(char(C)) --> !, pp_parse_result(seq(Args)) --> !, "[", pp_result_seq(Args), "]". pp_parse_result(none) --> !, - "null". + "nil". pp_parse_result(uint(V)) --> !, pp_parser(num(V)). pp_parse_result(sint(V)) --> !, diff --git a/src/bindings/ruby/lib/hammer/internal.rb b/src/bindings/ruby/lib/hammer/internal.rb index 03bc45de..469dd730 100644 --- a/src/bindings/ruby/lib/hammer/internal.rb +++ b/src/bindings/ruby/lib/hammer/internal.rb @@ -28,7 +28,7 @@ module Hammer :arena, :pointer, :elements, :pointer # HParsedToken** - def used + def length self[:used] end @@ -36,6 +36,19 @@ module Hammer elem_array = FFI::Pointer.new(:pointer, self[:elements]) return (0...self[:used]).map { |i| HParsedToken.new(elem_array[i].read_pointer) } end + + #def [](idx) + # raise ArgumentError, "Index out of range" unless idx >= 0 and idx < length + # elem_array = FFI::Pointer.new(:pointer, self[:elements]) + # return HParsedToken.new(elem_array[i].read_pointer) + #end + + def map(&code) + elements.map {|x| code.call x} + end + def each(&code) + elements.each {|x| code.call x} + end end class HBytes < FFI::Struct @@ -72,6 +85,12 @@ module Hammer :index, :size_t, :bit_offset, :char + def normalize + # If I'm null, return nil. + return nil if null? + return self + end + def token_type self[:token_type] end @@ -106,7 +125,7 @@ module Hammer def unmarshal case token_type when :sequence - self[:data][:seq].each {|x| x.unmarshal} + self[:data][:seq].map {|x| x.unmarshal} when :bytes self[:data][:bytes].token when :uint @@ -127,7 +146,7 @@ module Hammer :arena, :pointer def ast - self[:ast] + self[:ast].normalize end def bit_length @@ -140,13 +159,13 @@ module Hammer end # run a parser - attach_function :h_parse, [:h_parser, :string, :size_t], HParseResult.auto_ptr # TODO: Use :buffer_in instead of :string? + attach_function :h_parse, [:h_parser, :pointer, :size_t], HParseResult.auto_ptr # TODO: Use :buffer_in instead of :string? # build a parser attach_function :h_token, [:buffer_in, :size_t], :h_parser attach_function :h_ch, [:uint8], :h_parser attach_function :h_ch_range, [:uint8, :uint8], :h_parser - attach_function :h_int_range, [:int64, :int64], :h_parser + attach_function :h_int_range, [:h_parser, :int64, :int64], :h_parser attach_function :h_bits, [:size_t, :bool], :h_parser attach_function :h_int64, [], :h_parser attach_function :h_int32, [], :h_parser @@ -160,8 +179,8 @@ module Hammer attach_function :h_left, [:h_parser, :h_parser], :h_parser attach_function :h_right, [:h_parser, :h_parser], :h_parser attach_function :h_middle, [:h_parser, :h_parser, :h_parser], :h_parser - #attach_function :h_in, [:buffer_in, :size_t], :h_parser - #attach_function :h_not_in, [:buffer_in, :size_t], :h_parser + attach_function :h_in, [:pointer, :size_t], :h_parser + attach_function :h_not_in, [:pointer, :size_t], :h_parser attach_function :h_end_p, [], :h_parser attach_function :h_nothing_p, [], :h_parser attach_function :h_sequence, [:varargs], :h_parser @@ -171,7 +190,7 @@ module Hammer attach_function :h_xor, [:h_parser, :h_parser], :h_parser attach_function :h_many, [:h_parser], :h_parser attach_function :h_many1, [:h_parser], :h_parser - #attach_function :h_repeat_n, [:h_parser, :size_t], :h_parser + attach_function :h_repeat_n, [:h_parser, :size_t], :h_parser attach_function :h_optional, [:h_parser], :h_parser attach_function :h_ignore, [:h_parser], :h_parser attach_function :h_sepBy, [:h_parser, :h_parser], :h_parser diff --git a/src/bindings/ruby/lib/hammer/parser.rb b/src/bindings/ruby/lib/hammer/parser.rb index b496558f..4d9f4325 100644 --- a/src/bindings/ruby/lib/hammer/parser.rb +++ b/src/bindings/ruby/lib/hammer/parser.rb @@ -25,7 +25,8 @@ module Hammer raise RuntimeError, '@h_parser is nil' if @h_parser.nil? raise ArgumentError, 'expecting a String' unless data.is_a? String # TODO: Not needed, FFI checks that. - result = Hammer::Internal.h_parse(@h_parser, data, data.bytesize) + ibuf = FFI::MemoryPointer.from_string(data) + result = Hammer::Internal.h_parse(@h_parser, ibuf, data.bytesize) # Don't include the trailing null if result.null? return nil else @@ -73,13 +74,54 @@ module Hammer return Hammer::Parser.new(:token, h_parser, buffer) end - def self.ch(num) - raise ArgumentError, 'expecting a Fixnum in 0..255' unless num.is_a?(Fixnum) and num.between?(0, 255) + def self.marshal_ch_arg(num) + if num.is_a?(String) + raise ArgumentError, "Expecting either a fixnum in 0..255 or a single-byte String" unless num.bytes.length == 1 + num = num.bytes[0] + end + raise ArgumentError, 'Expecting a Fixnum in 0..255 or a single-byte String' unless num.is_a?(Fixnum) and num.between?(0, 255) + return num + end + private_class_method :marshal_ch_arg + + def self.ch(ch) + num = marshal_ch_arg(ch) h_parser = Hammer::Internal.h_ch(num) return Hammer::Parser.new(:ch, h_parser, nil) end + def self.ch_range(ch1, ch2) + ch1 = marshal_ch_arg(ch1) + ch2 = marshal_ch_arg(ch2) + h_parser = Hammer::Internal.h_ch_range(ch1, ch2) + return Hammer::Parser.new(:ch_range, h_parser, nil) + end + + def self.int_range(parser, i1, i2) + h_parser = Hammer::Internal.h_int_range(parser.h_parser, i1, i2) + return Hammer::Parser.new(:int_range, h_parser, nil) + end + + def self.in(charset) + raise ArgumentError, "Expected a String" unless charset.is_a?(String) + ibuf = FFI::MemoryPointer.from_string(charset) + h_parser = Hammer::Internal.h_in(ibuf, charset.bytesize) + return Hammer::Parser.new(:in, h_parser, nil) + end + + def self.repeat_n(parser, count) + h_parser = Hammer::Internal.h_repeat_n(parser.h_parser, count) + return Hammer::Parser.new(:repeat_n, h_parser, nil) + end + + def self.not_in(charset) + raise ArgumentError, "Expected a String" unless charset.is_a?(String) + ibuf = FFI::MemoryPointer.from_string(charset) + h_parser = Hammer::Internal.h_not_in(ibuf, charset.bytesize) + return Hammer::Parser.new(:not_in, h_parser, nil) + end + # Defines a parser constructor with the given name. # Options: # hammer_function: name of the hammer function to call (default: 'h_'+name) diff --git a/src/bindings/ruby/lib/minitest/hamer-parser_plugin.rb b/src/bindings/ruby/lib/minitest/hamer-parser_plugin.rb index 393a540b..a23d8b9a 100644 --- a/src/bindings/ruby/lib/minitest/hamer-parser_plugin.rb +++ b/src/bindings/ruby/lib/minitest/hamer-parser_plugin.rb @@ -18,7 +18,10 @@ module Minitest def refute_parse_ok(parser, probe) refute_nil parser, "Parser must not be nil (this is a problem with your test)" parse_result = parser.parse(probe) - assert_nil parse_result, "Parse succeeded unexpectedly with " + parse_result.ast.inspect + + if not parse_result.nil? + assert_nil parse_result, "Parse succeeded unexpectedly with " + parse_result.ast.inspect + end end end diff --git a/src/bindings/ruby/test/autogen_test.rb b/src/bindings/ruby/test/autogen_test.rb index a2566bc0..93a0c7a5 100644 --- a/src/bindings/ruby/test/autogen_test.rb +++ b/src/bindings/ruby/test/autogen_test.rb @@ -13,7 +13,7 @@ class TestToken < Minitest::Test end def test_2 - refute_parse_ok @parser_1, "95\xa2" + refute_parse_ok @parser_1, "95\xa3" end end @@ -25,7 +25,7 @@ class TestCh < Minitest::Test end def test_1 - assert_parse_ok @parser_1, "\xa2", '\xa2' + assert_parse_ok @parser_1, "\xa2", 0xa2 end def test_2 @@ -41,7 +41,7 @@ class TestChRange < Minitest::Test end def test_1 - assert_parse_ok @parser_1, "b", 'b' + assert_parse_ok @parser_1, "b", 0x62 end def test_2 @@ -197,7 +197,7 @@ class TestIntRange < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.int_range(h.uint8, 0x3, 0x10) + @parser_1 = h.int_range(h.uint8, 0x3, 0xa) end def test_1 @@ -218,19 +218,19 @@ class TestWhitespace < Minitest::Test end def test_1 - assert_parse_ok @parser_1, "a", 'a' + assert_parse_ok @parser_1, "a", 0x61 end def test_2 - assert_parse_ok @parser_1, " a", 'a' + assert_parse_ok @parser_1, " a", 0x61 end def test_3 - assert_parse_ok @parser_1, " a", 'a' + assert_parse_ok @parser_1, " a", 0x61 end def test_4 - assert_parse_ok @parser_1, "\x09a", 'a' + assert_parse_ok @parser_1, "\x09a", 0x61 end def test_5 @@ -238,11 +238,11 @@ class TestWhitespace < Minitest::Test end def test_6 - assert_parse_ok @parser_2, "", null + assert_parse_ok @parser_2, "", nil end def test_7 - assert_parse_ok @parser_2, " ", null + assert_parse_ok @parser_2, " ", nil end def test_8 @@ -258,7 +258,7 @@ class TestLeft < Minitest::Test end def test_1 - assert_parse_ok @parser_1, "a ", 'a' + assert_parse_ok @parser_1, "a ", 0x61 end def test_2 @@ -278,11 +278,11 @@ class TestMiddle < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.middle(h.ch(' '), h.ch('a'), h.ch(' ')) + @parser_1 = h.middle(h.ch(0x20), h.ch(0x61), h.ch(0x20)) end def test_1 - assert_parse_ok @parser_1, " a ", 'a' + assert_parse_ok @parser_1, " a ", 0x61 end def test_2 @@ -318,7 +318,7 @@ class TestIn < Minitest::Test end def test_1 - assert_parse_ok @parser_1, "b", 'b' + assert_parse_ok @parser_1, "b", 0x62 end def test_2 @@ -334,7 +334,7 @@ class TestNotIn < Minitest::Test end def test_1 - assert_parse_ok @parser_1, "d", 'd' + assert_parse_ok @parser_1, "d", 0x64 end def test_2 @@ -346,11 +346,11 @@ class TestEndP < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.sequence(h.ch('a'), h.end_p) + @parser_1 = h.sequence(h.ch(0x61), h.end_p) end def test_1 - assert_parse_ok @parser_1, "a", ['a'] + assert_parse_ok @parser_1, "a", [0x61] end def test_2 @@ -374,12 +374,12 @@ class TestSequence < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.sequence(h.ch('a'), h.ch('b')) - @parser_2 = h.sequence(h.ch('a'), h.whitespace(h.ch('b'))) + @parser_1 = h.sequence(h.ch(0x61), h.ch(0x62)) + @parser_2 = h.sequence(h.ch(0x61), h.whitespace(h.ch(0x62))) end def test_1 - assert_parse_ok @parser_1, "ab", ['a', 'b'] + assert_parse_ok @parser_1, "ab", [0x61, 0x62] end def test_2 @@ -391,15 +391,15 @@ class TestSequence < Minitest::Test end def test_4 - assert_parse_ok @parser_2, "ab", ['a', 'b'] + assert_parse_ok @parser_2, "ab", [0x61, 0x62] end def test_5 - assert_parse_ok @parser_2, "a b", ['a', 'b'] + assert_parse_ok @parser_2, "a b", [0x61, 0x62] end def test_6 - assert_parse_ok @parser_2, "a b", ['a', 'b'] + assert_parse_ok @parser_2, "a b", [0x61, 0x62] end end @@ -407,19 +407,19 @@ class TestChoice < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.choice(h.ch('a'), h.ch('b')) + @parser_1 = h.choice(h.ch(0x61), h.ch(0x62)) end def test_1 - assert_parse_ok @parser_1, "a", 'a' + assert_parse_ok @parser_1, "a", 0x61 end def test_2 - assert_parse_ok @parser_1, "b", 'b' + assert_parse_ok @parser_1, "b", 0x62 end def test_3 - assert_parse_ok @parser_1, "ab", 'a' + assert_parse_ok @parser_1, "ab", 0x61 end def test_4 @@ -431,12 +431,12 @@ class TestButnot < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.butnot(h.ch('a'), h.token("ab")) - @parser_2 = h.butnot(h.ch_range('0', '9'), h.ch('6')) + @parser_1 = h.butnot(h.ch(0x61), h.token("ab")) + @parser_2 = h.butnot(h.ch_range(0x30, 0x39), h.ch(0x36)) end def test_1 - assert_parse_ok @parser_1, "a", 'a' + assert_parse_ok @parser_1, "a", 0x61 end def test_2 @@ -444,11 +444,11 @@ class TestButnot < Minitest::Test end def test_3 - assert_parse_ok @parser_1, "aa", 'a' + assert_parse_ok @parser_1, "aa", 0x61 end def test_4 - assert_parse_ok @parser_2, "5", '5' + assert_parse_ok @parser_2, "5", 0x35 end def test_5 @@ -460,7 +460,7 @@ class TestDifference < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.difference(h.token("ab"), h.ch('a')) + @parser_1 = h.difference(h.token("ab"), h.ch(0x61)) end def test_1 @@ -476,15 +476,15 @@ class TestXor < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.xor(h.ch_range('0', '6'), h.ch_range('5', '9')) + @parser_1 = h.xor(h.ch_range(0x30, 0x36), h.ch_range(0x35, 0x39)) end def test_1 - assert_parse_ok @parser_1, "0", '0' + assert_parse_ok @parser_1, "0", 0x30 end def test_2 - assert_parse_ok @parser_1, "9", '9' + assert_parse_ok @parser_1, "9", 0x39 end def test_3 @@ -500,7 +500,7 @@ class TestMany < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.many(h.choice(h.ch('a'), h.ch('b'))) + @parser_1 = h.many(h.choice(h.ch(0x61), h.ch(0x62))) end def test_1 @@ -508,15 +508,15 @@ class TestMany < Minitest::Test end def test_2 - assert_parse_ok @parser_1, "a", ['a'] + assert_parse_ok @parser_1, "a", [0x61] end def test_3 - assert_parse_ok @parser_1, "b", ['b'] + assert_parse_ok @parser_1, "b", [0x62] end def test_4 - assert_parse_ok @parser_1, "aabbaba", ['a', 'a', 'b', 'b', 'a', 'b', 'a'] + assert_parse_ok @parser_1, "aabbaba", [0x61, 0x61, 0x62, 0x62, 0x61, 0x62, 0x61] end end @@ -524,7 +524,7 @@ class TestMany1 < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.many1(h.choice(h.ch('a'), h.ch('b'))) + @parser_1 = h.many1(h.choice(h.ch(0x61), h.ch(0x62))) end def test_1 @@ -532,15 +532,15 @@ class TestMany1 < Minitest::Test end def test_2 - assert_parse_ok @parser_1, "a", ['a'] + assert_parse_ok @parser_1, "a", [0x61] end def test_3 - assert_parse_ok @parser_1, "b", ['b'] + assert_parse_ok @parser_1, "b", [0x62] end def test_4 - assert_parse_ok @parser_1, "aabbaba", ['a', 'a', 'b', 'b', 'a', 'b', 'a'] + assert_parse_ok @parser_1, "aabbaba", [0x61, 0x61, 0x62, 0x62, 0x61, 0x62, 0x61] end def test_5 @@ -552,7 +552,7 @@ class TestRepeatN < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.repeat_n(h.choice(h.ch('a'), h.ch('b')), 0x2) + @parser_1 = h.repeat_n(h.choice(h.ch(0x61), h.ch(0x62)), 0x2) end def test_1 @@ -560,7 +560,7 @@ class TestRepeatN < Minitest::Test end def test_2 - assert_parse_ok @parser_1, "abdef", ['a', 'b'] + assert_parse_ok @parser_1, "abdef", [0x61, 0x62] end def test_3 @@ -572,19 +572,19 @@ class TestOptional < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.sequence(h.ch('a'), h.optional(h.choice(h.ch('b'), h.ch('c'))), h.ch('d')) + @parser_1 = h.sequence(h.ch(0x61), h.optional(h.choice(h.ch(0x62), h.ch(0x63))), h.ch(0x64)) end def test_1 - assert_parse_ok @parser_1, "abd", ['a', 'b', 'd'] + assert_parse_ok @parser_1, "abd", [0x61, 0x62, 0x64] end def test_2 - assert_parse_ok @parser_1, "acd", ['a', 'c', 'd'] + assert_parse_ok @parser_1, "acd", [0x61, 0x63, 0x64] end def test_3 - assert_parse_ok @parser_1, "ad", ['a', null, 'd'] + assert_parse_ok @parser_1, "ad", [0x61, nil, 0x64] end def test_4 @@ -604,11 +604,11 @@ class TestIgnore < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.sequence(h.ch('a'), h.ignore(h.ch('b')), h.ch('c')) + @parser_1 = h.sequence(h.ch(0x61), h.ignore(h.ch(0x62)), h.ch(0x63)) end def test_1 - assert_parse_ok @parser_1, "abc", ['a', 'c'] + assert_parse_ok @parser_1, "abc", [0x61, 0x63] end def test_2 @@ -620,23 +620,23 @@ class TestSepBy < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.sepBy(h.choice(h.ch('1'), h.ch('2'), h.ch('3')), h.ch(',')) + @parser_1 = h.sepBy(h.choice(h.ch(0x31), h.ch(0x32), h.ch(0x33)), h.ch(0x2c)) end def test_1 - assert_parse_ok @parser_1, "1,2,3", ['1', '2', '3'] + assert_parse_ok @parser_1, "1,2,3", [0x31, 0x32, 0x33] end def test_2 - assert_parse_ok @parser_1, "1,3,2", ['1', '3', '2'] + assert_parse_ok @parser_1, "1,3,2", [0x31, 0x33, 0x32] end def test_3 - assert_parse_ok @parser_1, "1,3", ['1', '3'] + assert_parse_ok @parser_1, "1,3", [0x31, 0x33] end def test_4 - assert_parse_ok @parser_1, "3", ['3'] + assert_parse_ok @parser_1, "3", [0x33] end def test_5 @@ -648,23 +648,23 @@ class TestSepBy1 < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.sepBy1(h.choice(h.ch('1'), h.ch('2'), h.ch('3')), h.ch(',')) + @parser_1 = h.sepBy1(h.choice(h.ch(0x31), h.ch(0x32), h.ch(0x33)), h.ch(0x2c)) end def test_1 - assert_parse_ok @parser_1, "1,2,3", ['1', '2', '3'] + assert_parse_ok @parser_1, "1,2,3", [0x31, 0x32, 0x33] end def test_2 - assert_parse_ok @parser_1, "1,3,2", ['1', '3', '2'] + assert_parse_ok @parser_1, "1,3,2", [0x31, 0x33, 0x32] end def test_3 - assert_parse_ok @parser_1, "1,3", ['1', '3'] + assert_parse_ok @parser_1, "1,3", [0x31, 0x33] end def test_4 - assert_parse_ok @parser_1, "3", ['3'] + assert_parse_ok @parser_1, "3", [0x33] end def test_5 @@ -676,13 +676,13 @@ class TestAnd < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.sequence(h.and(h.ch('0')), h.ch('0')) - @parser_2 = h.sequence(h.and(h.ch('0')), h.ch('1')) - @parser_3 = h.sequence(h.ch('1'), h.and(h.ch('2'))) + @parser_1 = h.sequence(h.and(h.ch(0x30)), h.ch(0x30)) + @parser_2 = h.sequence(h.and(h.ch(0x30)), h.ch(0x31)) + @parser_3 = h.sequence(h.ch(0x31), h.and(h.ch(0x32))) end def test_1 - assert_parse_ok @parser_1, "0", ['0'] + assert_parse_ok @parser_1, "0", [0x30] end def test_2 @@ -698,7 +698,7 @@ class TestAnd < Minitest::Test end def test_5 - assert_parse_ok @parser_3, "12", ['1'] + assert_parse_ok @parser_3, "12", [0x31] end def test_6 @@ -710,12 +710,12 @@ class TestNot < Minitest::Test def setup super h = Hammer::Parser - @parser_1 = h.sequence(h.ch('a'), h.choice(h.token("+"), h.token("++")), h.ch('b')) - @parser_2 = h.sequence(h.ch('a'), h.choice(h.sequence(h.token("+"), h.not(h.ch('+'))), h.token("++")), h.ch('b')) + @parser_1 = h.sequence(h.ch(0x61), h.choice(h.token("+"), h.token("++")), h.ch(0x62)) + @parser_2 = h.sequence(h.ch(0x61), h.choice(h.sequence(h.token("+"), h.not(h.ch(0x2b))), h.token("++")), h.ch(0x62)) end def test_1 - assert_parse_ok @parser_1, "a+b", ['a', "+", 'b'] + assert_parse_ok @parser_1, "a+b", [0x61, "+", 0x62] end def test_2 @@ -723,11 +723,11 @@ class TestNot < Minitest::Test end def test_3 - assert_parse_ok @parser_2, "a+b", ['a', ["+"], 'b'] + assert_parse_ok @parser_2, "a+b", [0x61, ["+"], 0x62] end def test_4 - assert_parse_ok @parser_2, "a++b", ['a', "++", 'b'] + assert_parse_ok @parser_2, "a++b", [0x61, "++", 0x62] end end @@ -736,46 +736,20 @@ class TestRightrec < Minitest::Test super h = Hammer::Parser @sp_rr = h.indirect - @sp_rr.bind h.choice(h.sequence(h.ch('a'), @sp_rr), h.epsilon_p) + @sp_rr.bind h.choice(h.sequence(h.ch(0x61), @sp_rr), h.epsilon_p) @parser_1 = @sp_rr end def test_1 - assert_parse_ok @parser_1, "a", ['a'] + assert_parse_ok @parser_1, "a", [0x61] end def test_2 - assert_parse_ok @parser_1, "aa", ['a', ['a']] + assert_parse_ok @parser_1, "aa", [0x61, [0x61]] end def test_3 - assert_parse_ok @parser_1, "aaa", ['a', ['a', ['a']]] - end -end - -class TestAmbiguous < Minitest::Test - def setup - super - h = Hammer::Parser - @sp_d = h.indirect - @sp_p = h.indirect - @sp_e = h.indirect - @sp_d.bind h.ch('d') - @sp_p.bind h.ch('+') - @sp_e.bind h.choice(h.sequence(@sp_e, @sp_p, @sp_e), @sp_d) - @parser_1 = @sp_e - end - - def test_1 - assert_parse_ok @parser_1, "d", 'd' - end - - def test_2 - assert_parse_ok @parser_1, "d+d", ['d', '+', 'd'] - end - - def test_3 - assert_parse_ok @parser_1, "d+d+d", [['d', '+', 'd'], '+', 'd'] + assert_parse_ok @parser_1, "aaa", [0x61, [0x61, [0x61]]] end end -- GitLab