]> mj.ucw.cz Git - umpf.git/blob - cond.y
do not unget EOF
[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 <n> NUM
25 %left EQ NEQ GE LE GT LT RE NRE
26 %left '|' '&' '^'
27 %left '!'
28 %type <b> boo
29
30 %%
31 input:  /* empty */
32         | input line
33 ;
34
35 line:   '\n'
36         | boo '\n'              { printf("%s\n",$1?"true":"false"); }
37         | error '\n'            { yyerrok; }
38 ;
39
40 boo:     CONST EQ CONST         { $$ = ! strcmp($1, $3); }
41         | CONST NEQ CONST       { $$ = !! strcmp($1, $3); }
42         | CONST RE REGEX        { $$ = regex_cmp($1,$3) >= 0 }
43         | CONST NRE REGEX       { $$ = regex_cmp($1,$3) < 0 }
44         | NUM EQ NUM            { $$ = $1 == $3 }
45         | NUM NEQ NUM           { $$ = $1 != $3 }
46         | NUM GE NUM            { $$ = $1 >= $3 }
47         | NUM LE NUM            { $$ = $1 <= $3 }
48         | NUM GT NUM            { $$ = $1 > $3 }
49         | NUM LT NUM            { $$ = $1 < $3 }
50         | boo '|' boo           { $$ = $1 || $3 }
51         | boo '&' boo           { $$ = $1 && $3 }
52         | boo '^' boo           { $$ = ($1 || $3) && !($1 && $3) }
53         | '!' boo               { $$ = ! $2 }
54 ;
55
56 ;
57 %%
58
59 #include <ctype.h>
60 #include <stdlib.h>
61
62 #define BUFSIZE 4096
63
64 int 
65 regex_cmp(char* s, char* r)
66 {
67         pcre *brum;
68         int erroroffset;
69         const char* error;
70         int ovector[OVECCOUNT];
71         
72         brum=pcre_compile(r,0,&error,&erroroffset,NULL);
73         if (!brum)
74                 return -1;
75         
76         int res=pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT);
77         
78         pcre_free(brum);
79
80         return res;
81 }
82
83 char*
84 get_string_out(char delim)
85 {
86         int last = delim; 
87         int i = 0;
88         char* s;
89         int c;
90
91         if (!(s = malloc(BUFSIZE))){
92                 puts("Low memory");
93                 exit(0);
94         }
95
96         while ((c = getchar()) != delim || last == '\\'){
97                 if (last=='\\' && c != delim)
98                         s[i-1] = c;
99                 else {          
100                         s[i] = c;
101                         i++;
102                 }
103                 last = c;
104                 if (i >= BUFSIZE-1)
105                         break;
106         }       
107         s[i] = '\0';
108
109         return s;
110 }
111
112 int
113 safe_unget(char c)
114 {
115         if (c==EOF)
116                 return 0;
117
118         ungetc(c,stdin);
119         return 1;
120 }
121
122 int
123 yylex(void)
124 {
125
126         int c, last;
127         
128         while ((c = getchar ()) == ' ' || c == '\t');
129         
130         if (c == '"'){
131                 last = '"';
132                 yylval.str = get_string_out('"');
133                 return CONST;   
134         }
135
136         if (c == '\''){
137                 last = '\'';
138                 yylval.str = get_string_out('\'');
139                 return CONST;   
140         }
141
142         if (c == '/'){
143                 last = '/';
144                 yylval.str = get_string_out('/');       
145                 return REGEX;   
146         }
147
148         if (isdigit(c)){
149                 ungetc(c,stdin);
150                 scanf("%d",&yylval.n);
151                 return NUM;
152         }
153
154         if (c == '!'){
155                 if ((c = getchar ()) == '=')
156                         return NEQ;
157                 else if (c == '~')
158                         return NRE;
159                 else
160                         if (! safe_unget(c))
161                                 return c;
162         }
163
164         if (c == '<'){
165                 if ((c = getchar ()) == '=')
166                         return LE;
167                 else
168                         return (safe_unget(c) ? LT : c); 
169         }
170
171         if (c == '>'){
172                 if ((c = getchar ()) == '=')
173                         return GE;
174                 else
175                         return (safe_unget(c) ? GT : c); 
176         }
177
178         if (c == '='){
179                 if ((c = getchar ()) == '=')
180                         return EQ;
181                 else
182                         if (! safe_unget(c))
183                                 return c;
184         }
185
186         if (c == '~'){
187                 if ((c = getchar ()) == '~')
188                         return RE;
189                 else
190                         if (! safe_unget(c))
191                                 return c;
192         }
193         
194         if (c == EOF)
195                 return 0;
196         
197         return c;
198 }
199
200 void
201 yyerror (char const *s)
202 {
203         fprintf (stderr, "%s\n", s);
204 }
205
206 int
207 main(void)
208 {
209         return yyparse ();
210 }