Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
%{
2
#include	"grep.h"
3
%}
4
 
5
%union
6
{
7
	int	val;
8
	char*	str;
9
	Re2	re;
10
}
11
 
12
%type	<re>	expr prog
13
%type	<re>	expr0 expr1 expr2 expr3 expr4
14
%token	<str>	LCLASS
15
%token	<val>	LCHAR
16
%token		LLPAREN LRPAREN LALT LSTAR LPLUS LQUES
17
%token		LBEGIN LEND LDOT LBAD LNEWLINE
18
%%
19
 
20
prog:	/* empty */
21
	{
22
		yyerror("empty pattern");
23
	}
24
|	expr newlines
25
	{
26
		$$.beg = ral(Tend);
27
		$$.end = $$.beg;
28
		$$ = re2cat(re2star(re2or(re2char(0x00, '\n'-1), re2char('\n'+1, 0xff))), $$);
29
		$$ = re2cat($1, $$);
30
		$$ = re2cat(re2star(re2char(0x00, 0xff)), $$);
31
		topre = $$;
32
	}
33
 
34
expr:
35
	expr0
36
|	expr newlines expr0
37
	{
38
		$$ = re2or($1, $3);
39
	}
40
 
41
expr0:
42
	expr1
43
|	LSTAR { literal = 1; } expr1
44
	{
45
		$$ = $3;
46
	}
47
 
48
expr1:
49
	expr2
50
|	expr1 LALT expr2
51
	{
52
		$$ = re2or($1, $3);
53
	}
54
 
55
expr2:
56
	expr3
57
|	expr2 expr3
58
	{
59
		$$ = re2cat($1, $2);
60
	}
61
 
62
expr3:
63
	expr4
64
|	expr3 LSTAR
65
	{
66
		$$ = re2star($1);
67
	}
68
|	expr3 LPLUS
69
	{
70
		$$.beg = ral(Talt);
71
		patchnext($1.end, $$.beg);
72
		$$.beg->alt = $1.beg;
73
		$$.end = $$.beg;
74
		$$.beg = $1.beg;
75
	}
76
|	expr3 LQUES
77
	{
78
		$$.beg = ral(Talt);
79
		$$.beg->alt = $1.beg;
80
		$$.end = $1.end;
81
		appendnext($$.end,  $$.beg);
82
	}
83
 
84
expr4:
85
	LCHAR
86
	{
87
		$$.beg = ral(Tclass);
88
		$$.beg->lo = $1;
89
		$$.beg->hi = $1;
90
		$$.end = $$.beg;
91
	}
92
|	LBEGIN
93
	{
94
		$$.beg = ral(Tbegin);
95
		$$.end = $$.beg;
96
	}
97
|	LEND
98
	{
99
		$$.beg = ral(Tend);
100
		$$.end = $$.beg;
101
	}
102
|	LDOT
103
	{
104
		$$ = re2class("^\n");
105
	}
106
|	LCLASS
107
	{
108
		$$ = re2class($1);
109
	}
110
|	LLPAREN expr1 LRPAREN
111
	{
112
		$$ = $2;
113
	}
114
 
115
newlines:
116
	LNEWLINE
117
|	newlines LNEWLINE
118
%%
119
 
120
void
121
yyerror(char *e, ...)
122
{
123
	va_list args;
124
 
125
	fprint(2, "grep: ");
126
	if(filename)
127
		fprint(2, "%s:%ld: ", filename, lineno);
128
	else if (pattern)
129
		fprint(2, "%s: ", pattern);
130
	va_start(args, e);
131
	vfprint(2, e, args);
132
	va_end(args);
133
	fprint(2, "\n");
134
	exits("syntax");
135
}
136
 
137
long
138
yylex(void)
139
{
140
	char *q, *eq;
141
	int c, s;
142
 
143
	if(peekc) {
144
		s = peekc;
145
		peekc = 0;
146
		return s;
147
	}
148
	c = getrec();
149
	if(literal) {
150
		if(c != 0 && c != '\n') {
151
			yylval.val = c;
152
			return LCHAR;
153
		}
154
		literal = 0;
155
	}
156
	switch(c) {
157
	default:
158
		yylval.val = c;
159
		s = LCHAR;
160
		break;
161
	case '\\':
162
		c = getrec();
163
		yylval.val = c;
164
		s = LCHAR;
165
		if(c == '\n')
166
			s = LNEWLINE;
167
		break;
168
	case '[':
169
		goto getclass;
170
	case '(':
171
		s = LLPAREN;
172
		break;
173
	case ')':
174
		s = LRPAREN;
175
		break;
176
	case '|':
177
		s = LALT;
178
		break;
179
	case '*':
180
		s = LSTAR;
181
		break;
182
	case '+':
183
		s = LPLUS;
184
		break;
185
	case '?':
186
		s = LQUES;
187
		break;
188
	case '^':
189
		s = LBEGIN;
190
		break;
191
	case '$':
192
		s = LEND;
193
		break;
194
	case '.':
195
		s = LDOT;
196
		break;
197
	case 0:
198
		peekc = -1;
199
	case '\n':
200
		s = LNEWLINE;
201
		break;
202
	}
203
	return s;
204
 
205
getclass:
206
	q = u.string;
207
	eq = q + nelem(u.string) - 5;
208
	c = getrec();
209
	if(c == '^') {
210
		q[0] = '^';
211
		q[1] = '\n';
212
		q[2] = '-';
213
		q[3] = '\n';
214
		q += 4;
215
		c = getrec();
216
	}
217
	for(;;) {
218
		if(q >= eq)
219
			error("class too long");
220
		if(c == ']' || c == 0)
221
			break;
222
		if(c == '\\') {
223
			*q++ = c;
224
			c = getrec();
225
			if(c == 0)
226
				break;
227
		}
228
		*q++ = c;
229
		c = getrec();
230
	}
231
	*q = 0;
232
	if(c == 0)
233
		return LBAD;
234
	yylval.str = u.string;
235
	return LCLASS;
236
}