All of the main test suite works
This commit is contained in:
parent
6a35872470
commit
753120f27e
6 changed files with 169 additions and 130 deletions
|
|
@ -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'];
|
||||
#}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)) --> !,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue