Test suite now builds
This commit is contained in:
parent
ee751a97c1
commit
14a5c5c1ef
9 changed files with 639 additions and 14 deletions
6
HACKING
6
HACKING
|
|
@ -59,4 +59,8 @@ There is a language-independent representation of the Hammer test
|
||||||
suite in `lib/test-suite`. This is intended to be used with the
|
suite in `lib/test-suite`. This is intended to be used with the
|
||||||
tsparser.pl prolog library, along with a language-specific frontend.
|
tsparser.pl prolog library, along with a language-specific frontend.
|
||||||
|
|
||||||
No language-specific frontends have been written yet.
|
Only the C# frontend exists so far; to regenerate the test suites using it, run
|
||||||
|
|
||||||
|
$ swipl -q -t halt -g tsgencsharp:prolog tsgencsharp.pl \
|
||||||
|
>../src/bindings/dotnet/test/hammer_tests.cs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ many1 {
|
||||||
test "daabbabadef" --> fail;
|
test "daabbabadef" --> fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
repeat-n {
|
repeat_n {
|
||||||
parser repeat_n(choice(ch('a'),ch('b')),0x2);
|
parser repeat_n(choice(ch('a'),ch('b')),0x2);
|
||||||
test "adef" --> fail;
|
test "adef" --> fail;
|
||||||
test "abdef" --> ['a','b'];
|
test "abdef" --> ['a','b'];
|
||||||
|
|
@ -270,11 +270,11 @@ and {
|
||||||
}
|
}
|
||||||
|
|
||||||
not {
|
not {
|
||||||
parser sequence(ch('a'), choice(token('+'), token("++")), ch('b'));
|
parser sequence(ch('a'), choice(token("+"), token("++")), ch('b'));
|
||||||
test "a+b" --> ['a',"+",'b'];
|
test "a+b" --> ['a',"+",'b'];
|
||||||
test "a++b" --> fail;
|
test "a++b" --> fail;
|
||||||
|
|
||||||
parser sequence(ch('a'), choice(sequence(token('+'), not(ch('+'))),
|
parser sequence(ch('a'), choice(sequence(token("+"), not(ch('+'))),
|
||||||
token("++")),
|
token("++")),
|
||||||
ch('b'));
|
ch('b'));
|
||||||
test "a+b" --> ['a', ["+"], 'b'];
|
test "a+b" --> ['a', ["+"], 'b'];
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ pp_test_elem(exec, parser(P)) -->
|
||||||
";\n".
|
";\n".
|
||||||
pp_test_elem(decl, subparser(Name,_)) -->
|
pp_test_elem(decl, subparser(Name,_)) -->
|
||||||
!, indent(3),
|
!, indent(3),
|
||||||
"Hammer.Parser ", pp_parser(ref(Name)),
|
"IndirectParser ", pp_parser(ref(Name)),
|
||||||
" = Hammer.Indirect();\n".
|
" = Hammer.Indirect();\n".
|
||||||
pp_test_elem(init, subparser(Name, Parser)) -->
|
pp_test_elem(init, subparser(Name, Parser)) -->
|
||||||
!, indent(3),
|
!, indent(3),
|
||||||
|
|
@ -160,7 +160,7 @@ pp_parse_result(none) --> !,
|
||||||
pp_parse_result(uint(V)) --> !,
|
pp_parse_result(uint(V)) --> !,
|
||||||
"(System.UInt64)", pp_parser(num(V)).
|
"(System.UInt64)", pp_parser(num(V)).
|
||||||
pp_parse_result(sint(V)) --> !,
|
pp_parse_result(sint(V)) --> !,
|
||||||
"(System.Int64)", pp_parser(num(V)).
|
"(System.Int64)(", pp_parser(num(V)), ")".
|
||||||
pp_parse_result(string(A)) --> !,
|
pp_parse_result(string(A)) --> !,
|
||||||
"new byte[]{ ", pp_byte_seq(A), "}".
|
"new byte[]{ ", pp_byte_seq(A), "}".
|
||||||
%pp_parse_result(A) -->
|
%pp_parse_result(A) -->
|
||||||
|
|
@ -180,8 +180,8 @@ pp_test_case(testcase(Name, Elems)) -->
|
||||||
!,
|
!,
|
||||||
indent(2), "[Test]\n",
|
indent(2), "[Test]\n",
|
||||||
{ format_test_name(Name, TName) },
|
{ format_test_name(Name, TName) },
|
||||||
indent(2), "public void ", TName, " {\n",
|
indent(2), "public void ", TName, "() {\n",
|
||||||
indent(3), "Hammer.Parser parser;\n",
|
indent(3), "Parser parser;\n",
|
||||||
pp_test_elems(decl, Elems),
|
pp_test_elems(decl, Elems),
|
||||||
pp_test_elems(init, Elems),
|
pp_test_elems(init, Elems),
|
||||||
pp_test_elems(exec, Elems),
|
pp_test_elems(exec, Elems),
|
||||||
|
|
@ -196,6 +196,7 @@ pp_test_cases([A|As]) -->
|
||||||
pp_test_suite(Suite) -->
|
pp_test_suite(Suite) -->
|
||||||
"namespace Hammer.Test {\n",
|
"namespace Hammer.Test {\n",
|
||||||
indent(1), "using NUnit.Framework;\n",
|
indent(1), "using NUnit.Framework;\n",
|
||||||
|
%indent(1), "using Hammer;\n",
|
||||||
indent(1), "[TestFixture]\n",
|
indent(1), "[TestFixture]\n",
|
||||||
indent(1), "public partial class HammerTest {\n",
|
indent(1), "public partial class HammerTest {\n",
|
||||||
pp_test_cases(Suite),
|
pp_test_cases(Suite),
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,13 @@ dotnettestenv = dotnetenv.Clone()
|
||||||
|
|
||||||
#dotnettestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0]))
|
#dotnettestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0]))
|
||||||
#dotnettests = ['t/hammer.t']
|
#dotnettests = ['t/hammer.t']
|
||||||
dotnettestenv.Append(CILLIBS=['/usr/lib/cli/nunit.core-2.6/nunit.core.dll','/usr/lib/cli/nunit.util-2.6/nunit.util.dll','/usr/lib/cli/nunit.framework-2.6/nunit.framework.dll','/usr/lib/cli/nunit.core.interfaces-2.6/nunit.core.interfaces.dll',str(hammer_dll[0])])
|
dotnettestenv.Append(CILLIBS=['/usr/lib/cli/nunit.core-2.6/nunit.core.dll','/usr/lib/cli/nunit.util-2.6/nunit.util.dll','/usr/lib/cli/nunit.framework-2.6/nunit.framework.dll','/usr/lib/cli/nunit.core.interfaces-2.6/nunit.core.interfaces.dll', "src/bindings/dotnet/hammer.dll"])
|
||||||
dotnettestlib = dotnettestenv.CLILibrary('hammer_test.dll', Glob('test/*.cs'))
|
dotnettestlib = dotnettestenv.CLILibrary('hammer_test.dll', Glob('test/*.cs'))
|
||||||
#dotnettestexec = dotnettestenv.Command(None, dotnettests + libhammer_dotnet + libhammer_shared, "make test -C " + targetdir)
|
Depends(dotnettestlib, hammer_dll)
|
||||||
#dotnettest = Alias("testdotnet", [dotnettestexec], dotnettestexec)
|
|
||||||
#AlwaysBuild(dotnettestexec)
|
dotnettestexec = dotnettestenv.Command(None, dotnettestlib, "nunit-console $SOURCE")
|
||||||
|
dotnettest = Alias("testdotnet", [dotnettestexec], dotnettestexec)
|
||||||
|
AlwaysBuild(dotnettestexec)
|
||||||
testruns.append(dotnettestlib)
|
testruns.append(dotnettestlib)
|
||||||
|
|
||||||
#dotnetinstallexec = dotnetenv.Command(None, libhammer_dotnet, "make install -C " + targetdir)
|
#dotnetinstallexec = dotnetenv.Command(None, libhammer_dotnet, "make install -C " + targetdir)
|
||||||
|
|
|
||||||
270
src/bindings/dotnet/ext/hammer.cs
Normal file
270
src/bindings/dotnet/ext/hammer.cs
Normal file
|
|
@ -0,0 +1,270 @@
|
||||||
|
using Hammer.Internal;
|
||||||
|
using System;
|
||||||
|
namespace Hammer
|
||||||
|
{
|
||||||
|
|
||||||
|
public class Parser
|
||||||
|
{
|
||||||
|
internal HParser wrapped;
|
||||||
|
internal System.Collections.IList pins; // objects that need to stay in scope for this one
|
||||||
|
internal Parser(HParser parser)
|
||||||
|
{
|
||||||
|
wrapped = parser;
|
||||||
|
pins = new System.Collections.ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Parser Pin(Object o)
|
||||||
|
{
|
||||||
|
pins.Add(o);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object Parse(byte[] str)
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
fixed(byte* b = &str[0]) {
|
||||||
|
HParseResult res = hammer.h_parse(wrapped, (IntPtr)b, (uint)str.Length);
|
||||||
|
if (res != null) {
|
||||||
|
return Unmarshal(res.ast);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Object Unmarshal(HParsedToken tok)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return new Object();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IndirectParser : Parser
|
||||||
|
{
|
||||||
|
internal IndirectParser(HParser parser)
|
||||||
|
: base(parser)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Bind(Parser p)
|
||||||
|
{
|
||||||
|
hammer.h_bind_indirect(this.wrapped, p.wrapped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Hammer
|
||||||
|
{
|
||||||
|
internal static IntPtr[] BuildParserArray(Parser[] parsers)
|
||||||
|
{
|
||||||
|
IntPtr[] rlist = new IntPtr[parsers.Length+1];
|
||||||
|
for (int i = 0; i < parsers.Length; i++)
|
||||||
|
{
|
||||||
|
rlist[i] = HParser.getCPtr(parsers[i].wrapped).Handle;
|
||||||
|
}
|
||||||
|
rlist[parsers.Length] = IntPtr.Zero;
|
||||||
|
return rlist;
|
||||||
|
}
|
||||||
|
public static Parser Sequence(params Parser[] parsers)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
IntPtr[] plist = BuildParserArray(parsers);
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (IntPtr *pp = &plist[0])
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_sequence__a((IntPtr)pp)).Pin(parsers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Choice(params Parser[] parsers)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
IntPtr[] plist = BuildParserArray(parsers);
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (IntPtr *pp = &plist[0])
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_choice__a((IntPtr)pp)).Pin(parsers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IndirectParser Indirect()
|
||||||
|
{
|
||||||
|
return new IndirectParser(hammer.h_indirect());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Ch(byte ch)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_ch(ch));
|
||||||
|
|
||||||
|
}
|
||||||
|
public static Parser Ch(char ch)
|
||||||
|
{
|
||||||
|
return Ch((byte)ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Ch_range(byte c1, byte c2)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_ch_range(c1, c2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Ch_range(char c1, char c2)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_ch_range((byte)c1, (byte)c2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Int_range(Parser p, System.Int64 i1, System.Int64 i2)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_int_range(p.wrapped, i1, i2));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Token(byte[] token)
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
fixed(byte* b = &token[0])
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_token((IntPtr)b, (uint)token.Length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser In(byte[] charset)
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
fixed(byte* b = &charset[0])
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_in((IntPtr)b, (uint)charset.Length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Not_in(byte[] charset)
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
fixed(byte* b = &charset[0])
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_not_in((IntPtr)b, (uint)charset.Length));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Token(string token)
|
||||||
|
{
|
||||||
|
// Encodes in UTF-8
|
||||||
|
return Token(System.Text.Encoding.UTF8.GetBytes(token));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser In(string charset)
|
||||||
|
{
|
||||||
|
// Encodes in UTF-8
|
||||||
|
return In(System.Text.Encoding.UTF8.GetBytes(charset));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Not_in(string charset)
|
||||||
|
{
|
||||||
|
// Encodes in UTF-8
|
||||||
|
return Not_in(System.Text.Encoding.UTF8.GetBytes(charset));
|
||||||
|
}
|
||||||
|
|
||||||
|
// No-arg parsers
|
||||||
|
public static Parser Int8() {return new Parser(hammer.h_int8());}
|
||||||
|
public static Parser Int16() {return new Parser(hammer.h_int16());}
|
||||||
|
public static Parser Int32() {return new Parser(hammer.h_int32());}
|
||||||
|
public static Parser Int64() {return new Parser(hammer.h_int64());}
|
||||||
|
public static Parser Uint8() {return new Parser(hammer.h_uint8());}
|
||||||
|
public static Parser Uint16() {return new Parser(hammer.h_uint16());}
|
||||||
|
public static Parser Uint32() {return new Parser(hammer.h_uint32());}
|
||||||
|
public static Parser Uint64() {return new Parser(hammer.h_uint64());}
|
||||||
|
|
||||||
|
public static Parser End_p() {return new Parser(hammer.h_end_p());}
|
||||||
|
public static Parser Nothing_p() {return new Parser(hammer.h_nothing_p());}
|
||||||
|
public static Parser Epsilon_p() {return new Parser(hammer.h_epsilon_p());}
|
||||||
|
|
||||||
|
|
||||||
|
// 1-arg parsers
|
||||||
|
public static Parser Ignore(Parser p)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_ignore(p.wrapped));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Not(Parser p)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_not(p.wrapped));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Whitespace(Parser p)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_whitespace(p.wrapped));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Optional(Parser p)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_optional(p.wrapped));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser And(Parser p)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_and(p.wrapped));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Many(Parser p)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_many(p.wrapped));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser Many1(Parser p)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_many1(p.wrapped));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser SepBy(Parser p, Parser sep)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_sepBy(p.wrapped, sep.wrapped));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parser SepBy1(Parser p, Parser sep)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_sepBy1(p.wrapped, sep.wrapped));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2-arg parsers
|
||||||
|
|
||||||
|
public static Parser Left(Parser p1, Parser p2)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_left(p1.wrapped, p2.wrapped));
|
||||||
|
}
|
||||||
|
public static Parser Right(Parser p1, Parser p2)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_right(p1.wrapped, p2.wrapped));
|
||||||
|
}
|
||||||
|
public static Parser Xor(Parser p1, Parser p2)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_xor(p1.wrapped, p2.wrapped));
|
||||||
|
}
|
||||||
|
public static Parser Difference(Parser p1, Parser p2)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_difference(p1.wrapped, p2.wrapped));
|
||||||
|
}
|
||||||
|
public static Parser Butnot(Parser p1, Parser p2)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_butnot(p1.wrapped, p2.wrapped));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Multi-arg parsers
|
||||||
|
public static Parser Middle(Parser p1, Parser p2, Parser p3)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_middle(p1.wrapped, p2.wrapped, p3.wrapped));
|
||||||
|
}
|
||||||
|
public static Parser Repeat_n(Parser p, uint count)
|
||||||
|
{
|
||||||
|
return new Parser(hammer.h_repeat_n(p.wrapped, count));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -9,9 +9,9 @@
|
||||||
// h_not_in
|
// h_not_in
|
||||||
|
|
||||||
//%typemap(cstype) uint8_t* "byte[]"
|
//%typemap(cstype) uint8_t* "byte[]"
|
||||||
%typemap(imtype) uint8_t* "IntPtr"
|
|
||||||
//%typemap(csin, pre="unsafe { fixed(byte* temp$csinput = &$csinput[0]) {", terminator="}}") uint8_t* "(IntPtr)temp$csinput"
|
//%typemap(csin, pre="unsafe { fixed(byte* temp$csinput = &$csinput[0]) {", terminator="}}") uint8_t* "(IntPtr)temp$csinput"
|
||||||
//%typemap(csvarin) uint8_t
|
//%typemap(csvarin) uint8_t
|
||||||
|
%typemap(imtype) uint8_t* "IntPtr"
|
||||||
%typemap(cstype) uint8_t* "IntPtr"
|
%typemap(cstype) uint8_t* "IntPtr"
|
||||||
%typemap(csin) uint8_t* "$csinput"
|
%typemap(csin) uint8_t* "$csinput"
|
||||||
%typemap(csvarout) uint8_t* %{
|
%typemap(csvarout) uint8_t* %{
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
%typemap(imtype) void*[] "IntPtr"
|
||||||
|
%typemap(cstype) void*[] "IntPtr"
|
||||||
|
%typemap(csin) void*[] "$csinput"
|
||||||
|
|
||||||
%ignore h_bit_writer_get_buffer;
|
%ignore h_bit_writer_get_buffer;
|
||||||
%apply (char *STRING, size_t LENGTH) {(uint8_t* str, size_t len)};
|
%apply (char *STRING, size_t LENGTH) {(uint8_t* str, size_t len)};
|
||||||
%apply (uint8_t* str, size_t len) {(const uint8_t* input, size_t length)}
|
%apply (uint8_t* str, size_t len) {(const uint8_t* input, size_t length)}
|
||||||
|
|
|
||||||
326
src/bindings/dotnet/test/hammer_tests.cs
Normal file
326
src/bindings/dotnet/test/hammer_tests.cs
Normal file
|
|
@ -0,0 +1,326 @@
|
||||||
|
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.Char)'\xa2');
|
||||||
|
CheckParseFail(parser, "\xa3");
|
||||||
|
}
|
||||||
|
[Test]
|
||||||
|
public void TestCh_range() {
|
||||||
|
Parser parser;
|
||||||
|
parser = Hammer.Ch_range(0x61, 0x63);
|
||||||
|
CheckParseOK(parser, "b", (System.Char)'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.Char)'a');
|
||||||
|
CheckParseOK(parser, " a", (System.Char)'a');
|
||||||
|
CheckParseOK(parser, " a", (System.Char)'a');
|
||||||
|
CheckParseOK(parser, "\x09a", (System.Char)'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.Char)'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.Char)'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.Char)'b');
|
||||||
|
CheckParseFail(parser, "d");
|
||||||
|
}
|
||||||
|
[Test]
|
||||||
|
public void TestNot_in() {
|
||||||
|
Parser parser;
|
||||||
|
parser = Hammer.Not_in("abc");
|
||||||
|
CheckParseOK(parser, "d", (System.Char)'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.Char)'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.Char)'a', (System.Char)'b'});
|
||||||
|
CheckParseFail(parser, "a");
|
||||||
|
CheckParseFail(parser, "b");
|
||||||
|
parser = Hammer.Sequence(Hammer.Ch('a'), Hammer.Whitespace(Hammer.Ch('b')));
|
||||||
|
CheckParseOK(parser, "ab", new object[]{ (System.Char)'a', (System.Char)'b'});
|
||||||
|
CheckParseOK(parser, "a b", new object[]{ (System.Char)'a', (System.Char)'b'});
|
||||||
|
CheckParseOK(parser, "a b", new object[]{ (System.Char)'a', (System.Char)'b'});
|
||||||
|
}
|
||||||
|
[Test]
|
||||||
|
public void TestChoice() {
|
||||||
|
Parser parser;
|
||||||
|
parser = Hammer.Choice(Hammer.Ch('a'), Hammer.Ch('b'));
|
||||||
|
CheckParseOK(parser, "a", (System.Char)'a');
|
||||||
|
CheckParseOK(parser, "b", (System.Char)'b');
|
||||||
|
CheckParseOK(parser, "ab", (System.Char)'a');
|
||||||
|
CheckParseFail(parser, "c");
|
||||||
|
}
|
||||||
|
[Test]
|
||||||
|
public void TestButnot() {
|
||||||
|
Parser parser;
|
||||||
|
parser = Hammer.Butnot(Hammer.Ch('a'), Hammer.Token("ab"));
|
||||||
|
CheckParseOK(parser, "a", (System.Char)'a');
|
||||||
|
CheckParseFail(parser, "ab");
|
||||||
|
CheckParseOK(parser, "aa", (System.Char)'a');
|
||||||
|
parser = Hammer.Butnot(Hammer.Ch_range('0', '9'), Hammer.Ch('6'));
|
||||||
|
CheckParseOK(parser, "5", (System.Char)'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.Char)'0');
|
||||||
|
CheckParseOK(parser, "9", (System.Char)'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.Char)'a'});
|
||||||
|
CheckParseOK(parser, "b", new object[]{ (System.Char)'b'});
|
||||||
|
CheckParseOK(parser, "aabbaba", new object[]{ (System.Char)'a', (System.Char)'a', (System.Char)'b', (System.Char)'b', (System.Char)'a', (System.Char)'b', (System.Char)'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.Char)'a'});
|
||||||
|
CheckParseOK(parser, "b", new object[]{ (System.Char)'b'});
|
||||||
|
CheckParseOK(parser, "aabbaba", new object[]{ (System.Char)'a', (System.Char)'a', (System.Char)'b', (System.Char)'b', (System.Char)'a', (System.Char)'b', (System.Char)'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.Char)'a', (System.Char)'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.Char)'a', (System.Char)'b', (System.Char)'d'});
|
||||||
|
CheckParseOK(parser, "acd", new object[]{ (System.Char)'a', (System.Char)'c', (System.Char)'d'});
|
||||||
|
CheckParseOK(parser, "ad", new object[]{ (System.Char)'a', null, (System.Char)'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.Char)'a', (System.Char)'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.Char)'1', (System.Char)'2', (System.Char)'3'});
|
||||||
|
CheckParseOK(parser, "1,3,2", new object[]{ (System.Char)'1', (System.Char)'3', (System.Char)'2'});
|
||||||
|
CheckParseOK(parser, "1,3", new object[]{ (System.Char)'1', (System.Char)'3'});
|
||||||
|
CheckParseOK(parser, "3", new object[]{ (System.Char)'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.Char)'1', (System.Char)'2', (System.Char)'3'});
|
||||||
|
CheckParseOK(parser, "1,3,2", new object[]{ (System.Char)'1', (System.Char)'3', (System.Char)'2'});
|
||||||
|
CheckParseOK(parser, "1,3", new object[]{ (System.Char)'1', (System.Char)'3'});
|
||||||
|
CheckParseOK(parser, "3", new object[]{ (System.Char)'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.Char)'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.Char)'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.Char)'a', new byte[]{ 0x2b}, (System.Char)'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.Char)'a', new object[]{ new byte[]{ 0x2b}}, (System.Char)'b'});
|
||||||
|
CheckParseOK(parser, "a++b", new object[]{ (System.Char)'a', new byte[]{ 0x2b, 0x2b}, (System.Char)'b'});
|
||||||
|
}
|
||||||
|
[Test]
|
||||||
|
public void TestLeftrec() {
|
||||||
|
Parser parser;
|
||||||
|
IndirectParser sp_lr = Hammer.Indirect();
|
||||||
|
sp_lr.Bind(Hammer.Choice(Hammer.Sequence(sp_lr, Hammer.Ch('a')), Hammer.Epsilon_p()));
|
||||||
|
parser = sp_lr;
|
||||||
|
CheckParseOK(parser, "a", new object[]{ (System.Char)'a'});
|
||||||
|
CheckParseOK(parser, "aa", new object[]{ new object[]{ (System.Char)'a'}, (System.Char)'a'});
|
||||||
|
CheckParseOK(parser, "aaa", new object[]{ new object[]{ new object[]{ (System.Char)'a'}, (System.Char)'a'}, (System.Char)'a'});
|
||||||
|
}
|
||||||
|
[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.Char)'a'});
|
||||||
|
CheckParseOK(parser, "aa", new object[]{ (System.Char)'a', new object[]{ (System.Char)'a'}});
|
||||||
|
CheckParseOK(parser, "aaa", new object[]{ (System.Char)'a', new object[]{ (System.Char)'a', new object[]{ (System.Char)'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.Char)'d');
|
||||||
|
CheckParseOK(parser, "d+d", new object[]{ (System.Char)'d', (System.Char)'+', (System.Char)'d'});
|
||||||
|
CheckParseOK(parser, "d+d+d", new object[]{ new object[]{ (System.Char)'d', (System.Char)'+', (System.Char)'d'}, (System.Char)'+', (System.Char)'d'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/bindings/dotnet/test/test_support.cs
Normal file
18
src/bindings/dotnet/test/test_support.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using Hammer;
|
||||||
|
namespace Hammer.Test
|
||||||
|
{
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
public partial class HammerTest
|
||||||
|
{
|
||||||
|
protected void CheckParseOK(Parser p, string probe, Object expected)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
protected void CheckParseFail(Parser p, string probe)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -45,7 +45,7 @@ def generate(env):
|
||||||
env['BUILDERS']['CLIProgram'] = McsBuilder
|
env['BUILDERS']['CLIProgram'] = McsBuilder
|
||||||
env['BUILDERS']['CLILibrary'] = McsLibBuilder
|
env['BUILDERS']['CLILibrary'] = McsLibBuilder
|
||||||
|
|
||||||
env['CSC'] = 'gmcs'
|
env['CSC'] = 'mcs'
|
||||||
env['_CSCLIBS'] = "${_stripixes('-r:', CILLIBS, '', '-r', '', __env__)}"
|
env['_CSCLIBS'] = "${_stripixes('-r:', CILLIBS, '', '-r', '', __env__)}"
|
||||||
env['_CSCLIBPATH'] = "${_stripixes('-lib:', CILLIBPATH, '', '-r', '', __env__)}"
|
env['_CSCLIBPATH'] = "${_stripixes('-lib:', CILLIBPATH, '', '-r', '', __env__)}"
|
||||||
env['CSCFLAGS'] = SCons.Util.CLVar('')
|
env['CSCFLAGS'] = SCons.Util.CLVar('')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue