Skip to content

Commit 49de5a2

Browse files
authored
Merge pull request #571 from vrurg/6d_prep_issue_9
Add tests for 6.e Grammar Take into account: 1. `.parse` now returns `Failure` on fail 2. The `Failure` contains `X::Syntax::Confused` exception object Related to rakudo/rakudo#3103
2 parents 1570e03 + de269b5 commit 49de5a2

File tree

4 files changed

+123
-4
lines changed

4 files changed

+123
-4
lines changed

S05-grammar/methods.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use v6;
1+
use v6.c;
22
use Test;
33

44
plan 8;

S05-grammar/parse_and_parsefile.t renamed to S05-grammar/parse_and_parsefile-6c.t

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use v6;
1+
use v6.c;
22
use Test;
33

44
plan 17;
@@ -9,7 +9,7 @@ grammar Foo { token TOP { \d+ } }
99
grammar Bar { token untop { \d+ } }
1010
grammar Baz { token TOP { \d+ \n } }
1111

12-
nok(Foo.parse("abc123xyz"), ".parse method invokes TOP rule, no match");
12+
is Foo.parse("abc123xyz"), Nil, ".parse method invokes TOP rule, no match";
1313
is(~Foo.parse("123"), "123", ".parse method invokes TOP rule, match");
1414
nok(Foo.parse("123xyz"), ".parse method requires match to end");
1515
is(~Foo.subparse("123xyz"), "123", ".subparse method doesn't require match to end");

S05-grammar/parse_and_parsefile-6e.t

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
use v6.e.PREVIEW;
2+
use Test;
3+
4+
plan 24;
5+
6+
# tests .parse and .parsefile methods on a grammar
7+
8+
grammar Foo { token TOP { \d+ } }
9+
grammar Bar { token untop { \d+ } }
10+
grammar Baz { token TOP { \d+ \n } }
11+
12+
my Mu \parent = Foo.^mro.first( *.^name eq 'Grammar' );
13+
is parent.^ver, '6.e', 'grammar is created using 6.e version of Grammar class';
14+
15+
ok Foo.parse("abc123xyz") ~~ Failure, ".parse method invokes TOP rule, no match";
16+
is(~Foo.parse("123"), "123", ".parse method invokes TOP rule, match");
17+
nok(Foo.parse("123xyz"), ".parse method requires match to end");
18+
is(~Foo.subparse("123xyz"), "123", ".subparse method doesn't require match to end");
19+
dies-ok({ Bar.parse("abc123xyz") }, "dies if no TOP rule");
20+
21+
22+
#?rakudo.js.browser skip 'writing to a file is not supported in the browser'
23+
{
24+
my $fh = open("parse_and_parsefile_test", :w);
25+
$fh.say("abc\n123\nxyz");
26+
$fh.close();
27+
nok(Foo.parsefile("parse_and_parsefile_test"), ".parsefile method invokes TOP rule, no match");
28+
unlink("parse_and_parsefile_test");
29+
30+
$fh = open("parse_and_parsefile_test", :w);
31+
$fh.say("123");
32+
$fh.close();
33+
is(~Baz.parsefile("parse_and_parsefile_test"), "123\n", ".parsefile method invokes TOP rule, match");
34+
dies-ok({ Bar.parsefile("parse_and_parsefile_test") }, "dies if no TOP rule");
35+
dies-ok({ Foo.parsefile("non_existent_file") }, "dies if file not found");
36+
37+
unlink("parse_and_parsefile_test");
38+
}
39+
40+
41+
grammar A::B {
42+
token TOP { \d+ }
43+
}
44+
nok(A::B.parse("zzz42zzz"), ".parse works with namespaced grammars, no match");
45+
is(~A::B.parse("42"), "42", ".parse works with namespaced grammars, match");
46+
47+
# TODO: Check for a good error message, not just the absence of a bad one.
48+
throws-like '::No::Such::Grammar.parse()', Exception, '.parse on missing grammar dies';
49+
50+
# RT #71062
51+
{
52+
grammar Integer { rule TOP { x } };
53+
lives-ok { Integer.parse('x') }, 'can .parse grammar named "Integer"';
54+
}
55+
56+
# RT #76884
57+
{
58+
grammar grr {
59+
token TOP {
60+
<line>*
61+
}
62+
token line { .* \n }
63+
}
64+
65+
my $match = grr.parse('foo bar asd');
66+
ok $match[0].perl, 'empty match is perlable, not Null PMC access';
67+
}
68+
69+
# RT #116597
70+
{
71+
grammar RT116597 {
72+
token TOP() { <lit 'a'> };
73+
token lit($s) { $s };
74+
}
75+
lives-ok { RT116597.parse('a') ~~ Failure },
76+
'can use <rule "param"> form of rule invocation in grammar';
77+
}
78+
79+
# RT #111768
80+
{
81+
grammar RT111768 {
82+
token e {
83+
| 'a' <e> { make ';' ~ $<e>.ast }
84+
| ';' { make 'a' }
85+
}
86+
}
87+
is RT111768.parse("aaaa;", :rule<e>).ast, ';;;;a', "Recursive .ast calls work";
88+
}
89+
90+
# RT #130081
91+
{
92+
my grammar G { regex TOP { ‘a’ || ‘abc’ } };
93+
is G.parse(abc), 'abc', 'A regex TOP will be backtracked into to get a long enough match';
94+
}
95+
96+
{
97+
my grammar G1 {
98+
token TOP { [ || [ <line> ]+ ] }
99+
token line { ^^ '#' \N+ [ \n | $ ] }
100+
}
101+
102+
my $res = G1.parse: q:to/BADTEXT/;
103+
# l1
104+
# l2
105+
# l3
106+
l4
107+
# l5
108+
BADTEXT
109+
ok $res ~~ Failure, "parse failed with Failure";
110+
my $ex = $res.exception;
111+
isa-ok $ex, X::Syntax::Confused, "failure exception is X::Syntax::Confused";
112+
is $ex.line, 3, "parsing failed at line 1";
113+
is $ex.pos, 14, "pos is 14";
114+
is ~$ex.pre, "# l3", "pre is '# l3'";
115+
is ~$ex.post, "<EOL>", "post is <EOL>";
116+
}
117+
118+
# vim: ft=perl6 expandtab sw=4

spectest.data

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ S05-grammar/example.t
400400
S05-grammar/inheritance.t
401401
S05-grammar/methods.t
402402
S05-grammar/namespace.t
403-
S05-grammar/parse_and_parsefile.t
403+
S05-grammar/parse_and_parsefile-6c.t
404+
S05-grammar/parse_and_parsefile-6e.t
404405
S05-grammar/polymorphism.t
405406
S05-grammar/protoregex.t
406407
S05-grammar/protos.t

0 commit comments

Comments
 (0)