-
Notifications
You must be signed in to change notification settings - Fork 13
/
query-parser.y
89 lines (69 loc) · 2.49 KB
/
query-parser.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
%{
#include <stdio.h>
#include <string.h>
#include "query.h"
#include "query-parser.h"
#include "query-parser.tab.h"
char* strdup(const char* wtf);
#define scanner context->scanner
int query_parser_lex(YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,void* yyscanner);
void query_parser_error(YYLTYPE* locp, query_parse_context* context, const char* err);
%}
// see http://www.phpcompiler.org/articles/reentrantparser.html
%name-prefix="query_parser_"
//%define api.pure too advanced for the old-ass version of bison on os x apparently
%pure-parser
%locations
%defines
%error-verbose
%parse-param { query_parse_context* context }
%lex-param { void* scanner }
%union {
wp_query* query;
char* string;
}
%token <string> WORD
%left <string> OR
%type <query> query atom disj parens phrase words result
%%
result: query { context->result = $$; }
;
query: { $$ = NULL; }
| query atom { if($1 == NULL) $$ = $2;
else if($1->type == WP_QUERY_CONJ) $$ = wp_query_add($1, $2);
else {
$$ = wp_query_new_conjunction();
$$ = wp_query_add($$, $1);
$$ = wp_query_add($$, $2);
}
}
| query disj { if($1 == NULL) $$ = $2;
else if($1->type == WP_QUERY_CONJ) $$ = wp_query_add($1, $2);
else {
$$ = wp_query_new_conjunction();
$$ = wp_query_add($$, $1);
$$ = wp_query_add($$, $2);
}
}
;
disj: atom OR atom { $$ = wp_query_new_disjunction(); $$ = wp_query_add($$, $1); $$ = wp_query_add($$, $3); }
| disj OR atom { $$ = wp_query_add($1, $3); }
;
atom: WORD { $$ = wp_query_new_term(strdup(context->default_field), $1); }
| parens
| phrase
| WORD ':' WORD { $$ = wp_query_new_term($1, $3); }
| WORD ':' parens { $$ = wp_query_set_all_child_fields($3, $1); }
| WORD ':' phrase { $$ = wp_query_set_all_child_fields($3, $1); }
| '-' atom { $$ = wp_query_new_negation(); $$ = wp_query_add($$, $2); }
| '~' WORD { $$ = wp_query_new_label($2); }
| '*' { $$ = wp_query_new_every(); }
;
phrase: '"' words '"' { $$ = $2; }
;
words: WORD { $$ = wp_query_new_phrase(); $$ = wp_query_add($$, wp_query_new_term(strdup(context->default_field), $1)); }
| words WORD { $$ = wp_query_add($1, wp_query_new_term(strdup(context->default_field), $2)); }
;
parens: '(' query ')' { $$ = $2; }
;
%%