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