|
Libecoli 0.11.1
Extensible COmmand LIne library
|
Libecoli grammar nodes. More...
Topics | |
| Any node | |
| A node that matches any single token. | |
| Bypass node | |
| A pass-through node useful for building graph loops. | |
| Command node | |
| A node that parses commands using a format string. | |
| Condition node | |
| A node that conditionally matches based on an expression. | |
| Dynamic node | |
| A node built dynamically at parse time by a callback. | |
| Dynamic list node | |
| A node that matches names from a dynamic list. | |
| Empty node | |
| A node that matches an empty input. | |
| Expression node | |
| A node for parsing and evaluating expressions with operators. | |
| File node | |
| A node that matches and completes file paths. | |
| Integer node | |
| Nodes that match signed or unsigned integers. | |
| Many node | |
| A node that matches its child multiple times. | |
| None node | |
| A node that never matches anything. | |
| Once node | |
| A node that prevents its child from being parsed more than once. | |
| Option node | |
| A node that makes its child optional. | |
| Or node | |
| A node that matches one of its child nodes. | |
| Regex node | |
| A node that matches input against a regular expression. | |
| Regex lexer node | |
| A lexer node using regular expressions for tokenization. | |
| Sequence node | |
| A node that matches a sequence of child nodes in order. | |
| Shell lexer node | |
| A lexer node using shell-like tokenization rules. | |
| Space node | |
| A node that matches whitespace. | |
| String node | |
| A node that matches a specific string. | |
| Subset node | |
| A node that matches any subset of its children in any order. | |
Data Structures | |
| struct | ec_node_type |
Macros | |
| #define | EC_NO_ID "" |
| #define | EC_NODE_TYPE_REGISTER(t) |
| #define | EC_NODE_TYPE_REGISTER_OVERRIDE(t) |
Typedefs | |
| typedef int(* | ec_node_set_config_t) (struct ec_node *node, const struct ec_config *config) |
| typedef int(* | ec_parse_t) (const struct ec_node *node, struct ec_pnode *pstate, const struct ec_strvec *strvec) |
| typedef int(* | ec_complete_t) (const struct ec_node *node, struct ec_comp *comp, const struct ec_strvec *strvec) |
| typedef char *(* | ec_node_desc_t) (const struct ec_node *) |
| typedef int(* | ec_node_init_priv_t) (struct ec_node *) |
| typedef void(* | ec_node_free_priv_t) (struct ec_node *) |
| typedef size_t(* | ec_node_get_children_count_t) (const struct ec_node *) |
| typedef int(* | ec_node_get_child_t) (const struct ec_node *, size_t i, struct ec_node **child, unsigned int *refs) |
Functions | |
| int | ec_node_type_register (struct ec_node_type *type, bool override) |
| const struct ec_node_type * | ec_node_type_lookup (const char *name) |
| void | ec_node_type_dump (FILE *out) |
| const struct ec_config_schema * | ec_node_type_schema (const struct ec_node_type *type) |
| const char * | ec_node_type_name (const struct ec_node_type *type) |
| struct ec_node * | ec_node_from_type (const struct ec_node_type *type, const char *id) |
| struct ec_node * | ec_node (const char *typename, const char *id) |
| struct ec_node * | ec_node_clone (struct ec_node *node) |
| void | ec_node_free (struct ec_node *node) |
| int | ec_node_set_config (struct ec_node *node, struct ec_config *config) |
| const struct ec_config * | ec_node_get_config (const struct ec_node *node) |
| size_t | ec_node_get_children_count (const struct ec_node *node) |
| int | ec_node_get_child (const struct ec_node *node, size_t i, struct ec_node **child) |
| const struct ec_node_type * | ec_node_type (const struct ec_node *node) |
| struct ec_dict * | ec_node_attrs (const struct ec_node *node) |
| const char * | ec_node_id (const struct ec_node *node) |
| char * | ec_node_desc (const struct ec_node *node) |
| void | ec_node_dump (FILE *out, const struct ec_node *node) |
| struct ec_node * | ec_node_find (struct ec_node *node, const char *id) |
| struct ec_node_iter * | ec_node_iter (struct ec_node *node) |
| struct ec_node_iter * | ec_node_iter_next (struct ec_node_iter *root, struct ec_node_iter *iter, bool iter_children) |
| void | ec_node_iter_free (struct ec_node_iter *iter) |
| struct ec_node * | ec_node_iter_get_node (struct ec_node_iter *iter) |
| struct ec_node_iter * | ec_node_iter_get_parent (struct ec_node_iter *iter) |
| int | ec_node_check_type (const struct ec_node *node, const struct ec_node_type *type) |
| const char * | ec_node_get_type_name (const struct ec_node *node) |
| void * | ec_node_priv (const struct ec_node *node) |
| void | ec_node_schema_dump (FILE *out, const struct ec_node *node) |
Variables | |
| struct ec_node_type_list | node_type_list |
Libecoli grammar nodes.
The grammar node is a main structure of the ecoli library, used to define how to match and complete the input tokens. A node is a generic object that implements:
One basic example is the string node (ec_node_str()). A node ec_node_str("foo") will match any token list starting with "foo", for example:
A node ec_node_str("foo") will complete with "foo" if the input contains one token, with the same beginning as "foo":
But it will not complete:
A node can have child nodes. For instance, a sequence node ec_node_seq(ec_node_str("foo"), ec_node_str("bar")) will match a sequence: ["foo", "bar"].
Note: at some places in the documentation and the code, we may talk about the grammar tree, but as loops are allowed, we should instead talk about grammar graph.
| #define EC_NO_ID "" |
Node has no identifier.
| #define EC_NODE_TYPE_REGISTER | ( | t | ) |
Register a node type at library load.
The node type is registered in a function that has the constructor attribute: the function is called at library load.
| t | The name of the ec_node_type structure variable. |
| #define EC_NODE_TYPE_REGISTER_OVERRIDE | ( | t | ) |
Register a node type at library load, overriding previous registration.
The node type is registered in a function that has the constructor attribute: the function is called at library load.
Be careful when using this macro, as the last type with a given name is the one that is actually registered. The call order may be hard to predict, especially within the same binary.
| t | The name of the ec_node_type structure variable. |
Function type used to configure a node.
The function pointer is not called directly, the helper ec_node_set_config() should be used instead.
The configuration passed to this function pointer is valid, i.e. ec_config_validate() returned 0 on it.
This function provided by a node type is supposed to do additional checks on the configuration and store private data, if needed. If it returns 0, ec_node_set_config() stores the generic configuration in the node. The function can just return 0 if nothing needs to be stored in private data.
| node | The node to configure. |
| config | The configuration to apply to the node. |
| typedef int(* ec_parse_t) (const struct ec_node *node, struct ec_pnode *pstate, const struct ec_strvec *strvec) |
Parse a string vector using the given grammar graph.
The function pointer is not called directly, the helpers ec_parse(), ec_parse_strvec() or ec_parse_child() should be used instead.
The implementation of this method for a node that manages children will call ec_parse_child(child, pstate, child_strvec).
| node | The grammar graph. |
| pstate | A pointer to the leaf being parsed in the parsing tree. It can be used by a node to retrieve information from the current parsing tree. To get the root of the tree, ec_pnode_get_root(pstate) should be used. |
| strvec | The string vector to be parsed. |
| typedef int(* ec_complete_t) (const struct ec_node *node, struct ec_comp *comp, const struct ec_strvec *strvec) |
Get completion items using the given grammar graph.
The function pointer should not be called directly, the helpers ec_complete(), ec_complete_strvec() or ec_complete_child() should be used instead.
This function completes the last element of the string vector. For instance, node.type->complete(node, comp, ["ls"]) will list all commands that start with "ls", while node.type->complete(node, comp, ["ls", ""]) will list all possible values for the next argument.
The implementation of this function in the node is supposed to either:
A node that does not provide any method for the completion will fall back to ec_complete_unknown(): this helper returns a completion item of type EC_COMP_UNKNOWN, just to indicate that everything before the last element of the string vector has been parsed successfully, but we don't know how to complete the last element.
| node | The root node of the grammar graph. |
| comp | The current list of completion items, to be filled by the node.type->complete() method. |
| strvec | The string vector to be completed. |
| typedef char *(* ec_node_desc_t) (const struct ec_node *) |
Get the short description of a grammar node.
This function pointer should not be called directly. The ec_node_desc() helper should be used instead.
This callback is typically used when building a help string for a grammar graph. It is used in ecoli editline interface to generate contextual help like this (first column):
<int> An integer. foo The foo string. bar The bar string.
If this callback is set to NULL in the node type, the default behavior is to return the node type name inside <>, for instance <int>. The string node type implements this method to return the string value. An integer node could implement it to return its range (e.g., "1..10").
The returned value is a pointer that must be freed by the caller with free().
On error, NULL is returned and errno is set.
| typedef int(* ec_node_init_priv_t) (struct ec_node *) |
Initialize the node private area.
This function pointer should not be called directly. The ec_node() and ec_node_from_type() helpers, that allocate new nodes, should be used instead.
If not NULL, this function is called when a node is instantiated, to initialize the private area of a node. In any case, the private area is first zeroed.
On success, 0 is returned. On error, a negative value is returned and errno is set.
| typedef void(* ec_node_free_priv_t) (struct ec_node *) |
Free the node private area.
This function pointer should not be called directly. The ec_node_free() helper should be used instead.
When a node is deleted, this function is called to free the resources referenced in the node private area.
| typedef size_t(* ec_node_get_children_count_t) (const struct ec_node *) |
Count the number of node children.
This function pointer should not be called directly. The ec_node_get_children_count() helper should be used instead.
Some grammar nodes like seq, or, many, (...), reference children nodes in the grammar graph. This function returns the number of children.
| typedef int(* ec_node_get_child_t) (const struct ec_node *, size_t i, struct ec_node **child, unsigned int *refs) |
Get the i-th child node.
This function pointer should not be called directly. The ec_node_get_child() helper should be used instead.
Some grammar nodes like seq, or, many, (...), reference children nodes in the grammar graph. This function sets the i-th child (with i lower than the return value of ec_node_get_children_count()) in the child pointer. It also returns the number of references to the child owned by the parent. This information is used by the algorithm that frees a grammar graph taking care of loops.
On success, 0 is returned. On error, a negative value is returned and errno is set.
| int ec_node_type_register | ( | struct ec_node_type * | type, |
| bool | override ) |
Register a node type.
The name of the type being registered is a unique identifier. However, it is possible to force the registration of a type with an existing name by setting "override" to true. Note that the initial type is not removed from the list, instead the new one is added before in the list.
| type | The node type to be registered. |
| override | Allow the registration of an existing type. |
| const struct ec_node_type * ec_node_type_lookup | ( | const char * | name | ) |
Lookup node type by name.
| name | The name of the node type to search. |
| void ec_node_type_dump | ( | FILE * | out | ) |
Dump registered node types.
| out | The stream where the dump is sent. |
| const struct ec_config_schema * ec_node_type_schema | ( | const struct ec_node_type * | type | ) |
Get the config schema of a node type.
| type | The node type. |
| const char * ec_node_type_name | ( | const struct ec_node_type * | type | ) |
Get the name of a node type.
| type | The node type. |
| struct ec_node * ec_node_from_type | ( | const struct ec_node_type * | type, |
| const char * | id ) |
Create a new node when the type is known.
This function is typically called from the node constructor.
| type | The type of the node to create. |
| id | The node identifier. |
| struct ec_node * ec_node | ( | const char * | typename, |
| const char * | id ) |
Create a new node from its type name.
This function is typically called from user code, for node types that do not provide a specific constructor.
| typename | The type name of the node to create. |
| id | The node identifier. |
Clone a grammar node.
This function takes a reference to the node. If ec_node_free() is later called on this node, it will decrease only the reference. The free is effective when the reference count reaches 0. The reference counter is initialized to 1 at node creation.
| node | The node to clone. |
| void ec_node_free | ( | struct ec_node * | node | ) |
Decrement node reference counter and free the node if it is the last reference.
| node | The grammar node to free. |
Set node configuration.
For a node that supports generic configuration, set its configuration.
After a call to this function, the config is owned by the node and must not be used by the caller anymore.
| node | The grammar node to configure. |
| config | The configuration to apply on the node. |
Get the current node configuration.
For a node that supports generic configuration, get its configuration.
| node | The grammar node. |
| size_t ec_node_get_children_count | ( | const struct ec_node * | node | ) |
Return the number of children for a node.
| node | The grammar node. |
Get the n-th child of a node.
| node | The grammar node. |
| i | The index of the child node, that must be lower than the number of children. |
| child | The pointer where the child node pointer will be stored on success. |
| const struct ec_node_type * ec_node_type | ( | const struct ec_node * | node | ) |
Get the type of a node.
| node | The grammar node. |
Get the attributes dict of the node.
A user can add any attribute to a node. The attributes keys starting with an underscore are reserved.
| node | The grammar node. |
| const char * ec_node_id | ( | const struct ec_node * | node | ) |
Get node identifier.
| node | The grammar node. |
| char * ec_node_desc | ( | const struct ec_node * | node | ) |
Get node short description.
| node | The grammar node. |
| void ec_node_dump | ( | FILE * | out, |
| const struct ec_node * | node ) |
Dump a grammar tree.
| out | The stream where the dump is sent. |
| node | The grammar tree to dump. |
Find a node from its identifier string.
Browse the tree using pre-order depth traversal, and return the first node that matches the given identifier.
| node | The grammar tree. |
| id | The identifier to match. |
| struct ec_node_iter * ec_node_iter | ( | struct ec_node * | node | ) |
Create an iterator on a grammar tree.
A grammar tree is actually not really a tree, it is an oriented graph where loops can exist. For this reason, it is not possible to iterate the grammar graph without storing somewhere the list of browsed nodes in order to break loops.
Another property of grammar graphs is that the same node can appear several times at different places in the graph, having a different parent. This kind of node will be iterated only once.
The typical use is:
Technically, this function builds a tree from the grammar graph. Each node of this tree references a node of the grammar graph.
| node | The grammar graph to iterate |
| struct ec_node_iter * ec_node_iter_next | ( | struct ec_node_iter * | root, |
| struct ec_node_iter * | iter, | ||
| bool | iter_children ) |
Iterate to the next node.
See ec_node_iter().
| root | The iterator returned by ec_node_iter(). |
| iter | The current node in the iterator. |
| iter_children | True to iterate the children of "iter", false to skip them. |
| void ec_node_iter_free | ( | struct ec_node_iter * | iter | ) |
Free a grammar graph iterator.
| iter | The iterator returned by ec_node_iter() to free. |
| struct ec_node * ec_node_iter_get_node | ( | struct ec_node_iter * | iter | ) |
Get the grammar node referenced by the iterator node.
| iter | The iterator node. |
| struct ec_node_iter * ec_node_iter_get_parent | ( | struct ec_node_iter * | iter | ) |
Get the parent of an iterator node.
| iter | The iterator node. |
| int ec_node_check_type | ( | const struct ec_node * | node, |
| const struct ec_node_type * | type ) |
Check the type of a node.
| node | The grammar node. |
| type | The pointer to the type structure. |
| const char * ec_node_get_type_name | ( | const struct ec_node * | node | ) |
Get the type name of a grammar node.
| node | The grammar node. |
| void * ec_node_priv | ( | const struct ec_node * | node | ) |
Get the pointer to the node private area.
| node | The grammar node. |
| void ec_node_schema_dump | ( | FILE * | out, |
| const struct ec_node * | node ) |
Dump the node configuration schema.
| out | The stream where the dump is sent. |
| node | The grammar node. |
|
extern |
The list of registered node types. Must not be modified by user, except at initialization using the EC_NODE_TYPE_REGISTER() or EC_NODE_TYPE_REGISTER_OVERRIDE() macros.