/* * pgbench Expression Tokenizer -- Public Interface * * Hand-written tokenizer that implements the lexical analysis from * PostgreSQL's src/bin/pgbench/exprscan.l, adapted for use with * a Lime-generated parser. * * The tokenizer handles: * - Case-insensitive keywords (AND, OR, NOT, CASE, WHEN, etc.) * - Variables (:name) * - Integer constants (decimal) * - Double constants (decimal with '.', 'e'/'E' exponent) * - Boolean constants (TRUE, FALSE) * - NULL constant * - The special INT64_MIN overflow literal "9223372036854775808" * - All arithmetic, comparison, bitwise, and logical operators * - Function names (identifiers not matching a keyword) * * Token codes come from pgbench_expr.h (generated by Lime). * * Usage: * PgbenchScanner *s = pgbench_scanner_create(input, len); * TokenValue val; * int tok; * while ((tok = pgbench_scan(s, &val)) > 0) { * pgbenchExprParse(parser, tok, val, pstate); * } * pgbenchExprParse(parser, 0, empty_val, pstate); * pgbench_scanner_destroy(s); */ #ifndef PGBENCH_TOKENIZE_H #define PGBENCH_TOKENIZE_H #include #include #include /* Token code defines from the Lime-generated parser header. */ #include "pgbench_expr.h" #ifdef __cplusplus extern "C" { #endif /* ====================================================================== * Semantic value type * * Matches the %token_type in the Lime grammar. * ====================================================================== */ typedef union TokenValue { int64_t ival; /* Integer constants, function numbers */ double dval; /* Double constants */ bool bval; /* Boolean constants */ char *str; /* Variable names, function names */ } TokenValue; /* ====================================================================== * Opaque scanner handle * ====================================================================== */ typedef struct PgbenchScanner PgbenchScanner; /* ====================================================================== * Scanner lifecycle * ====================================================================== */ /* * Create a scanner for the given input string. * The input must remain valid for the lifetime of the scanner. */ PgbenchScanner *pgbench_scanner_create(const char *input, size_t length); /* * Destroy a scanner and free resources. Passing NULL is a no-op. */ void pgbench_scanner_destroy(PgbenchScanner *s); /* ====================================================================== * Token extraction * ====================================================================== */ /* * Extract the next token from the input. * * Returns: * > 0 Token code from pgbench_expr.h * 0 End of input * -1 Lexical error (call pgbench_scanner_error() for details) * * On success, *val is filled with the semantic value. * Caller owns any val->str pointer returned (must free when done). */ int pgbench_scan(PgbenchScanner *s, TokenValue *val); /* ====================================================================== * Error reporting * ====================================================================== */ /* * Return the last error message, or NULL if no error. */ const char *pgbench_scanner_error(const PgbenchScanner *s); /* * Return the byte offset of the last error, or -1. */ int pgbench_scanner_error_location(const PgbenchScanner *s); /* ====================================================================== * Debugging * ====================================================================== */ /* * Return a human-readable name for a token code. */ const char *pgbench_token_name(int token); #ifdef __cplusplus } #endif #endif /* PGBENCH_TOKENIZE_H */