18937e888355774c04e7d7883d8a017b19ad08a5
[project/jsonpath.git] / lexer.l
1 %{
2 /*
3 * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <ctype.h>
19
20 #include "parser.h"
21
22 int yylex(struct jp_state *s);
23
24 #define YY_DECL int yylex(struct jp_state *s)
25
26 static void
27 str_put(struct jp_state *s, char c)
28 {
29 if ((s->str_ptr - s->str_buf + 1) < sizeof(s->str_buf))
30 *s->str_ptr++ = c;
31 }
32
33 static void
34 str_decode(struct jp_state *s, const char *input, int base)
35 {
36 int code;
37 char *end;
38
39 code = strtoul(input, &end, base);
40
41 if (end == input || *end)
42 return;
43
44 if (code > 0 && code <= 0x7F)
45 {
46 str_put(s, code);
47 }
48 else if (code > 0 && code <= 0x7FF)
49 {
50 str_put(s, ((code >> 6) & 0x1F) | 0xC0);
51 str_put(s, ( code & 0x3F) | 0x80);
52 }
53 else if (code > 0 && code <= 0xFFFF)
54 {
55 str_put(s, ((code >> 12) & 0x0F) | 0xE0);
56 str_put(s, ((code >> 6) & 0x3F) | 0x80);
57 str_put(s, ( code & 0x3F) | 0x80);
58 }
59 else if (code > 0 && code <= 0x10FFFF)
60 {
61 str_put(s, ((code >> 18) & 0x07) | 0xF0);
62 str_put(s, ((code >> 12) & 0x3F) | 0x80);
63 str_put(s, ((code >> 6) & 0x3F) | 0x80);
64 str_put(s, ( code & 0x3F) | 0x80);
65 }
66 }
67
68 %}
69
70 %option outfile="lexer.c" header-file="lexer.h"
71 %option noyywrap nounput noinput
72
73 DOT "."
74 LABEL [a-zA-Z_][a-zA-Z0-9_]*
75
76 BROPEN "["
77 BRCLOSE "]"
78 POPEN "("
79 PCLOSE ")"
80
81 ROOT "$"
82 THIS "@"
83
84 LT "<"
85 LE "<="
86 GT ">"
87 GE ">="
88 NE "!="
89 EQ "="
90 NOT "!"
91 AND "&&"
92 OR "||"
93
94 NUMBER -?[0-9]+
95 WILDCARD "*"
96 BOOL (true|false)
97
98 WS [ \t\n]*
99
100 %x STRING
101
102 %%
103
104 ["'] {
105 s->str_ptr = s->str_buf;
106 s->str_quote = *yytext;
107 memset(s->str_buf, 0, sizeof(s->str_buf));
108 BEGIN(STRING);
109 }
110
111 <STRING>{
112 ["'] {
113 if (*yytext == s->str_quote)
114 {
115 BEGIN(INITIAL);
116 yylval.op = jp_alloc_op(T_STRING, 0, s->str_buf);
117 return T_STRING;
118 }
119
120 str_put(s, *yytext);
121 }
122
123 \\([0-3][0-7]{1,2}|[0-7]{0,2}) { str_decode(s, yytext + 1, 8); }
124 \\x[A-Fa-f0-9]{2} { str_decode(s, yytext + 2, 16); }
125 \\u[A-Fa-f0-9]{4} { str_decode(s, yytext + 2, 16); }
126 \\a { str_put(s, '\a'); }
127 \\b { str_put(s, '\b'); }
128 \\e { str_put(s, '\e'); }
129 \\f { str_put(s, '\f'); }
130 \\n { str_put(s, '\n'); }
131 \\r { str_put(s, '\r'); }
132 \\t { str_put(s, '\t'); }
133 \\v { str_put(s, '\v'); }
134 \\. { str_put(s, *yytext); }
135 [^\\"']+ { while (*yytext) str_put(s, *yytext++); }
136 }
137
138 {BOOL} {
139 yylval.op = jp_alloc_op(T_BOOL, (*yytext == 't'), NULL);
140 return T_BOOL;
141 }
142
143 {NUMBER} {
144 yylval.op = jp_alloc_op(T_NUMBER, atoi(yytext), NULL);
145 return T_NUMBER;
146 }
147
148 {LABEL} {
149 yylval.op = jp_alloc_op(T_LABEL, 0, yytext);
150 return T_LABEL;
151 }
152
153 {WILDCARD} {
154 yylval.op = jp_alloc_op(T_WILDCARD, 0, NULL);
155 return T_WILDCARD;
156 }
157
158 {DOT} { return T_DOT; }
159 {BROPEN} { return T_BROPEN; }
160 {BRCLOSE} { return T_BRCLOSE; }
161 {POPEN} { return T_POPEN; }
162 {PCLOSE} { return T_PCLOSE; }
163
164 {ROOT} { return T_ROOT; }
165 {THIS} { return T_THIS; }
166
167 {LT} { return T_LT; }
168 {LE} { return T_LE; }
169 {GT} { return T_GT; }
170 {GE} { return T_GE; }
171 {EQ} { return T_EQ; }
172 {NE} { return T_NE; }
173 {NOT} { return T_NOT; }
174 {AND} { return T_AND; }
175 {OR} { return T_OR; }
176
177 {WS} { }
178
179 %%