# A set of rules for parsing Signatures in perl6
# XXX no support for isLValue, isWritable, or isLazy (don't understand isLazy)
# described in InternalNames.hs line 798
# ??? does (terminates => *) work with any named rule?
# Can I do ',')>?
# What about [ ](terminates => *)
grammar Signature {
# XXX add unicode alternatives
token open_q { <[<]> }
token close_q { <[>]> }
token open_qq { <[<]**{2}> } # ??? is this syntax right?
token close_qq { <[>]**{2}> }
token open_paren { <[(]> }
token close_paren { <[)]> }
token open_curly { <[{]> }
token close_curly { <[}]> }
token open_array { <[[]> }
token close_array { <[\]]> }
# stand-in for bracketing constructs
# XXX add more or get unicode character classes working
# XXX after matching an open_group symbol, only count the
# appropriate close_group as a match
token open_group {
[
|
|
|
|
|
]
}
token close_group {
[
|
|
|
|
|
]
}
token close_param { <[,)]> }
# separator used in multi sigs to separate multiple levels of invocants
token tie_break { <[:]> }
# perl6 sigils in signatures
token is_array { $ := <[@]> }
token is_scalar { $ := <[$]> }
token is_code { $ := <[&]> }
token is_hash { $ := <[%]> }
token sigil { | | | }
# names don't have \d as the first character and have
# at least one non-_ character
token param_name { [ | _ ]+ [ | \d | _ ]+ }
token internal { }
token external { }
# defaults for arguments can be assigned in the sig
token default { = ? $ := ',' )> }
# types start with an uppercase letter
token type_name { + [ | _ | \d ]* }
token type { }
token ret_type { }
token type_var { }
token ret_arrow { \-\-\> }
token returns { * }
# parse *@x and :$x and mark for slurpy/named
token is_named { <[:]> }
token is_slurpy { <[*]> }
token prefix_mod { [ | ] }
# parse $x! and $x? and mark for required/optional
token is_optional { <[?]> }
token is_required { <[!]> }
token postfix_mod { [ | ] }
# parse $^x and mark it as an implicit. leave room for other twigils
token is_implicit { <[^]> }
token twigil { }
# traits have the same rules for names as params
token trait_name := param_name;
token trait { is + }
# this allows specifying a type on a parameter, as well parameterizing that type.
token dwigil { [:]**{2} }
token declarator { my | our | has | state | constant }
token type_param { + [ * ]? }
# $x, $^x, $
token positional {
[ ? $ := ? ]
}
# :$x, :x($y), :$, :$(x)
token named {
[
| $ := ?
| ?
]
}
# *@x
token slurpy {
? ? ? * ?
}
# [ $x, *@y ]
# ??? how should unpacked params be accessed? in $?
# in some cases they'll be aliased to something in $
# in other cases, they'll act as anonymous $
token unpacked {
* ? ? + * * *
}
rule param {
? ?
[
|
|
|
]
? * ?
}
# signature for a single dispatch routine
# ??? does this definition backtrack
rule single_sig {
[ ? ]* * ?
}
# sig for multi dispatch routine
rule multi_sig {
[ ]* ?
: { @single_sig[ *..( +$ - 1 ) ] >>++ } # thanks audreyt++
}
}