summaryrefslogtreecommitdiff
path: root/txp.lex
diff options
context:
space:
mode:
Diffstat (limited to 'txp.lex')
-rw-r--r--txp.lex111
1 files changed, 111 insertions, 0 deletions
diff --git a/txp.lex b/txp.lex
new file mode 100644
index 0000000..4b04fb3
--- /dev/null
+++ b/txp.lex
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+ /*
+ * 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;}
+num_lines {return NUM_LINES;}
+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;
+}