drgn/libdrgn/lexer.h
Omar Sandoval 8b264f8823 Update copyright headers to Facebook and add missing headers
drgn was originally my side project, but for awhile now it's also been
my work project. Update the copyright headers to reflect this, and add a
copyright header to various files that were missing it.
2020-05-15 15:13:02 -07:00

132 lines
3.1 KiB
C

// Copyright (c) Facebook, Inc. and its affiliates.
// SPDX-License-Identifier: GPL-3.0+
/**
* @file
*
* Lexer interface.
*
* See @ref Lexer.
*/
#ifndef DRGN_LEXER_H
#define DRGN_LEXER_H
#include <stddef.h>
#include "vector.h"
/**
* @ingroup Internals
*
* @defgroup Lexer Lexer
*
* Lexical analysis.
*
* This is a convenient interface for lexical analysis. @ref drgn_lexer provides
* the abstraction of a stack of tokens (@ref drgn_token) on top of a raw @ref
* drgn_lexer_func.
*
* @{
*/
struct drgn_error;
struct drgn_lexer;
struct drgn_token;
/**
* Lexer function.
*
* A lexer function does the work of lexing the next token in a string. It
* should initialize the passed in token and advance @ref drgn_lexer::p.
*/
typedef struct drgn_error *(*drgn_lexer_func)(struct drgn_lexer *,
struct drgn_token *);
/** Lexical token. */
struct drgn_token {
/** Kind of token as defined by the lexer function. */
int kind;
/**
* String value of the token (i.e., the lexeme).
*
* This points to the contents of the original string, so it isn't
* null-terminated.
*/
const char *value;
/** Length of the token value. */
size_t len;
};
DEFINE_VECTOR_TYPE(drgn_token_vector, struct drgn_token)
/**
* Lexer instance.
*
* A lexer comprises a lexer function, a position, and a stack of tokens. Tokens
* can be pushed and popped onto the stack. When the stack is empty, a pop calls
* the lexer function instead.
*/
struct drgn_lexer {
/** Lexer function. */
drgn_lexer_func func;
/** Current position in the string. */
const char *p;
/** Stack of tokens. */
struct drgn_token_vector stack;
};
/**
* Initialize a @ref drgn_lexer from a lexer function and a string.
*
* @param[in] lexer Lexer to initialize.
* @param[in] func Lexer function.
* @param[in] str String to lex.
*/
void drgn_lexer_init(struct drgn_lexer *lexer, drgn_lexer_func func,
const char *str);
/**
* Free memory allocated by a @ref drgn_lexer.
*
* @param[in] lexer Lexer to deinitialize.
*/
void drgn_lexer_deinit(struct drgn_lexer *lexer);
/**
* Return the next token from a @ref drgn_lexer.
*
* If there are tokens on the stack, this pops and returns the top token.
* Otherwise, this calls the lexer function to get the next token.
*
* @return @c NULL on success, non-@c NULL on error.
*/
struct drgn_error *drgn_lexer_pop(struct drgn_lexer *lexer,
struct drgn_token *token);
/**
* Push a token onto the stack of a @ref drgn_lexer.
*
* This token must have been returned by @ref drgn_lexer_pop().
*
* @return @c NULL on success, non-@c NULL on error.
*/
struct drgn_error *drgn_lexer_push(struct drgn_lexer *lexer,
const struct drgn_token *token);
/**
* Return the next token from a @ref drgn_lexer and leave it on top of the
* stack.
*
* This is equivalent to a call to @ref drgn_lexer_pop() immediately followed by
* a call to @ref drgn_lexer_push().
*
* @return @c NULL on success, non-@c NULL on error.
*/
struct drgn_error *drgn_lexer_peek(struct drgn_lexer *lexer,
struct drgn_token *token);
/** @} */
#endif /* DRGN_LEXER_H */