]>
Commit | Line | Data |
---|---|---|
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 | |
11 | int yylex(void); | |
12 | extern char *parseStrError; | |
9b276ca6 | 13 | extern int parseStrErrorPos; |
ffc11f03 CP |
14 | |
15 | #define MAXSTACKSIZE 50 | |
16 | ||
17 | typedef struct parserlist { | |
18 | searchASTExpr expr; | |
19 | struct parserlist *next; | |
20 | } parserlist; | |
21 | ||
ffc11f03 CP |
22 | static int stackpos; |
23 | static parserlist *stack[MAXSTACKSIZE]; | |
24 | static int stackcount[MAXSTACKSIZE]; | |
25 | static fnFinder functionfinder; | |
26 | static void *fnfarg; | |
27 | static parsertree **presult, sresult; | |
28 | ||
9b276ca6 CP |
29 | extern int lexerror, lexpos; |
30 | void yystrerror(const char *format, ...); | |
31 | void lexreset(void); | |
32 | ||
ffc11f03 CP |
33 | void 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 | ||
48 | void 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 | ||
59 | void 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 | %% | |
77 | invocation: 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 | ||
132 | function: 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 | ||
145 | argumentlist: /* empty */ | WHITESPACE argument argumentlist; | |
146 | ||
147 | argument: | |
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 | 172 | literal: IDENTIFIER | STRING; |