Introduction
Introduction Statistics Contact Development Disclaimer Help
grep.y - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
grep.y (2815B)
---
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:
21 expr newlines
22 {
23 $$.beg = ral(Tend);
24 $$.end = $$.beg;
25 $$ = re2cat(re2star(re2or(re2char(0x00, '\n'-1), re2char…
26 $$ = re2cat($1, $$);
27 $$ = re2cat(re2star(re2char(0x00, 0xff)), $$);
28 topre = $$;
29 }
30
31 expr:
32 expr0
33 | expr newlines expr0
34 {
35 $$ = re2or($1, $3);
36 }
37
38 expr0:
39 expr1
40 | LSTAR { literal = 1; } expr1
41 {
42 $$ = $3;
43 }
44
45 expr1:
46 expr2
47 | expr1 LALT expr2
48 {
49 $$ = re2or($1, $3);
50 }
51
52 expr2:
53 expr3
54 | expr2 expr3
55 {
56 $$ = re2cat($1, $2);
57 }
58
59 expr3:
60 expr4
61 | expr3 LSTAR
62 {
63 $$ = re2star($1);
64 }
65 | expr3 LPLUS
66 {
67 $$.beg = ral(Talt);
68 patchnext($1.end, $$.beg);
69 $$.beg->u.alt = $1.beg;
70 $$.end = $$.beg;
71 $$.beg = $1.beg;
72 }
73 | expr3 LQUES
74 {
75 $$.beg = ral(Talt);
76 $$.beg->u.alt = $1.beg;
77 $$.end = $1.end;
78 appendnext($$.end, $$.beg);
79 }
80
81 expr4:
82 LCHAR
83 {
84 $$.beg = ral(Tclass);
85 $$.beg->u.x.lo = $1;
86 $$.beg->u.x.hi = $1;
87 $$.end = $$.beg;
88 }
89 | LBEGIN
90 {
91 $$.beg = ral(Tbegin);
92 $$.end = $$.beg;
93 }
94 | LEND
95 {
96 $$.beg = ral(Tend);
97 $$.end = $$.beg;
98 }
99 | LDOT
100 {
101 $$ = re2class("^\n");
102 }
103 | LCLASS
104 {
105 $$ = re2class($1);
106 }
107 | LLPAREN expr1 LRPAREN
108 {
109 $$ = $2;
110 }
111
112 newlines:
113 LNEWLINE
114 | newlines LNEWLINE
115 %%
116
117 void
118 yyerror(char *e, ...)
119 {
120 if(filename)
121 fprint(2, "grep: %s:%ld: %s\n", filename, lineno, e);
122 else
123 fprint(2, "grep: %s\n", e);
124 exits("syntax");
125 }
126
127 int
128 yylex(void)
129 {
130 char *q, *eq;
131 int c, s;
132
133 if(peekc) {
134 s = peekc;
135 peekc = 0;
136 return s;
137 }
138 c = getrec();
139 if(literal) {
140 if(c != 0 && c != '\n') {
141 yylval.val = c;
142 return LCHAR;
143 }
144 literal = 0;
145 }
146 switch(c) {
147 default:
148 yylval.val = c;
149 s = LCHAR;
150 break;
151 case '\\':
152 c = getrec();
153 yylval.val = c;
154 s = LCHAR;
155 if(c == '\n')
156 s = LNEWLINE;
157 break;
158 case '[':
159 goto getclass;
160 case '(':
161 s = LLPAREN;
162 break;
163 case ')':
164 s = LRPAREN;
165 break;
166 case '|':
167 s = LALT;
168 break;
169 case '*':
170 s = LSTAR;
171 break;
172 case '+':
173 s = LPLUS;
174 break;
175 case '?':
176 s = LQUES;
177 break;
178 case '^':
179 s = LBEGIN;
180 break;
181 case '$':
182 s = LEND;
183 break;
184 case '.':
185 s = LDOT;
186 break;
187 case 0:
188 peekc = -1;
189 case '\n':
190 s = LNEWLINE;
191 break;
192 }
193 return s;
194
195 getclass:
196 q = u.string;
197 eq = q + nelem(u.string) - 5;
198 c = getrec();
199 if(c == '^') {
200 q[0] = '^';
201 q[1] = '\n';
202 q[2] = '-';
203 q[3] = '\n';
204 q += 4;
205 c = getrec();
206 }
207 for(;;) {
208 if(q >= eq)
209 error("class too long");
210 if(c == ']' || c == 0)
211 break;
212 if(c == '\\') {
213 *q++ = c;
214 c = getrec();
215 if(c == 0)
216 break;
217 }
218 *q++ = c;
219 c = getrec();
220 }
221 *q = 0;
222 if(c == 0)
223 return LBAD;
224 yylval.str = u.string;
225 return LCLASS;
226 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.