]> jfr.im git - irc/quakenet/newserv.git/blame - newsearch/newsearch.y
I do wonder how this worked on FreeBSD (newsearch parser changes).
[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;
1a4268e5 34 *presult = &sresult;
ffc11f03
CP
35
36 sresult.exprlist = NULL;
37 sresult.strlist = NULL;
38 sresult.finished = 0;
1a4268e5 39
ffc11f03
CP
40 functionfinder = fnf;
41 fnfarg = arg;
42
43 stackpos = 0;
44}
45
46%}
47
48%token LPAREN RPAREN WHITESPACE IDENTIFIER STRING
49
50%%
51invocation: LPAREN function argumentlist RPAREN
52 {
e828314e 53 sstring *str = $2;
ffc11f03
CP
54 int i, count;
55 searchASTExpr *ap, *root;
56 parserlist *pp, *npp;
57 expressionlist *xl;
58 parseFunc pfn;
59
60 stackpos--;
61 count = stackcount[stackpos];
62
91bf3d57 63 pfn = functionfinder(str->content, fnfarg);
ffc11f03
CP
64 if(!pfn) {
65 parse_free(&sresult);
66 YYERROR;
67 }
68 /* if we're at the top of the stack we're the root of the tree */
69 if(stackpos != 0) {
70 /*
71 * we store this function containing its children in the stack list
72 * as there might be functions or other stuff after it, such as:
73 * (fn (fn2) moo moo)
74 */
75 parserlist *rootp = malloc(sizeof(searchASTExpr) + sizeof(parserlist));
76 root = &rootp->expr;
77
78 stackcount[stackpos-1]++;
79 rootp->next = stack[stackpos-1];
80 stack[stackpos-1] = rootp;
81 } else {
82 /* need space for the final result and real root */
83 *presult = malloc(sizeof(parsertree) + sizeof(searchASTExpr));
84
85 memcpy(*presult, &sresult, sizeof(parsertree));
86 (*presult)->finished = 1;
87
88 root = (*presult)->root;
89 }
90
91 xl = malloc(sizeof(expressionlist) + sizeof(searchASTExpr) * count);
92 xl->next = (*presult)->exprlist;
93 (*presult)->exprlist = xl;
94
95 ap = xl->expr;
96 for(i=count-1,pp=stack[stackpos];i>=0;i--,pp=npp) {
97 npp = pp->next;
98 memcpy(&ap[i], &pp->expr, sizeof(searchASTExpr));
99 free(pp);
100 }
101 *root = NSASTManualNode(pfn, count, ap);
102
e828314e 103 freesstring(str);
ffc11f03
CP
104 }
105
106function: IDENTIFIER
107 {
108 if(stackpos >= MAXSTACKSIZE - 1)
109 YYERROR;
110
111 stackcount[stackpos] = 0;
112 stack[stackpos] = NULL;
113
114 stackpos++;
115 };
116
117argumentlist: /* empty */ | WHITESPACE argument argumentlist;
118
119argument:
120 invocation | literal
121 {
e828314e 122 sstring *str = $1;
1a4268e5
CP
123 parserlist *l = malloc(sizeof(parserlist));
124 stringlist *sl = malloc(sizeof(stringlist));
ffc11f03 125
e828314e 126 l->expr = NSASTLiteral(str->content);
ffc11f03
CP
127 l->next = stack[stackpos - 1];
128 stack[stackpos - 1] = l;
129 stackcount[stackpos - 1]++;
130
e828314e 131 sl->data = str;
ffc11f03
CP
132 sl->next = (*presult)->strlist;
133 (*presult)->strlist = sl;
134 }
135 ;
136
e828314e 137literal: IDENTIFIER | STRING;