1 /*
2 *
3 * parser.c -
4 *
5 * Copyright (C) 1997-1999 Satoru Takabayashi All rights reserved.
6 * This is free software with ABSOLUTELY NO WARRANTY.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 * 02111-1307, USA
22 *
23 * This file must be encoded in EUC-JP encoding.
24 *
25 */
26
27 /*
28 * recursive parser: expr, orop, term, andop, fator
29 * original idea came from Programming Perl 1st edtion
30 */
31
32 #include <stdio.h>
33 #include <string.h>
34 #include "namazu.h"
35
36 /* definitions of operator */
37 #define AND_STRING "&"
38 #define OR_STRING "|"
39 #define NOT_STRING "!"
40 #define LP_STRING "("
41 #define RP_STRING ")"
42
43 /* also acceptable as word since v1.1.1 */
44 #define AND_STRING_ALT "and"
45 #define OR_STRING_ALT "or"
46 #define NOT_STRING_ALT "not"
47
48 #define AND_OP 1
49 #define NOT_OP 2
50
51 static int Cp = 0; /* variable that saves current position of parser */
52
53
54 /* check a character if metacharacter (operator) of not */
ismetastring(uchar * c)55 int ismetastring(uchar * c)
56 {
57 if ((!strcmp(c, AND_STRING)) ||
58 (!strcmp(c, AND_STRING_ALT)) ||
59 (!strcmp(c, OR_STRING)) ||
60 (!strcmp(c, OR_STRING_ALT)) ||
61 (!strcmp(c, NOT_STRING)) ||
62 (!strcmp(c, NOT_STRING_ALT)) ||
63 (!strcmp(c, LP_STRING)) ||
64 (!strcmp(c, RP_STRING)))
65 return 1;
66 return 0;
67 }
68
69
factor(int * ignore)70 HLIST factor(int *ignore)
71 {
72 HLIST val;
73 val.n = 0;
74
75 while (1) {
76 if (!KeyItem[Cp])
77 return val;
78
79 if (!strcmp(KeyItem[Cp], LP_STRING)) {
80 Cp++;
81 if (KeyItem[Cp] == NULL)
82 return val;
83 val = expr();
84 if (KeyItem[Cp] == NULL)
85 return val;
86 if (!strcmp(KeyItem[Cp], RP_STRING))
87 Cp++;
88 break;
89 } else if (!ismetastring(KeyItem[Cp])) {
90 val = do_search(KeyItem[Cp], val);
91 /* MSG_TOO_MUCH_MATCH;
92 MSG_TOO_MUCH_HIT; case */
93 if (val.n < 0) {
94 *ignore = 1;
95 val.n = 0; /* assign 0 - note that is important */
96 }
97
98 Cp++;
99 break;
100 } else {
101 Cp++;
102 }
103 }
104 return val;
105 }
106
andop(void)107 int andop(void)
108 {
109 if (KeyItem[Cp] == NULL)
110 return 0;
111 if (!strcmp(KeyItem[Cp], AND_STRING) ||
112 !strcmp(KeyItem[Cp], AND_STRING_ALT)) {
113 Cp++;
114 return AND_OP;
115 }
116 if (!strcmp(KeyItem[Cp], NOT_STRING) ||
117 !strcmp(KeyItem[Cp], NOT_STRING_ALT)) {
118 Cp++;
119 return NOT_OP;
120 }
121 if (!strcmp(KeyItem[Cp], LP_STRING))
122 return AND_OP;
123 if (!ismetastring(KeyItem[Cp]))
124 return AND_OP;
125 return 0;
126 }
127
term(void)128 HLIST term(void)
129 {
130 HLIST left, right;
131 int ignore = 0, op;
132
133 left = factor(&ignore);
134 while ((op = andop())) {
135 right = factor(&ignore);
136 if (op == AND_OP) {
137 left = andmerge(left, right, &ignore);
138 } else if (op == NOT_OP) {
139 left = notmerge(left, right, &ignore);
140 }
141 ignore = 0;
142 }
143 return left;
144 }
145
146
orop(void)147 int orop(void)
148 {
149 if (KeyItem[Cp] == NULL)
150 return 0;
151 if (!strcmp(KeyItem[Cp], OR_STRING) ||
152 !strcmp(KeyItem[Cp], OR_STRING_ALT)) {
153 Cp++;
154 return 1;
155 }
156 return 0;
157 }
158
expr()159 HLIST expr()
160 {
161 HLIST left, right;
162
163 left = term();
164 while (orop()) {
165 right = term();
166 left = ormerge(left, right);
167 }
168 return left;
169 }
170
initialize_parser(void)171 void initialize_parser(void)
172 {
173 Cp = 0;
174 }
175