搭配 pybind11
食用
/**
* @brief buggy, complex and disturbing grammar for help() information parsing generated by pybind11
*/
constexpr auto doc_parse_grammar = R"(
doc <- title name classes functions version file
title <- 'Help on module ' module_name ':' block_space
module_name <- typeref
name <- 'NAME' internal_space module_name block_space
classes <- 'CLASSES' class_tree block_space class_decl*
functions <- 'FUNCTIONS' internal_space function_list
version <- 'VERSION' internal_space version_code block_space
file <- 'FILE' internal_space file_name
version_code <- < [0-9]+(.[0-9]+)* >
file_name <- < [/a-zA-z.0-9-]+ >
class_tree <- < (internal_space (inherited_type / typeref))* >
inherited_type <- < typeref '(' typeref ')' >
class_decl <- 'class' inherited_type internal_space_ex method_resolution_order? methods? static_methods? readonly_properties? data_attributes? inherited_methods? inherited_properties? skipped_static_new? block_space
method_resolution_order <- 'Method resolution order:' (internal_space_ex typeref)* block_space_ex
methods <- 'Methods defined here:' block_space_ex ((skipped_init / override_method_itf / method) block_space_ex)* splitter?
static_methods <- 'Static methods defined here:' block_space_ex ((override_method_itf / method) block_space_ex)* splitter?
skipped_init <- '__init__(self, /, *args, **kwargs)' internal_space_ex [ \tA-Za-z0-9.()?!]*
override_method_itf <- identifier '(...)' internal_space_ex identifier '(*args, **kwargs)' internal_space_ex 'Overloaded function.' override_method_list
override_method_list <- (block_space_ex [0-9]+ '. ' method_prototype)*
method <- identifier '(...)' ('from' typeref)? internal_space_ex method_prototype
method_prototype <- function_name '(' (argument / ', ')* ') -> ' return_type (comment)?
comment <- [\n] ' | ' [\n] ' | ' [` A-Za-z.()?!]+
function_name <- identifier
readonly_properties <- ('Readonly properties' / 'Data descriptors') 'defined here:' (block_space_ex identifier)* block_space_ex splitter
data_attributes <- 'Data and other attributes defined here:' (internal_space_ex+ (type_alias / data_attr))* block_space_ex internal_space_ex? splitter
data_attr <- < identifier ' = ' typeref >
type_alias <- < identifier ' = <class' [a-zA-Z0-9_. '"]+ ('...' / '>')? >
inherited_methods <- 'Methods inherited from ' typeref ':' block_space_ex ((override_method_itf / method) block_space_ex)* splitter?
inherited_properties <- 'Readonly properties inherited from ' typeref ':' (block_space_ex identifier)* block_space_ex splitter
skipped_static_new <- 'Static methods inherited from pybind11_builtins.pybind11_object:' block_space_ex '__new__(*args, **kwargs) from pybind11_builtins.pybind11_type' internal_space_ex 'Create and return a new object. See help(type) for accurate signature.'
function_list <- method_in_function_list*
method_in_function_list <- identifier '(...) method of ' typeref 'instance' internal_space_ex method_prototype block_space
return_type <- < templated_type / complex_type / typeref >
argument <- < argument_name ': ' (templated_type / argument_type) ('=' complex_value)?>
argument_name <- < identifier >
argument_type <- < complex_type / typeref >
complex_value <- < '[' (',' / complex_value / ' ')* ']' / (['"a-zA-Z0-9_.,]+ / '(' ['"a-zA-Z0-9_.,]+ ')') >
complex_type <- ('List' / 'Tuple' / 'Dict' / 'numpy.ndarray' / 'Set') '[' (templated_type / parallel_types) ']'
parallel_types <- (complex_type / typeref ('[' [0-9]+ ']')? / ', ') *
identifier <- < [A-Za-z_][A-Za-z_0-9]* >
typeref <- < identifier (('.' / '::') identifier)* >
templated_type <- 'const'? symbol '<' (templated_type / type / ', ')* '>' ([ &*]+)?
type <- <'const'? [ ]* [0-9a-zA-Z_:&*]+ ([ &*]+)?>
symbol <- <[a-zA-Z_][0-9a-zA-Z_:]*>
splitter <- < '----------------------------------------------------------------------' internal_space_ex? >
block_space <- < ([\n][\t ]*){2} >
block_space_ex <- < ([\n][\t |]*){2} >
internal_space <- < [\n][\t ]* >
internal_space_ex <- < [\n][\t |]* >
%whitespace <- < [ \t]* >
)";