316 lines
14 KiB
C#
316 lines
14 KiB
C#
namespace Hammer.Test {
|
|
using NUnit.Framework;
|
|
[TestFixture]
|
|
public partial class HammerTest {
|
|
[Test]
|
|
public void TestToken() {
|
|
Parser parser;
|
|
parser = Hammer.Token("95\xa2");
|
|
CheckParseOK(parser, "95\xa2", new byte[]{ 0x39, 0x35, 0xa2});
|
|
CheckParseFail(parser, "95\xa2");
|
|
}
|
|
[Test]
|
|
public void TestCh() {
|
|
Parser parser;
|
|
parser = Hammer.Ch(0xa2);
|
|
CheckParseOK(parser, "\xa2", (System.UInt64)'\xa2');
|
|
CheckParseFail(parser, "\xa3");
|
|
}
|
|
[Test]
|
|
public void TestCh_range() {
|
|
Parser parser;
|
|
parser = Hammer.Ch_range(0x61, 0x63);
|
|
CheckParseOK(parser, "b", (System.UInt64)'b');
|
|
CheckParseFail(parser, "d");
|
|
}
|
|
[Test]
|
|
public void TestInt64() {
|
|
Parser parser;
|
|
parser = Hammer.Int64();
|
|
CheckParseOK(parser, "\xff\xff\xff\xfe\x00\x00\x00\x00", (System.Int64)(-0x200000000));
|
|
CheckParseFail(parser, "\xff\xff\xff\xfe\x00\x00\x00");
|
|
}
|
|
[Test]
|
|
public void TestInt32() {
|
|
Parser parser;
|
|
parser = Hammer.Int32();
|
|
CheckParseOK(parser, "\xff\xfe\x00\x00", (System.Int64)(-0x20000));
|
|
CheckParseFail(parser, "\xff\xfe\x00");
|
|
CheckParseOK(parser, "\x00\x02\x00\x00", (System.Int64)(0x20000));
|
|
CheckParseFail(parser, "\x00\x02\x00");
|
|
}
|
|
[Test]
|
|
public void TestInt16() {
|
|
Parser parser;
|
|
parser = Hammer.Int16();
|
|
CheckParseOK(parser, "\xfe\x00", (System.Int64)(-0x200));
|
|
CheckParseFail(parser, "\xfe");
|
|
CheckParseOK(parser, "\x02\x00", (System.Int64)(0x200));
|
|
CheckParseFail(parser, "\x02");
|
|
}
|
|
[Test]
|
|
public void TestInt8() {
|
|
Parser parser;
|
|
parser = Hammer.Int8();
|
|
CheckParseOK(parser, "\x88", (System.Int64)(-0x78));
|
|
CheckParseFail(parser, "");
|
|
}
|
|
[Test]
|
|
public void TestUint64() {
|
|
Parser parser;
|
|
parser = Hammer.Uint64();
|
|
CheckParseOK(parser, "\x00\x00\x00\x02\x00\x00\x00\x00", (System.UInt64)0x200000000);
|
|
CheckParseFail(parser, "\x00\x00\x00\x02\x00\x00\x00");
|
|
}
|
|
[Test]
|
|
public void TestUint32() {
|
|
Parser parser;
|
|
parser = Hammer.Uint32();
|
|
CheckParseOK(parser, "\x00\x02\x00\x00", (System.UInt64)0x20000);
|
|
CheckParseFail(parser, "\x00\x02\x00");
|
|
}
|
|
[Test]
|
|
public void TestUint16() {
|
|
Parser parser;
|
|
parser = Hammer.Uint16();
|
|
CheckParseOK(parser, "\x02\x00", (System.UInt64)0x200);
|
|
CheckParseFail(parser, "\x02");
|
|
}
|
|
[Test]
|
|
public void TestUint8() {
|
|
Parser parser;
|
|
parser = Hammer.Uint8();
|
|
CheckParseOK(parser, "x", (System.UInt64)0x78);
|
|
CheckParseFail(parser, "");
|
|
}
|
|
[Test]
|
|
public void TestInt_range() {
|
|
Parser parser;
|
|
parser = Hammer.Int_range(Hammer.Uint8(), 0x3, 0x10);
|
|
CheckParseOK(parser, "\x05", (System.UInt64)0x5);
|
|
CheckParseFail(parser, "\x0b");
|
|
}
|
|
[Test]
|
|
public void TestWhitespace() {
|
|
Parser parser;
|
|
parser = Hammer.Whitespace(Hammer.Ch(0x61));
|
|
CheckParseOK(parser, "a", (System.UInt64)'a');
|
|
CheckParseOK(parser, " a", (System.UInt64)'a');
|
|
CheckParseOK(parser, " a", (System.UInt64)'a');
|
|
CheckParseOK(parser, "\x09a", (System.UInt64)'a');
|
|
CheckParseFail(parser, "_a");
|
|
parser = Hammer.Whitespace(Hammer.End_p());
|
|
CheckParseOK(parser, "", null);
|
|
CheckParseOK(parser, " ", null);
|
|
CheckParseFail(parser, " x");
|
|
}
|
|
[Test]
|
|
public void TestLeft() {
|
|
Parser parser;
|
|
parser = Hammer.Left(Hammer.Ch(0x61), Hammer.Ch(0x20));
|
|
CheckParseOK(parser, "a ", (System.UInt64)'a');
|
|
CheckParseFail(parser, "a");
|
|
CheckParseFail(parser, " ");
|
|
CheckParseFail(parser, "ba");
|
|
}
|
|
[Test]
|
|
public void TestMiddle() {
|
|
Parser parser;
|
|
parser = Hammer.Middle(Hammer.Ch(' '), Hammer.Ch('a'), Hammer.Ch(' '));
|
|
CheckParseOK(parser, " a ", (System.UInt64)'a');
|
|
CheckParseFail(parser, "a");
|
|
CheckParseFail(parser, " a");
|
|
CheckParseFail(parser, "a ");
|
|
CheckParseFail(parser, " b ");
|
|
CheckParseFail(parser, "ba ");
|
|
CheckParseFail(parser, " ab");
|
|
}
|
|
[Test]
|
|
public void TestIn() {
|
|
Parser parser;
|
|
parser = Hammer.In("abc");
|
|
CheckParseOK(parser, "b", (System.UInt64)'b');
|
|
CheckParseFail(parser, "d");
|
|
}
|
|
[Test]
|
|
public void TestNot_in() {
|
|
Parser parser;
|
|
parser = Hammer.Not_in("abc");
|
|
CheckParseOK(parser, "d", (System.UInt64)'d');
|
|
CheckParseFail(parser, "a");
|
|
}
|
|
[Test]
|
|
public void TestEnd_p() {
|
|
Parser parser;
|
|
parser = Hammer.Sequence(Hammer.Ch('a'), Hammer.End_p());
|
|
CheckParseOK(parser, "a", new object[]{ (System.UInt64)'a'});
|
|
CheckParseFail(parser, "aa");
|
|
}
|
|
[Test]
|
|
public void TestNothing_p() {
|
|
Parser parser;
|
|
parser = Hammer.Nothing_p();
|
|
CheckParseFail(parser, "a");
|
|
}
|
|
[Test]
|
|
public void TestSequence() {
|
|
Parser parser;
|
|
parser = Hammer.Sequence(Hammer.Ch('a'), Hammer.Ch('b'));
|
|
CheckParseOK(parser, "ab", new object[]{ (System.UInt64)'a', (System.UInt64)'b'});
|
|
CheckParseFail(parser, "a");
|
|
CheckParseFail(parser, "b");
|
|
parser = Hammer.Sequence(Hammer.Ch('a'), Hammer.Whitespace(Hammer.Ch('b')));
|
|
CheckParseOK(parser, "ab", new object[]{ (System.UInt64)'a', (System.UInt64)'b'});
|
|
CheckParseOK(parser, "a b", new object[]{ (System.UInt64)'a', (System.UInt64)'b'});
|
|
CheckParseOK(parser, "a b", new object[]{ (System.UInt64)'a', (System.UInt64)'b'});
|
|
}
|
|
[Test]
|
|
public void TestChoice() {
|
|
Parser parser;
|
|
parser = Hammer.Choice(Hammer.Ch('a'), Hammer.Ch('b'));
|
|
CheckParseOK(parser, "a", (System.UInt64)'a');
|
|
CheckParseOK(parser, "b", (System.UInt64)'b');
|
|
CheckParseOK(parser, "ab", (System.UInt64)'a');
|
|
CheckParseFail(parser, "c");
|
|
}
|
|
[Test]
|
|
public void TestButnot() {
|
|
Parser parser;
|
|
parser = Hammer.Butnot(Hammer.Ch('a'), Hammer.Token("ab"));
|
|
CheckParseOK(parser, "a", (System.UInt64)'a');
|
|
CheckParseFail(parser, "ab");
|
|
CheckParseOK(parser, "aa", (System.UInt64)'a');
|
|
parser = Hammer.Butnot(Hammer.Ch_range('0', '9'), Hammer.Ch('6'));
|
|
CheckParseOK(parser, "5", (System.UInt64)'5');
|
|
CheckParseFail(parser, "6");
|
|
}
|
|
[Test]
|
|
public void TestDifference() {
|
|
Parser parser;
|
|
parser = Hammer.Difference(Hammer.Token("ab"), Hammer.Ch('a'));
|
|
CheckParseOK(parser, "ab", new byte[]{ 0x61, 0x62});
|
|
CheckParseFail(parser, "a");
|
|
}
|
|
[Test]
|
|
public void TestXor() {
|
|
Parser parser;
|
|
parser = Hammer.Xor(Hammer.Ch_range('0', '6'), Hammer.Ch_range('5', '9'));
|
|
CheckParseOK(parser, "0", (System.UInt64)'0');
|
|
CheckParseOK(parser, "9", (System.UInt64)'9');
|
|
CheckParseFail(parser, "5");
|
|
CheckParseFail(parser, "a");
|
|
}
|
|
[Test]
|
|
public void TestMany() {
|
|
Parser parser;
|
|
parser = Hammer.Many(Hammer.Choice(Hammer.Ch('a'), Hammer.Ch('b')));
|
|
CheckParseOK(parser, "", new object[]{ });
|
|
CheckParseOK(parser, "a", new object[]{ (System.UInt64)'a'});
|
|
CheckParseOK(parser, "b", new object[]{ (System.UInt64)'b'});
|
|
CheckParseOK(parser, "aabbaba", new object[]{ (System.UInt64)'a', (System.UInt64)'a', (System.UInt64)'b', (System.UInt64)'b', (System.UInt64)'a', (System.UInt64)'b', (System.UInt64)'a'});
|
|
}
|
|
[Test]
|
|
public void TestMany1() {
|
|
Parser parser;
|
|
parser = Hammer.Many1(Hammer.Choice(Hammer.Ch('a'), Hammer.Ch('b')));
|
|
CheckParseFail(parser, "");
|
|
CheckParseOK(parser, "a", new object[]{ (System.UInt64)'a'});
|
|
CheckParseOK(parser, "b", new object[]{ (System.UInt64)'b'});
|
|
CheckParseOK(parser, "aabbaba", new object[]{ (System.UInt64)'a', (System.UInt64)'a', (System.UInt64)'b', (System.UInt64)'b', (System.UInt64)'a', (System.UInt64)'b', (System.UInt64)'a'});
|
|
CheckParseFail(parser, "daabbabadef");
|
|
}
|
|
[Test]
|
|
public void TestRepeat_n() {
|
|
Parser parser;
|
|
parser = Hammer.Repeat_n(Hammer.Choice(Hammer.Ch('a'), Hammer.Ch('b')), 0x2);
|
|
CheckParseFail(parser, "adef");
|
|
CheckParseOK(parser, "abdef", new object[]{ (System.UInt64)'a', (System.UInt64)'b'});
|
|
CheckParseFail(parser, "dabdef");
|
|
}
|
|
[Test]
|
|
public void TestOptional() {
|
|
Parser parser;
|
|
parser = Hammer.Sequence(Hammer.Ch('a'), Hammer.Optional(Hammer.Choice(Hammer.Ch('b'), Hammer.Ch('c'))), Hammer.Ch('d'));
|
|
CheckParseOK(parser, "abd", new object[]{ (System.UInt64)'a', (System.UInt64)'b', (System.UInt64)'d'});
|
|
CheckParseOK(parser, "acd", new object[]{ (System.UInt64)'a', (System.UInt64)'c', (System.UInt64)'d'});
|
|
CheckParseOK(parser, "ad", new object[]{ (System.UInt64)'a', null, (System.UInt64)'d'});
|
|
CheckParseFail(parser, "aed");
|
|
CheckParseFail(parser, "ab");
|
|
CheckParseFail(parser, "ac");
|
|
}
|
|
[Test]
|
|
public void TestIgnore() {
|
|
Parser parser;
|
|
parser = Hammer.Sequence(Hammer.Ch('a'), Hammer.Ignore(Hammer.Ch('b')), Hammer.Ch('c'));
|
|
CheckParseOK(parser, "abc", new object[]{ (System.UInt64)'a', (System.UInt64)'c'});
|
|
CheckParseFail(parser, "ac");
|
|
}
|
|
[Test]
|
|
public void TestSepBy() {
|
|
Parser parser;
|
|
parser = Hammer.SepBy(Hammer.Choice(Hammer.Ch('1'), Hammer.Ch('2'), Hammer.Ch('3')), Hammer.Ch(','));
|
|
CheckParseOK(parser, "1,2,3", new object[]{ (System.UInt64)'1', (System.UInt64)'2', (System.UInt64)'3'});
|
|
CheckParseOK(parser, "1,3,2", new object[]{ (System.UInt64)'1', (System.UInt64)'3', (System.UInt64)'2'});
|
|
CheckParseOK(parser, "1,3", new object[]{ (System.UInt64)'1', (System.UInt64)'3'});
|
|
CheckParseOK(parser, "3", new object[]{ (System.UInt64)'3'});
|
|
CheckParseOK(parser, "", new object[]{ });
|
|
}
|
|
[Test]
|
|
public void TestSepBy1() {
|
|
Parser parser;
|
|
parser = Hammer.SepBy1(Hammer.Choice(Hammer.Ch('1'), Hammer.Ch('2'), Hammer.Ch('3')), Hammer.Ch(','));
|
|
CheckParseOK(parser, "1,2,3", new object[]{ (System.UInt64)'1', (System.UInt64)'2', (System.UInt64)'3'});
|
|
CheckParseOK(parser, "1,3,2", new object[]{ (System.UInt64)'1', (System.UInt64)'3', (System.UInt64)'2'});
|
|
CheckParseOK(parser, "1,3", new object[]{ (System.UInt64)'1', (System.UInt64)'3'});
|
|
CheckParseOK(parser, "3", new object[]{ (System.UInt64)'3'});
|
|
CheckParseFail(parser, "");
|
|
}
|
|
[Test]
|
|
public void TestAnd() {
|
|
Parser parser;
|
|
parser = Hammer.Sequence(Hammer.And(Hammer.Ch('0')), Hammer.Ch('0'));
|
|
CheckParseOK(parser, "0", new object[]{ (System.UInt64)'0'});
|
|
CheckParseFail(parser, "1");
|
|
parser = Hammer.Sequence(Hammer.And(Hammer.Ch('0')), Hammer.Ch('1'));
|
|
CheckParseFail(parser, "0");
|
|
CheckParseFail(parser, "1");
|
|
parser = Hammer.Sequence(Hammer.Ch('1'), Hammer.And(Hammer.Ch('2')));
|
|
CheckParseOK(parser, "12", new object[]{ (System.UInt64)'1'});
|
|
CheckParseFail(parser, "13");
|
|
}
|
|
[Test]
|
|
public void TestNot() {
|
|
Parser parser;
|
|
parser = Hammer.Sequence(Hammer.Ch('a'), Hammer.Choice(Hammer.Token("+"), Hammer.Token("++")), Hammer.Ch('b'));
|
|
CheckParseOK(parser, "a+b", new object[]{ (System.UInt64)'a', new byte[]{ 0x2b}, (System.UInt64)'b'});
|
|
CheckParseFail(parser, "a++b");
|
|
parser = Hammer.Sequence(Hammer.Ch('a'), Hammer.Choice(Hammer.Sequence(Hammer.Token("+"), Hammer.Not(Hammer.Ch('+'))), Hammer.Token("++")), Hammer.Ch('b'));
|
|
CheckParseOK(parser, "a+b", new object[]{ (System.UInt64)'a', new object[]{ new byte[]{ 0x2b}}, (System.UInt64)'b'});
|
|
CheckParseOK(parser, "a++b", new object[]{ (System.UInt64)'a', new byte[]{ 0x2b, 0x2b}, (System.UInt64)'b'});
|
|
}
|
|
[Test]
|
|
public void TestRightrec() {
|
|
Parser parser;
|
|
IndirectParser sp_rr = Hammer.Indirect();
|
|
sp_rr.Bind(Hammer.Choice(Hammer.Sequence(Hammer.Ch('a'), sp_rr), Hammer.Epsilon_p()));
|
|
parser = sp_rr;
|
|
CheckParseOK(parser, "a", new object[]{ (System.UInt64)'a'});
|
|
CheckParseOK(parser, "aa", new object[]{ (System.UInt64)'a', new object[]{ (System.UInt64)'a'}});
|
|
CheckParseOK(parser, "aaa", new object[]{ (System.UInt64)'a', new object[]{ (System.UInt64)'a', new object[]{ (System.UInt64)'a'}}});
|
|
}
|
|
[Test]
|
|
public void TestAmbiguous() {
|
|
Parser parser;
|
|
IndirectParser sp_d = Hammer.Indirect();
|
|
IndirectParser sp_p = Hammer.Indirect();
|
|
IndirectParser sp_e = Hammer.Indirect();
|
|
sp_d.Bind(Hammer.Ch('d'));
|
|
sp_p.Bind(Hammer.Ch('+'));
|
|
sp_e.Bind(Hammer.Choice(Hammer.Sequence(sp_e, sp_p, sp_e), sp_d));
|
|
parser = sp_e;
|
|
CheckParseOK(parser, "d", (System.UInt64)'d');
|
|
CheckParseOK(parser, "d+d", new object[]{ (System.UInt64)'d', (System.UInt64)'+', (System.UInt64)'d'});
|
|
CheckParseOK(parser, "d+d+d", new object[]{ new object[]{ (System.UInt64)'d', (System.UInt64)'+', (System.UInt64)'d'}, (System.UInt64)'+', (System.UInt64)'d'});
|
|
}
|
|
}
|
|
}
|