/* SPDX-License-Identifier: GPL-3.0-only */ /* * Since we do not supply yywrap(), we use noyywrap to instruct the scanner to * behave as though yywrap() returned 1. */ %option noyywrap /* * We don't want symbols to clash with those of other flex users, particularly * lopsub. */ %option prefix="txp_yy" /* * Generate a scanner that maintains the number of the current line read from * its input in the yylineno variable. */ %option yylineno /* Generate a bison-compatible scanner. */ %option bison-bridge bison-locations /* * Warn (in particular) if the default rule can be matched but no default rule * has been given. */ %option warn /* * Generate a scanner which is portable and safe to use in one or more threads * of control. */ %option reentrant /* * Generate a scanner which always looks one extra character ahead. This is a * bit faster than an interactive scanner for which look ahead happens only * when necessary. */ %option never-interactive %{ #include "tf.h" #define YYSTYPE TXP_YYSTYPE #define YYLTYPE TXP_YYLTYPE #define YY_DECL int txp_yylex(TXP_YYSTYPE *yylval_param, TXP_YYLTYPE *yylloc_param, \ struct txp_context *ctx, struct txp_ast_node **ast, txp_yyscan_t yyscanner) #include "txp.bison.h" #define TXP_YY_USER_ACTION do {txp_yylloc->first_line = txp_yylineno;} while (0); %} DECIMAL_CONSTANT (0|([[:digit:]]{-}[0])[[:digit:]]*) STRING_LITERAL \"([^\"\\\n]|(\\[\"\\abfnrtv]))*\" REGEX_PATTERN \/([^\/\\\n]|(\\[\/\\abfnrtv]))*\/([in])* %% tag {return TAG;} len {return LEN;} text {return TEXT;} true {return TRUE;} false {return FALSE;} [[:space:]]+|#.*\n /* skip comments and whitespace */ "("|")"|","|"+"|"-"|"*"|"/"|"<"|">" {return yytext[0];} "||" {return OR;} "&&" {return AND;} "!" {return NOT;} "==" {return EQUAL;} "!=" {return NOT_EQUAL;} "<=" {return LESS_OR_EQUAL;} ">=" {return GREATER_OR_EQUAL;} "=~" {return REGEX_MATCH;} {DECIMAL_CONSTANT} { int ret; yylval->node = txp_new_ast_leaf_node(NUM); ret = atoi64(yytext, &yylval->node->sv.intval); if (ret < 0) { free(yylval->node); txp_parse_error(yylloc->first_line, ctx, "%s: %s", yytext, tf_strerror(-ret)); return -E_TXP; } return NUM; } {STRING_LITERAL} { yylval->node = txp_new_ast_leaf_node(STRING_LITERAL); parse_quoted_string(yytext, "\"\"", &yylval->node->sv.strval); return STRING_LITERAL; } {REGEX_PATTERN} { int ret; yylval->node = txp_new_ast_leaf_node(REGEX_PATTERN); ret = txp_parse_regex_pattern(yytext, &yylval->node->sv.re_pattern); if (ret < 0) { txp_parse_error(yylloc->first_line, ctx, "%s: %s", yytext, tf_strerror(-ret)); return -E_TXP; } return REGEX_PATTERN; } . { txp_parse_error(yylloc->first_line, ctx, "unrecognized text: %s", yytext); return -E_TXP; }