@@ -288,7 +288,7 @@ the number for the currently parsed C<digit> digits.
288
288
say Digifier.parse('255 435 777', actions => Devanagari.new).made;
289
289
# OUTPUT: «(२५५ ४३५ ७७७)»
290
290
291
- = head2 Methods in Grammar
291
+ = head2 Methods in grammars
292
292
293
293
It's fine to use methods instead of rules or tokens in a grammar, as long
294
294
as they return a L < Cursor|/type/Cursor > :
@@ -312,7 +312,7 @@ provided by parse methods:
312
312
# OUTPUT: «12»
313
313
= end code
314
314
315
- = head2 Dynamic Variables in Grammars
315
+ = head2 Dynamic variables in grammars
316
316
317
317
Variables can be defined in tokens by prefixing the lines of code defining them
318
318
with C < : > . Arbitrary code can be embedded anywhere in a token by surrounding it
@@ -359,6 +359,56 @@ matches with the correct guard:
359
359
# OUTPUT: #<failed match>
360
360
= end code
361
361
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
+
362
412
= head1 X < Action Objects|Actions >
363
413
364
414
A successful grammar match gives you a parse tree of L < Match|/type/Match >
0 commit comments