cmake: let generated lexer.c, parser.c depend on their respective source files, clean...
[oweals/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 static char *str_ptr;
23 static char str_buf[128];
24
25 static void
26 str_put(char c)
27 {
28         if ((str_ptr - str_buf + 1) < sizeof(str_buf))
29                 *str_ptr++ = c;
30 }
31
32 static void
33 str_decode(const char *input, int base)
34 {
35         int code;
36         char *end;
37
38         code = strtoul(input, &end, base);
39
40         if (end == input || *end)
41                 return;
42
43         if (code > 0 && code <= 0x7F)
44         {
45                 str_put(code);
46         }
47         else if (code > 0 && code <= 0x7FF)
48         {
49                 str_put(((code >>  6) & 0x1F) | 0xC0);
50                 str_put(( code        & 0x3F) | 0x80);
51         }
52         else if (code > 0 && code <= 0xFFFF)
53         {
54                 str_put(((code >> 12) & 0x0F) | 0xE0);
55                 str_put(((code >>  6) & 0x3F) | 0x80);
56                 str_put(( code        & 0x3F) | 0x80);
57         }
58         else if (code > 0 && code <= 0x10FFFF)
59         {
60                 str_put(((code >> 18) & 0x07) | 0xF0);
61                 str_put(((code >> 12) & 0x3F) | 0x80);
62                 str_put(((code >>  6) & 0x3F) | 0x80);
63                 str_put(( code        & 0x3F) | 0x80);
64         }
65 }
66
67 %}
68
69 %option outfile="lexer.c" header-file="lexer.h"
70 %option noyywrap nounput noinput
71
72 DOT                     "."
73 LABEL           [a-zA-Z_][a-zA-Z0-9_]*
74
75 BROPEN          "["
76 BRCLOSE         "]"
77 POPEN           "("
78 PCLOSE          ")"
79
80 ROOT            "$"
81 THIS            "@"
82
83 LT                      "<"
84 LE                      "<="
85 GT                      ">"
86 GE                      ">="
87 NE                      "!="
88 EQ                      "="
89 NOT                     "!"
90 AND                     "&&"
91 OR                      "||"
92
93 NUMBER          -?[0-9]+
94 WILDCARD        "*"
95 BOOL            (true|false)
96
97 WS                      [ \t\n]*
98
99 %x                      STRING
100
101 %%
102
103 \" {
104         str_ptr = str_buf;
105         memset(str_buf, 0, sizeof(str_buf));
106         BEGIN(STRING);
107 }
108
109 <STRING>{
110         \" {
111                 BEGIN(INITIAL);
112                 yylval.op = jp_alloc_op(T_STRING, 0, str_buf);
113                 return T_STRING;
114         }
115
116         \\([0-3][0-7]{1,2}|[0-7]{0,2})  { str_decode(yytext + 1, 8); }
117         \\x[A-Fa-f0-9]{2}                               { str_decode(yytext + 2, 16); }
118         \\u[A-Fa-f0-9]{4}                               { str_decode(yytext + 2, 16); }
119         \\a                                                             { str_put('\a'); }
120         \\b                                                             { str_put('\b'); }
121         \\e                                                             { str_put('\e'); }
122         \\f                                                             { str_put('\f'); }
123         \\n                                                             { str_put('\n'); }
124         \\r                                                             { str_put('\r'); }
125         \\t                                                             { str_put('\t'); }
126         \\v                                                             { str_put('\v'); }
127         \\.                                                             { str_put(*yytext); }
128         [^\\"]+                                                 { while (*yytext) str_put(*yytext++); }
129 }
130
131 {BOOL} {
132         yylval.op = jp_alloc_op(T_BOOL, (*yytext == 't'), NULL);
133         return T_BOOL;
134 }
135
136 {NUMBER} {
137         yylval.op = jp_alloc_op(T_NUMBER, atoi(yytext), NULL);
138         return T_NUMBER;
139 }
140
141 {LABEL} {
142         yylval.op = jp_alloc_op(T_LABEL, 0, yytext);
143         return T_LABEL;
144 }
145
146 {WILDCARD} {
147         yylval.op = jp_alloc_op(T_WILDCARD, 0, NULL);
148         return T_WILDCARD;
149 }
150
151 {DOT}           { return T_DOT; }
152 {BROPEN}        { return T_BROPEN; }
153 {BRCLOSE}       { return T_BRCLOSE; }
154 {POPEN}         { return T_POPEN; }
155 {PCLOSE}        { return T_PCLOSE; }
156
157 {ROOT}          { return T_ROOT; }
158 {THIS}          { return T_THIS; }
159
160 {LT}            { return T_LT; }
161 {LE}            { return T_LE; }
162 {GT}            { return T_GT; }
163 {GE}            { return T_GE; }
164 {EQ}            { return T_EQ; }
165 {NE}            { return T_NE; }
166 {NOT}           { return T_NOT; }
167 {AND}           { return T_AND; }
168 {OR}            { return T_OR; }
169
170 {WS}            { }
171
172 %%