Skip to content

Commit afd5944

Browse files
authored
Merge pull request #2219 from Kaiepi/grammars
Document grammar attributes Thanks a lot!
2 parents eedafd1 + 965c2f4 commit afd5944

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

doc/Language/grammars.pod6

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ the number for the currently parsed C<digit> digits.
288288
say Digifier.parse('255 435 777', actions => Devanagari.new).made;
289289
# OUTPUT: «(२५५ ४३५ ७७७)␤»
290290
291-
=head2 Methods in Grammar
291+
=head2 Methods in grammars
292292
293293
It's fine to use methods instead of rules or tokens in a grammar, as long
294294
as they return a L<Cursor|/type/Cursor>:
@@ -312,7 +312,7 @@ provided by parse methods:
312312
# OUTPUT: «12␤»
313313
=end code
314314
315-
=head2 Dynamic Variables in Grammars
315+
=head2 Dynamic variables in grammars
316316
317317
Variables can be defined in tokens by prefixing the lines of code defining them
318318
with C<:>. Arbitrary code can be embedded anywhere in a token by surrounding it
@@ -359,6 +359,56 @@ matches with the correct guard:
359359
# OUTPUT: #<failed match>
360360
=end code
361361
362+
=head2 Attributes in grammars
363+
364+
Attributes may be defined in grammars. However, they can only be accessed by
365+
methods. Attempting to use them from within a token will throw an exception
366+
because tokens are methods of L<Cursor|/type/Cursor>, not of the grammar
367+
itself. Note that mutating an attribute from within a method called in a token
368+
will I<only modify the attribute for that token's own match object>! Grammar
369+
attributes can be accessed in the match returned after parsing if made public:
370+
371+
grammar HTTPRequest {
372+
has Bool $.invalid;
373+
374+
token TOP {
375+
<type> <path> 'HTTP/1.1' \r\n
376+
[<field> \r\n]+
377+
\r\n
378+
$<body>=.*
379+
}
380+
381+
token type {
382+
| GET | POST | OPTIONS | HEAD | PUT | DELETE | TRACE | CONNECT
383+
| \S+ <.error>
384+
}
385+
386+
token path {
387+
| '/' [[\w+]+ % \/] [\.\w+]?
388+
| '*'
389+
| \S+ <.error>
390+
}
391+
392+
token field {
393+
| $<name>=\w+ : $<value>=<-[\r\n]>*
394+
| <-[\r\n]>+ <.error>
395+
}
396+
397+
method error(--> ::?CLASS:D) {
398+
$!invalid = True;
399+
self;
400+
}
401+
}
402+
403+
my $header = "MEOWS / HTTP/1.1\r\nHost: docs.perl6.org\r\nsup lol\r\n\r\n";.
404+
my $/ = HTTPRequest.parse($header);
405+
say $<type>.invalid;
406+
# OUTPUT: True
407+
say $<path>.invalid;
408+
# OUTPUT: (Bool)
409+
say $<field>».invalid;
410+
# OUTPUT: [(Bool) True]
411+
362412
=head1 X<Action Objects|Actions>
363413
364414
A successful grammar match gives you a parse tree of L<Match|/type/Match>

0 commit comments

Comments
 (0)