.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "XS::Parse::Sublike 3pm" .TH XS::Parse::Sublike 3pm "2021-01-23" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" "XS::Parse::Sublike" \- XS functions to assist in parsing "sub"\-like syntax .SH "DESCRIPTION" .IX Header "DESCRIPTION" This module provides some \s-1XS\s0 functions to assist in writing parsers for \&\f(CW\*(C`sub\*(C'\fR\-like syntax, primarily for authors of keyword plugins using the \&\f(CW\*(C`PL_keyword_plugin\*(C'\fR hook mechanism. It is unlikely to be of much use to anyone else; and highly unlikely to be any use when writing perl code using these. Unless you are writing a keyword plugin using \s-1XS,\s0 this module is not for you. .PP This module is also currently experimental, and the design is still evolving and subject to change. Later versions may break \s-1ABI\s0 compatibility, requiring changes or at least a rebuild of any module that depends on it. .SH "XS FUNCTIONS" .IX Header "XS FUNCTIONS" .SS "boot_xs_parse_sublike" .IX Subsection "boot_xs_parse_sublike" .Vb 1 \& void boot_xs_parse_sublike(double ver) .Ve .PP Call this function from your \f(CW\*(C`BOOT\*(C'\fR section in order to initialise the module and parsing hooks. .PP \&\fIver\fR should either be 0 or a decimal number for the module version requirement; e.g. .PP .Vb 1 \& boot_xs_parse_sublike(0.04); .Ve .SS "xs_parse_sublike" .IX Subsection "xs_parse_sublike" .Vb 1 \& int xs_parse_sublike(const struct XSParseSublikeHooks *hooks, void *hookdata, OP **op_ptr) .Ve .PP This function performs the actual parsing of a \f(CW\*(C`sub\*(C'\fR\-like keyword. It expects the lexer to be at a position just after the introduction keyword has been consumed, and will proceed to parse an optional name, list of attributes, signature (if enabled by \f(CW\*(C`use feature \*(Aqsignatures\*(Aq\*(C'\fR), and code body. The return value and \f(CW\*(C`op_ptr\*(C'\fR can be used directly from the keyword plugin function. It is intended this function be invoked from it, and the result returned directly. .PP For a more automated handling of keywords, see \*(L"register_xs_parse_sublike\*(R". .PP \&\fIhooks\fR should be a structure that can provide optional function pointers used to customise the parsing process at various stages. \fIhookdata\fR is an opaque pointer which is passed through to each of the hook stage functions. .SS "register_xs_parse_sublike" .IX Subsection "register_xs_parse_sublike" .Vb 2 \& void register_xs_parse_sublike(const char *keyword, \& const struct XSParseSublikeHooks *hooks, void *hookdata) .Ve .PP This function installs a set of parsing hooks to be associated with the given keyword. Such a keyword will then be handled automatically by a keyword parser installed by \f(CW\*(C`XS::Parse::Sublike\*(C'\fR itself. .PP When the keyword is encountered, the hook's \f(CW\*(C`permit\*(C'\fR function is first tested to see if the keyword is permitted at this point. If the function returns true then the keyword is consumed and parsed as per \*(L"xs_parse_sublike\*(R". .PP \&\fIhookdata\fR is an opaque pointer which is passed through to each of the hook stage functions when they are invoked. .SS "xs_parse_sublike_any" .IX Subsection "xs_parse_sublike_any" .Vb 2 \& int xs_parse_sublike_any(const struct XSParseSublikeHooks *hooks, void *hookdata, \& OP **op_ptr) .Ve .PP This function expects to consume an introduction keyword at the lexer position which is either \f(CW\*(C`sub\*(C'\fR or the name of another \f(CW\*(C`sub\*(C'\fR\-like keyword, which has been previously registered using \*(L"register_xs_parse_sublike\*(R". It then proceeds to parse the subsequent syntax similar to how it would have parsed if encountered by the module's own keyword parser plugin, except that the second set of hooks given here also take effect. .PP If a regular \f(CW\*(C`sub\*(C'\fR is encountered, then this is parsed using the \fIhooks\fR in a similar way to \f(CW\*(C`xs_parse_sublike()\*(C'\fR. .PP If a different registered \f(CW\*(C`sub\*(C'\fR\-like keyword is encountered, then parsing is performed using \fBboth\fR sets of hooks \- the ones given to this function as well as the ones registered with the keyword. This allows their effects to combined. The hooks given by the \fIhooks\fR argument are considered to be on the \&\*(L"outside\*(R" from those of the registered keyword \*(L"inside\*(R". The outside ones run first for all stages, except \f(CW\*(C`pre_blockend\*(C'\fR which runs them inside-out. .PP \&\fIhookdata\fR is an opaque pointer which is passed through to each of the hook stage functions when they are invoked. .SH "PARSE CONTEXT" .IX Header "PARSE CONTEXT" The various hook stages all share state about the ongoing parse process using various fields of the \f(CW\*(C`XSParseSublikeContext\*(C'\fR structure. .PP .Vb 6 \& struct XSParseSublikeContext { \& SV *name; \& OP *attrs; \& OP *body; \& CV *cv; \& } .Ve .SH "PARSE HOOKS" .IX Header "PARSE HOOKS" The \f(CW\*(C`XSParseSublikeHooks\*(C'\fR structure provides the following hook stages, which are invoked in the given order. .PP The structure has a \fIflags\fR field, which controls various optional parts of operation. The following flags are defined. .IP "\s-1XS_PARSE_SUBLIKE_FLAG_FILTERATTRS\s0" 4 .IX Item "XS_PARSE_SUBLIKE_FLAG_FILTERATTRS" If set, the optional \f(CW\*(C`filter_attr\*(C'\fR stage will be invoked. .PP In addition there are two \f(CW\*(C`U8\*(C'\fR fields named \fIrequire_parts\fR and \&\fIskip_parts\fR which control the behaviour of various parts of the syntax which are usually optional. Any parts with bits set in \fIrequire_parts\fR become non-optional, and an error if they are missing. Any parts with bits set in \&\fIskip_parts\fR will skip the relevant part of the parsing process. .PP When two sets of hooks are combined by the \f(CW\*(C`xs_parse_sublike_any\*(C'\fR function, these bitmasks are accumulated together with inclusive or. Any part required by either set of hooks will still be required; any step skipped by either will be skipped entirely. .PP If the same bit is set in both fields then the relevant parsing step will not be performed but it will still be an error for that section to be missing. This is likely not useful. .PP Note that for skipped parts, only the actual parsing steps are skipped. A hook function can still set the relevant fields in the context structure anyway to force a particular value for those parts. .IP "\s-1XS_PARSE_SUBLIKE_PART_NAME\s0" 4 .IX Item "XS_PARSE_SUBLIKE_PART_NAME" The name of the function. .IP "\s-1XS_PARSE_SUBLIKE_PART_ATTRS\s0" 4 .IX Item "XS_PARSE_SUBLIKE_PART_ATTRS" The attributes of the function. .Sp This part can be skipped, but the bit is ignored when in \fIrequire_parts\fR. It is always permitted to not provide any additional attributes to a function definition. .IP "\s-1XS_PARSE_SUBLIKE_PART_SIGNATURE\s0" 4 .IX Item "XS_PARSE_SUBLIKE_PART_SIGNATURE" The parameter signature of the function. .Sp This part can be skipped, but the bit is ignored when in \fIrequire_parts\fR. It is always permitted not to provide a signature for a function definition, because such syntax only applies when \f(CW\*(C`use feature \*(Aqsignatures\*(Aq\*(C'\fR is in effect, and only on supporting perl versions. .ie n .SS "The ""permit"" Stage" .el .SS "The \f(CWpermit\fP Stage" .IX Subsection "The permit Stage" .Vb 1 \& bool (*permit)(pTHX_ void *hookdata) .Ve .PP Called by the installed keyword parser hook which is used to handle keywords registered by \*(L"register_xs_parse_sublike\*(R". This hook stage should inspect whether the keyword is permitted at this time (typically by inspecting the hints hash \f(CW\*(C`GvHV(PL_hintgv)\*(C'\fR for some imported key) and return true only if the keyword is permitted. .SS "Parse Name" .IX Subsection "Parse Name" At this point, the optional name is parsed and filled into the \f(CW\*(C`name\*(C'\fR field of the context. .ie n .SS "The ""pre_subparse"" Stage" .el .SS "The \f(CWpre_subparse\fP Stage" .IX Subsection "The pre_subparse Stage" .Vb 1 \& void (*pre_subparse)(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata) .Ve .PP Invoked just before \f(CW\*(C`start_subparse()\*(C'\fR is called. .SS "Parse Attrs" .IX Subsection "Parse Attrs" At this point the optional sub attributes are parsed and filled into the \&\f(CW\*(C`attrs\*(C'\fR field of the context, then \f(CW\*(C`block_start()\*(C'\fR is called. .ie n .SS "The optional ""filter_attr"" Stage" .el .SS "The optional \f(CWfilter_attr\fP Stage" .IX Subsection "The optional filter_attr Stage" .Vb 2 \& bool (*filter_attr)(pTHX_ struct XSParseSublikeContext *ctx, \& SV *attr, SV *val, void *hookdata); .Ve .PP If the \fIflags\fR field includes \f(CW\*(C`XS_PARSE_SUBLIKE_FLAG_FILTERATTRS\*(C'\fR then each individual attribute is passed through this optional filter function immediately as each is parsed. \fIattr\fR will be a string \s-1SV\s0 containing the name of the attribute, and \fIval\fR will either be \f(CW\*(C`NULL\*(C'\fR, or a string \s-1SV\s0 containing the contents of the parens after its name (without the parens themselves). .PP If the filter returns \f(CW\*(C`true\*(C'\fR, it indicates that it has in some way handled the attribute and it should not be added to the list given to \f(CW\*(C`newATTRSUB()\*(C'\fR. If the filter returns \f(CW\*(C`false\*(C'\fR it will be handled in the usual way; equivalent to the case where the filter function did not exist. .ie n .SS "The ""post_blockstart"" Stage" .el .SS "The \f(CWpost_blockstart\fP Stage" .IX Subsection "The post_blockstart Stage" .Vb 1 \& void (*post_blockstart)(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata) .Ve .PP Invoked after the \f(CW\*(C`block_start()\*(C'\fR function has been called. This hook stage may wish to perform any alterations of \f(CW\*(C`PL_compcv\*(C'\fR or related, inspect or alter the lexical pad, provide hints hash values, or any other tasks before the signature and code body are parsed. .SS "Parse Body" .IX Subsection "Parse Body" At this point, the main body of the function is parsed and the optree is stored in the \f(CW\*(C`body\*(C'\fR field of the context. If the perl version supports sub signatures and they are enabled and found, the body will be prefixed with the signature ops as well. .ie n .SS "The ""pre_blockend"" Stage" .el .SS "The \f(CWpre_blockend\fP Stage" .IX Subsection "The pre_blockend Stage" .Vb 1 \& void (*pre_blockend)(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata) .Ve .PP Invoked just before the \f(CW\*(C`block_end()\*(C'\fR function is invoked. The hook stage may wish to inspect or alter the optree stored in the \f(CW\*(C`body\*(C'\fR context field. .ie n .SS "The ""post_newcv"" Stage" .el .SS "The \f(CWpost_newcv\fP Stage" .IX Subsection "The post_newcv Stage" .Vb 1 \& void (*post_newcv)(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata) .Ve .PP Invoked just after \f(CW\*(C`newATTRSUB()\*(C'\fR has been invoked on the optree. The hook stage may wish to inspect or alter the \s-1CV\s0 stored in the \f(CW\*(C`cv\*(C'\fR context field. .SH "AUTHOR" .IX Header "AUTHOR" Paul Evans