Skip to content

Commit 1b14b3b

Browse files
committed
Document using dynamic variables for state in grammars
1 parent fc5de43 commit 1b14b3b

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

doc/Language/grammars.pod6

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,53 @@ provided by parse methods:
312312
# OUTPUT: «12␤»
313313
=end code
314314
315+
=head2 Dynamic Variables in Grammars
316+
317+
Variables can be defined in tokens by prefixing the lines of code defining them
318+
with C<:>. Arbitrary code can be embedded anywhere in a token by surrounding it
319+
with curly braces. This is useful for keeping state between tokens, which can be
320+
used to alter how the grammar will parse text. Using dynamic variables
321+
(variables with C<$*>, C<@*>, C<&*>, C<%*> twigils) in tokens cascades down
322+
through I<all> tokens defined thereafter within the one where it's defined,
323+
avoiding having to pass them from token to token as arguments.
324+
325+
One use for dynamic variables is guards for matches. This example uses guards to
326+
explain which regex classes parse whitespace literally:
327+
328+
grammar GrammarAdvice {
329+
rule TOP {
330+
:my Int $*USE-WS;
331+
"use" <type> "for" <significance> "whitespace by default"
332+
}
333+
token type {
334+
| "rules" { $*USE-WS = 1 }
335+
| "tokens" { $*USE-WS = 0 }
336+
| "regexes" { $*USE-WS = 0 }
337+
}
338+
token significance {
339+
| <?{ $*USE-WS == 1 }> "significant"
340+
| <?{ $*USE-WS == 0 }> "insignificant"
341+
}
342+
}
343+
344+
Here, text such as "use rules for significant whitespace by default" will only
345+
match if the state assigned by whether rules, tokens, or regexes are mentioned
346+
matches with the correct guard:
347+
348+
=begin code :preamble<grammar GrammarAdvice{};>
349+
say GrammarAdvice.subparse("use rules for significant whitespace by default");
350+
# OUTPUT: «use rules for significant whitespace by default»
351+
352+
say GrammarAdvice.subparse("use tokens for insignificant whitespace by default");
353+
# OUTPUT: «use tokens for insignificant whitespace by default»
354+
355+
say GrammarAdvice.subparse("use regexes for insignificant whitespace by default");
356+
# OUTPUT: «use regexes for insignificant whitespace by default»
357+
358+
say GrammarAdvice.subparse("use regexes for significant whitespace by default")
359+
# OUTPUT: #<failed match>
360+
=end code
361+
315362
=head1 X<Action Objects|Actions>
316363
317364
A successful grammar match gives you a parse tree of L<Match|/type/Match>

0 commit comments

Comments
 (0)