NAME¶
bt_traversal - AST traversal/query functions in btparse library
SYNOPSIS¶
AST * bt_next_entry (AST * entry_list,
AST * prev_entry)
AST * bt_next_field (AST * entry, AST * prev, char ** name)
AST * bt_next_value (AST * head,
AST * prev,
bt_nodetype_t * nodetype,
char ** text)
bt_metatype_t bt_entry_metatype (AST * entry)
char * bt_entry_type (AST * entry)
char * bt_entry_key (AST * entry)
char * bt_get_text (AST * node)
DESCRIPTION¶
The functions described here are all used to traverse and query the
abstract-syntax trees (ASTs) returned by the input functions described in
bt_input. The three "bt_next" functions
("bt_next_entry()", "bt_next_field()", and
"bt_next_value()") are used respectively to traverse a list of
entries, the list of fields within a particular entry, and the list of simple
values associated with a particular field. The other functions are just used
to query various nodes in the tree for the useful information contained in
them.
Traversal functions¶
- bt_next_entry()
-
AST * bt_next_entry (AST * entry_list,
AST * prev_entry)
Used to traverse the linked list of entries returned by
"bt_parse_file()" (see bt_input). On the first call, you should
supply "NULL" for "prev_entry", and a pointer to the
head of the list will be returned. On subsequent calls, pass the previous
return value as "prev_entry"; the function returns the next
entry in the list, or "NULL" if there are no more entries. Also
returns "NULL" if either "entry_list" or
"prev_entry" are improper.
For example (ignoring error handling and variable declarations):
entries = bt_parse_file (filename, options, &status);
entry = NULL;
while (entry = bt_next_entry (entries, entry))
{
/* process entry */
}
- bt_next_field()
-
AST * bt_next_field (AST * entry, AST * prev, char ** name)
Used to traverse the list of fields in a regular or macro definition entry.
(You should call "bt_entry_metatype()" to determine if you have
the right kind of entry before calling "bt_next_field()".)
"entry" should be a pointer to the AST for a single entry, as
returned by "bt_parse_entry()", "bt_parse_entry_s()",
or "bt_next_entry()". On the first call, supply "NULL"
for "prev"; "bt_next_field()" will return a pointer to
the first field in "entry", or "NULL" if
"entry" has no fields (for instance, if it's a comment or
preamble entry). On subsequent calls, pass the previous return value as
"prev"; "bt_next_field()" will keep returning pointers
to field sub-ASTs as long as it makes sense. These pointers can then be
passed to "bt_next_value()" or "bt_get_text()" to get
the field's value.
For example, the loop body in the previous example could be:
field = NULL;
while (field = bt_next_field (entry, field, &field_name))
{
/* process field */
}
- bt_next_value()
-
AST * bt_next_value (AST * head,
AST * prev,
bt_nodetype_t * nodetype,
char ** text)
Traverses the list of simple values that make up the value of a single
field. (Recall that a simple value is either a quoted string, a macro
invocation, or a number. A compound value is a list of these separated by
'#' in the original input. Depending on the string post-processing options
used when the data was parsed, the "list of simple values"
nature of the original data may be preserved in the AST that you're
traversing, in which case you'll need a "bt_next_value()" loop.
"bt_next_value()" works much like "bt_next_entry()" and
"bt_next_field()": on the first call, you supply
"NULL" for "prev", and on subsequent calls you supply
the previous return value. Returns "NULL" when there are no more
simple values to return. Also sets *nodetype and *text to the
corresponding information from the simple value node. *nodetype will be
one of "BTAST_STRING", "BTAST_MACRO", or
"BTAST_NUMBER"; *text will point to the same string as the AST
node does (it is not copied for you), so don't mess with it.
For example, the loop body in the "bt_next_field()" example could
be replaced with:
value = NULL;
while (value = bt_next_field (field, value, &nodetype, &text))
{
switch (nodetype)
{
case BTAST_STRING: /* process the string */
case BTAST_MACRO: /* process the macro */
case BTAST_NUMBER: /* process the number */
}
}
See also "bt_get_text".
Query functions¶
- bt_entry_metatype()
-
bt_metatype_t bt_entry_metatype (AST * entry)
Returns the metatype of an entry. (Recall that the metatype is an
enumerated type whose values are derived from the specific type of an
entry; for instance, an @comment entry has type "comment" and
metatype "BTE_COMMENT". The type-metatype relationship is
similarly obvious for "BTE_PREAMBLE"; "BTE_MACRODEF"
corresponds to @string entries; and "BTE_REGULAR" corresponds to
any other type.)
Returns "BTE_UNKNOWN" if "entry" is invalid (i.e.,
"NULL" or not a pointer to an entry AST).
- bt_entry_type()
-
char * bt_entry_type (AST * entry)
Returns the type of an entry. Recall that the type is the name that appears
after the '@' character in the original input. Returns "NULL" if
"entry" is invalid (i.e., "NULL" or not a pointer to
an entry AST).
- bt_entry_key()
-
char * bt_entry_key (AST * entry)
Returns the citation key of a regular entry. (The citation key is the name
that appears after the entry-open delimiter in a regular entry.) Returns
"NULL" if "entry" is invalid (i.e., "NULL"
or not a pointer to the AST for a regular entry).
- bt_get_text()
-
char * bt_get_text (AST * node)
Performs all string post-processing (macro expansion, concatenation of
simple values, and whitespace collapsing) of a compound value and returns
the string that results. Can be called either on a field for a regular or
macro definition entry (as returned by "bt_next_field()"), or on
a comment or preamble entry. Returns "NULL" if called on an
invalid AST node.
SEE ALSO¶
btparse, bt_input, bt_postprocess
AUTHOR¶
Greg Ward <gward@python.net>