]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/newsearch.y
LUA: port luadb to dbapi2 to drop postgres dependency
[irc/quakenet/newserv.git] / newsearch / newsearch.y
CommitLineData
ffc11f03
CP
1%{
2#include <stdio.h>
3#include <string.h>
9b276ca6 4#include <stdarg.h>
ffc11f03
CP
5#include "../lib/stringbuf.h"
6#include "newsearch.h"
7#include "parser.h"
8
e828314e 9#define YYSTYPE sstring *
ffc11f03
CP
10
11int yylex(void);
12extern char *parseStrError;
9b276ca6 13extern int parseStrErrorPos;
ffc11f03
CP
14
15#define MAXSTACKSIZE 50
16
17typedef struct parserlist {
18 searchASTExpr expr;
19 struct parserlist *next;
20} parserlist;
21
ffc11f03
CP
22static int stackpos;
23static parserlist *stack[MAXSTACKSIZE];
24static int stackcount[MAXSTACKSIZE];
25static fnFinder functionfinder;
26static void *fnfarg;
27static parsertree **presult, sresult;
28
9b276ca6
CP
29extern int lexerror, lexpos;
30void yystrerror(const char *format, ...);
31void lexreset(void);
32
ffc11f03
CP
33void resetparser(fnFinder fnf, void *arg, parsertree **result) {
34 presult = result;
1a4268e5 35 *presult = &sresult;
ffc11f03
CP
36
37 sresult.exprlist = NULL;
38 sresult.strlist = NULL;
39 sresult.finished = 0;
1a4268e5 40
ffc11f03
CP
41 functionfinder = fnf;
42 fnfarg = arg;
9b276ca6 43
ffc11f03 44 stackpos = 0;
9b276ca6
CP
45 lexreset();
46}
47
48void yyerror(const char *str) {
49 if(lexerror) {
50 lexerror = 0;
51 yystrerror("lexical error");
52 return;
53 }
54
55 parseStrError = (char *)str;
56 parseStrErrorPos = lexpos;
57}
58
59void yystrerror(const char *format, ...) {
60 va_list va;
61 static char buf[512];
62
63 parse_free(&sresult);
64
65 va_start(va, format);
66 vsnprintf(buf, sizeof(buf), format, va);
67 va_end(va);
68
69 yyerror(buf);
ffc11f03
CP
70}
71
72%}
73
74%token LPAREN RPAREN WHITESPACE IDENTIFIER STRING
75
76%%
77invocation: LPAREN function argumentlist RPAREN
78 {
e828314e 79 sstring *str = $2;
ffc11f03
CP
80 int i, count;
81 searchASTExpr *ap, *root;
82 parserlist *pp, *npp;
83 expressionlist *xl;
84 parseFunc pfn;
85
86 stackpos--;
87 count = stackcount[stackpos];
88
91bf3d57 89 pfn = functionfinder(str->content, fnfarg);
ffc11f03 90 if(!pfn) {
9b276ca6 91 yystrerror("unknown function: %s", str->content);
ffc11f03
CP
92 YYERROR;
93 }
94 /* if we're at the top of the stack we're the root of the tree */
95 if(stackpos != 0) {
96 /*
97 * we store this function containing its children in the stack list
98 * as there might be functions or other stuff after it, such as:
99 * (fn (fn2) moo moo)
100 */
101 parserlist *rootp = malloc(sizeof(searchASTExpr) + sizeof(parserlist));
102 root = &rootp->expr;
103
104 stackcount[stackpos-1]++;
105 rootp->next = stack[stackpos-1];
106 stack[stackpos-1] = rootp;
107 } else {
108 /* need space for the final result and real root */
109 *presult = malloc(sizeof(parsertree) + sizeof(searchASTExpr));
110
111 memcpy(*presult, &sresult, sizeof(parsertree));
112 (*presult)->finished = 1;
113
114 root = (*presult)->root;
115 }
116
117 xl = malloc(sizeof(expressionlist) + sizeof(searchASTExpr) * count);
118 xl->next = (*presult)->exprlist;
119 (*presult)->exprlist = xl;
120
121 ap = xl->expr;
122 for(i=count-1,pp=stack[stackpos];i>=0;i--,pp=npp) {
123 npp = pp->next;
124 memcpy(&ap[i], &pp->expr, sizeof(searchASTExpr));
125 free(pp);
126 }
127 *root = NSASTManualNode(pfn, count, ap);
128
e828314e 129 freesstring(str);
ffc11f03
CP
130 }
131
132function: IDENTIFIER
133 {
9b276ca6
CP
134 if(stackpos >= MAXSTACKSIZE - 1) {
135 yyerror("function stack overflow");
ffc11f03 136 YYERROR;
9b276ca6
CP
137 }
138
ffc11f03
CP
139 stackcount[stackpos] = 0;
140 stack[stackpos] = NULL;
141
142 stackpos++;
143 };
144
145argumentlist: /* empty */ | WHITESPACE argument argumentlist;
146
147argument:
148 invocation | literal
149 {
e828314e 150 sstring *str = $1;
1a4268e5 151 parserlist *l = malloc(sizeof(parserlist));
1c105527
CP
152
153 if(str) {
154 stringlist *sl;
155 l->expr = NSASTLiteral(str->content);
156
157 sl = malloc(sizeof(stringlist));
158 sl->data = str;
159 sl->next = (*presult)->strlist;
160 (*presult)->strlist = sl;
161 } else {
162 l->expr = NSASTLiteral("");
163 }
164
ffc11f03
CP
165 l->next = stack[stackpos - 1];
166 stack[stackpos - 1] = l;
167 stackcount[stackpos - 1]++;
168
ffc11f03
CP
169 }
170 ;
171
e828314e 172literal: IDENTIFIER | STRING;