]> mj.ucw.cz Git - umpf.git/blob - cond.y
lex
[umpf.git] / cond.y
1 %{
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <pcre.h>
6
7 #define OVECCOUNT 3
8
9 int yylex (void);
10 void yyerror (char const *);
11
12 int regex_cmp(char* s, char* r);
13
14 %}
15
16 %union {
17         int b;  
18         int n;
19         char* str;
20 }
21
22 %token <str> CONST
23 %token <str> REGEX
24 %token ERR
25 %token <n> NUM
26 %token <str> VAR
27 %token KW_IF KW_ELSE KW_PIPE KW_MAIL KW_COPY
28 %token '(' ')' '{' '}'
29 %left ARROW
30 %left EQ NEQ GE LE '<' '>' RE NRE
31 %left '+' '-' 
32 %left '*' '/'
33 %left '|' '&' '^'
34 %left '!'
35 %left '=' 
36 %type <b> boo
37
38 %%
39 input:  /* empty */
40         | input line
41 ;
42
43 line:   '\n'
44         | boo '\n'              { printf("%s\n",$1?"true":"false"); }
45         | error '\n'            { yyerrok; }
46 ;
47
48 boo:     CONST EQ CONST         { $$ = ! strcmp($1, $3); }
49         | CONST NEQ CONST       { $$ = !! strcmp($1, $3); }
50         | CONST RE REGEX        { $$ = regex_cmp($1,$3) >= 0 }
51         | CONST NRE REGEX       { $$ = regex_cmp($1,$3) < 0 }
52         | NUM EQ NUM            { $$ = $1 == $3 }
53         | NUM NEQ NUM           { $$ = $1 != $3 }
54         | NUM GE NUM            { $$ = $1 >= $3 }
55         | NUM LE NUM            { $$ = $1 <= $3 }
56         | NUM '>' NUM           { $$ = $1 > $3 }
57         | NUM '<' NUM           { $$ = $1 < $3 }
58         | boo '|' boo           { $$ = $1 || $3 }
59         | boo '&' boo           { $$ = $1 && $3 }
60         | boo '^' boo           { $$ = ($1 || $3) && !($1 && $3) }
61         | '!' boo               { $$ = ! $2 }
62 ;
63
64 ;
65 %%
66
67 #include <ctype.h>
68 #include <stdlib.h>
69
70 #define BUFSIZE 4096
71
72 int 
73 regex_cmp(char* s, char* r)
74 {
75         pcre *brum;
76         int erroroffset;
77         const char* error;
78         int ovector[OVECCOUNT];
79         
80         brum=pcre_compile(r,0,&error,&erroroffset,NULL);
81         if (!brum)
82                 return -1;
83         
84         int res=pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT);
85         
86         pcre_free(brum);
87
88         return res;
89 }
90
91 char*
92 get_string_out(char delim)
93 {
94         int last = delim; 
95         int i = 0;
96         char* s;
97         int c;
98
99         if (!(s = malloc(BUFSIZE))){
100                 puts("Low memory");
101                 exit(0);
102         }
103
104         while ((c = getchar()) != delim || last == '\\'){
105                 if (last=='\\' && c != delim)
106                         s[i-1] = c;
107                 else {          
108                         s[i] = c;
109                         i++;
110                 }
111                 last = c;
112                 if (i >= BUFSIZE-1)
113                         break;
114         }       
115         s[i] = '\0';
116
117         return s;
118 }
119
120 int
121 safe_unget(char c)
122 {
123         if (c==EOF)
124                 return 0;
125
126         ungetc(c,stdin);
127         return 1;
128 }
129
130 int
131 yylex(void)
132 {
133
134         int c, last;
135         
136         while ((c = getchar ()) == ' ' || c == '\t');
137         
138         if (c == '"'){
139                 last = '"';
140                 yylval.str = get_string_out('"');
141                 return CONST;   
142         }
143
144         if (c == '\''){
145                 last = '\'';
146                 yylval.str = get_string_out('\'');
147                 return CONST;   
148         }
149
150         if (c == '/'){
151                 last = '/';
152                 yylval.str = get_string_out('/');       
153                 return REGEX;   
154         }
155
156         if (isdigit(c)){
157                 ungetc(c,stdin);
158                 scanf("%d",&yylval.n);
159                 return NUM;
160         }
161
162         if (c == '!'){
163                 if ((c = getchar ()) == '=')
164                         return NEQ;
165                 else if (c == '~')
166                         return NRE;
167                 else {
168                         safe_unget(c);
169                         return '!';     
170                 }
171         }
172
173         if (c == '<'){
174                 if ((c = getchar ()) == '=')
175                         return LE;
176                 else {
177                         safe_unget(c);
178                         return '<';
179                 }
180         }
181
182         if (c == '>'){
183                 if ((c = getchar ()) == '=')
184                         return GE;
185                 else {
186                         safe_unget(c);
187                         return '>'; 
188                 } 
189         }
190
191         if (c == '='){
192                 if ((c = getchar ()) == '=')
193                         return EQ;
194                 else {
195                         safe_unget(c);
196                         return '='; 
197                 }
198         }
199
200         if (c == '~'){
201                 if ((c = getchar ()) == '~')
202                         return RE;
203                 else {
204                         safe_unget(c);
205                         return ERR;
206                 }
207         }
208
209         if (c == '-'){
210                 if ((c = getchar ()) == '>')
211                         return ARROW;
212                 else {
213                         safe_unget(c);
214                         return '-';
215                 }
216         }
217
218         if (c == '$'){
219                 int i=0;
220         
221                 if (!(yylval.str=malloc(BUFSIZE))){
222                         puts("Low memory");
223                         exit (0);
224                 }
225                         
226                 while (isalnum(c = getchar()) || c == '_' || c == '-'){
227                         yylval.str[i]=c;
228                         i++;
229                         if (i >= BUFSIZE)
230                                 break;
231                 }
232
233                 return VAR;
234         }
235
236         if (c == '\n' || c == '+' || c == '*' || c == '/' ||
237                 c == '(' || c == ')' || c == '{' || c == '}')
238                 return c;
239
240 #define KLEN 10
241
242         if (isalpha(c)){
243                 char buf[KLEN]; 
244                 int i=0;
245
246                 ungetc(c,stdin);
247                 while (isalpha(c = getchar()) && i<KLEN-1)
248                         buf[i++]=c;
249                 buf[i]=0;
250                 
251                 if (!strcmp(buf,"if"))
252                         return KW_IF;
253                 else if (!strcmp(buf,"else"))
254                         return KW_ELSE;
255                 else if (!strcmp(buf,"pipe"))
256                         return KW_COPY;
257                 else if (!strcmp(buf,"mail"))
258                         return KW_MAIL;
259                 else if (!strcmp(buf,"copy"))
260                         return KW_COPY;
261                 else
262                         return ERR;
263         }
264         
265         if (c == EOF)
266                 return 0;
267         
268         return ERR;
269 }
270
271 void
272 yyerror (char const *s)
273 {
274         fprintf (stderr, "%s\n", s);
275 }
276
277 int
278 main(void)
279 {
280 //      yydebug=1;
281         return yyparse ();
282 }