debian: Remove hard-coded dependency on liblopsub1.
[tfortune.git] / txp.lex
1 /* SPDX-License-Identifier: GPL-3.0-only */
2
3  /*
4   * Since we do not supply yywrap(), we use noyywrap to instruct the scanner to
5   * behave as though yywrap() returned 1.
6   */
7 %option noyywrap
8
9  /*
10   * We don't want symbols to clash with those of other flex users, particularly
11   * lopsub.
12   */
13 %option prefix="txp_yy"
14
15  /*
16   * Generate a scanner that maintains the number of the current line read from
17   * its input in the yylineno variable.
18   */
19 %option yylineno
20
21  /* Generate a bison-compatible scanner. */
22 %option bison-bridge bison-locations
23
24  /*
25   * Warn (in particular) if the default rule can be matched but no default rule
26   * has been given.
27   */
28 %option warn
29
30  /*
31   * Generate a scanner which is portable and safe to use in one or more threads
32   * of control.
33   */
34 %option reentrant
35
36  /*
37   * Generate a scanner which always looks one extra character ahead. This is a
38   * bit faster than an interactive scanner for which look ahead happens only
39   * when necessary.
40   */
41 %option never-interactive
42
43 %{
44 #include "tf.h"
45
46 #define YYSTYPE TXP_YYSTYPE
47 #define YYLTYPE TXP_YYLTYPE
48 #define YY_DECL int txp_yylex(TXP_YYSTYPE *yylval_param, TXP_YYLTYPE *yylloc_param, \
49         struct txp_context *ctx, struct txp_ast_node **ast, txp_yyscan_t yyscanner)
50 #include "txp.bison.h"
51 #define TXP_YY_USER_ACTION do {txp_yylloc->first_line = txp_yylineno;} while (0);
52 %}
53 DECIMAL_CONSTANT  (0|([[:digit:]]{-}[0])[[:digit:]]*)
54 STRING_LITERAL    \"([^\"\\\n]|(\\[\"\\abfnrtv]))*\"
55 REGEX_PATTERN     \/([^\/\\\n]|(\\[\/\\abfnrtv]))*\/([in])*
56 %%
57
58 tag {return TAG;}
59 len {return LEN;}
60 text {return TEXT;}
61 true {return TRUE;}
62 false {return FALSE;}
63
64 [[:space:]]+|#.*\n /* skip comments and whitespace */
65
66 "("|")"|","|"+"|"-"|"*"|"/"|"<"|">" {return yytext[0];}
67
68 "||" {return OR;}
69 "&&" {return AND;}
70 "!" {return NOT;}
71 "==" {return EQUAL;}
72 "!=" {return NOT_EQUAL;}
73 "<=" {return LESS_OR_EQUAL;}
74 ">=" {return GREATER_OR_EQUAL;}
75 "=~" {return REGEX_MATCH;}
76
77 {DECIMAL_CONSTANT} {
78         int ret;
79         yylval->node = txp_new_ast_leaf_node(NUM);
80         ret = atoi64(yytext, &yylval->node->sv.intval);
81         if (ret < 0) {
82                 free(yylval->node);
83                 txp_parse_error(yylloc->first_line, ctx, "%s: %s", yytext,
84                         tf_strerror(-ret));
85                 return -E_TXP;
86         }
87         return NUM;
88 }
89
90 {STRING_LITERAL} {
91         yylval->node = txp_new_ast_leaf_node(STRING_LITERAL);
92         parse_quoted_string(yytext, "\"\"", &yylval->node->sv.strval);
93         return STRING_LITERAL;
94 }
95
96 {REGEX_PATTERN} {
97         int ret;
98         yylval->node = txp_new_ast_leaf_node(REGEX_PATTERN);
99         ret = txp_parse_regex_pattern(yytext, &yylval->node->sv.re_pattern);
100         if (ret < 0) {
101                 txp_parse_error(yylloc->first_line, ctx, "%s: %s", yytext,
102                         tf_strerror(-ret));
103                 return -E_TXP;
104         }
105         return REGEX_PATTERN;
106 }
107
108 . {
109         txp_parse_error(yylloc->first_line, ctx, "unrecognized text: %s",
110                 yytext);
111         return -E_TXP;
112 }