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