5.3 Functions

5.3.1 p_context_new

The p_context_new() function must be called to allocate and initialize the context structure. The input to be used for lexing/parsing is passed in when initializing the context structure.

C example:

p_context_t * context = p_context_new(input, input_length);

D example:

p_context_t * context = p_context_new(input);

5.3.2 p_context_delete

The p_context_delete() function must be called to deinitialize and deallocate a context structure allocated by p_context_init().

5.3.3 p_lex

The p_lex() function is the main entry point to the lexer. It is normally called automatically by the generated parser to retrieve the next input token for the parser and does not need to be called by the user. However, the user may initialize a context and call p_lex() to use the generated lexer in a standalone mode.

Example:

p_context_t * context = p_context_new(input, input_length);
p_token_info_t token_info;
size_t result = p_lex(context, &token_info);
switch (result)
{
case P_DECODE_ERROR:
    /* UTF-8 decode error */
    break;
case P_UNEXPECTED_INPUT:
    /* Input text does not match any lexer pattern. */
    break;
case P_USER_TERMINATED:
    /* Lexer user code block requested to terminate the lexer. */
    break;
case P_SUCCESS:
    /*
     * token_info.position holds the text position of the first code point in the token.
     * token_info.end_position holds the text position of the last code point in the token.
     * token_info.length holds the number of input bytes used by the token.
     * token_info.token holds the token ID of the lexed token
     * token_info.pvalue holds the parser value associated with the token.
     */
    break;
}

5.3.4 p_parse

The p_parse() function is the main entry point to the parser. It must be passed a pointer to an initialized context structure.

Example:

p_context_t * context = p_context_new(input, input_length);
size_t result = p_parse(context);

When multiple start rules are specified, a separate parse function is generated for each which starts parsing at the given rule. For example, if Statement is specified as a start rule:

size_t result = p_parse_Statement(context);

In this case, the parser will start parsing with the Statement rule.

5.3.5 p_position_valid

The p_position_valid() function is only generated for C targets. it is used to determine whether or not a p_position_t structure is valid.

Example:

if (p_position_valid(node->position))
{
    ....
}

For D targets, rather than using p_position_valid(), the valid property function of the p_position_t structure can be queried (e.g. if (node.position.valid)).

5.3.6 p_result

The p_result() function can be used to retrieve the final parse value after p_parse() returns a P_SUCCESS value.

Example:

p_context_t * context = p_context_new(input, input_length);
size_t result = p_parse(context);
if (p_parse(context) == P_SUCCESS)
{
    result = p_result(context);
}

If tree generation mode is active, then the p_result() function returns a Start * pointing to the Start tree node structure.

When multiple start rules are specified, a separate result function is generated for each which returns the parse result for the corresponding rule. For example, if Statement is specified as a start rule:

p_context_t * context = p_context_new(input, input_length);
size_t result = p_parse(context);
if (p_parse_Statement(context) == P_SUCCESS)
{
    result = p_result_Statement(context);
}

In this case, the parser will start parsing with the Statement rule and the parse result from the Statement rule will be returned.

5.3.7 p_position

The p_position() function can be used to retrieve the parser position where an error occurred.

Example:

p_context_t * context = p_context_new(input, input_length);
size_t result = p_parse(context);
if (p_parse(context) == P_UNEXPECTED_TOKEN)
{
    p_position_t error_position = p_position(context);
    fprintf(stderr, "Error: unexpected token at row %u column %u\n",
        error_position.row + 1, error_position.col + 1);
}

5.3.8 p_user_terminate_code

The p_user_terminate_code() function can be used to retrieve the user terminate code after p_parse() returns a P_USER_TERMINATED value. User terminate codes are arbitrary values that can be defined by the user to be returned when the user requests to terminate parsing. They have no particular meaning to Propane.

Example:

if (p_parse(context) == P_USER_TERMINATED)
{
    size_t user_terminate_code = p_user_terminate_code(context);
}

5.3.9 p_token

The p_token() function can be used to retrieve the current parse token. This is useful after p_parse() returns a P_UNEXPECTED_TOKEN value. terminate code after p_parse() returns a P_USER_TERMINATED value to indicate what token the parser was not expecting.

Example:

if (p_parse(context) == P_UNEXPECTED_TOKEN)
{
    p_token_t unexpected_token = p_token(context);
}

5.3.10 p_decode_code_point

The p_decode_code_point() function can be used to decode code points from a UTF-8 string. It does not require a lexer/parser context structure and can be used as a standalone UTF-8 decoder or from within a lexer or parser user code block.

D Example:

size_t result;
p_code_point_t code_point;
ubyte code_point_length;

result = p_decode_code_point("\xf0\x9f\xa7\xa1", &code_point, &code_point_length);
assert(result == P_SUCCESS);
assert(code_point == 0x1F9E1u);
assert(code_point_length == 4u);

5.3.11 p_tree_delete

The p_tree_delete() function can be used to free the memory used by the tree. It should be passed the same value that is returned by p_result().

Note that if any lexer user code block allocates memory to store in a token's pvalue, in order to properly free this memory the free_token_node statement should be used to provide a code block that frees this memory. If specified, the free_token_node code block will be executed during the p_tree_delete() process to allow user code to free any memory associated with a token node's pvalue.

When multiple start rules are specified, a separate p_tree_delete function is generated for each which frees the tree resulting from parsing the given rule. For example, if Statement is specified as a start rule:

p_tree_delete_Statement(statement_tree);

In this case, Propane will free a Statement tree structure returned by the p_parse_Statement(context) function.