|
|
1.1 root 1: /*
2: * egrep -- print lines containing (or not containing) a regular expression
3: *
4: * status returns:
5: * 0 - ok, and some matches
6: * 1 - ok, but no matches
7: * 2 - some error; matches irrelevant
8: */
9: %token CHAR DOT CCL NCCL OR CAT STAR PLUS QUEST
10: %left OR
11: %left CHAR DOT CCL NCCL '('
12: %left CAT
13: %left STAR PLUS QUEST
14:
15: %{
16: #include "hdr.h"
17: %}
18:
19: %%
20: s: t
21: { unary(FINAL, $1);
22: line--;
23: }
24: ;
25: t: b r
26: { $$ = node(CAT, $1, $2); }
27: | OR b r OR
28: { $$ = node(CAT, $2, $3); }
29: | OR b r
30: { $$ = node(CAT, $2, $3); }
31: | b r OR
32: { $$ = node(CAT, $1, $2); }
33: ;
34: b:
35: { $$ = enter(DOT);
36: $$ = unary(STAR, $$); }
37: ;
38: r: CHAR
39: { $$ = iflag?node(OR, enter(tolower($1)), enter(toupper($1))):enter($1); }
40: | DOT
41: { $$ = enter(DOT); }
42: | CCL
43: { $$ = cclenter(CCL); }
44: | NCCL
45: { $$ = cclenter(NCCL); }
46: ;
47:
48: r: r OR r
49: { $$ = node(OR, $1, $3); }
50: | r r %prec CAT
51: { $$ = node(CAT, $1, $2); }
52: | r STAR
53: { $$ = unary(STAR, $1); }
54: | r PLUS
55: { $$ = unary(PLUS, $1); }
56: | r QUEST
57: { $$ = unary(QUEST, $1); }
58: | '(' r ')'
59: { $$ = $2; }
60: | error
61: ;
62:
63: %%
64: yyerror(s) {
65: fprint(2, "egrep: %s\n", s);
66: exit(2);
67: }
68:
69: yylex() {
70: extern int yylval;
71: int cclcnt, x;
72: register char c, d;
73: switch(c = nextch()) {
74: case '^': c = LEFT;
75: goto defchar;
76: case '$': c = RIGHT;
77: goto defchar;
78: case '|': return (OR);
79: case '*': return (STAR);
80: case '+': return (PLUS);
81: case '?': return (QUEST);
82: case '(': return (c);
83: case ')': return (c);
84: case '.': return (DOT);
85: case '\0': return (0);
86: case RIGHT: return (OR);
87: case '[':
88: x = CCL;
89: cclcnt = 0;
90: count = nxtchar++;
91: if ((c = nextch()) == '^') {
92: x = NCCL;
93: c = nextch();
94: }
95: do {
96: if (c == '\0') synerror();
97: if (c == '-' && cclcnt > 0 && chars[nxtchar-1] != 0) {
98: if ((d = nextch()) != 0) {
99: c = chars[nxtchar-1];
100: while (c < d) {
101: if (iflag && isalpha(c)) {
102: if (nxtchar >= MAXLIN-1) overflo();
103: chars[nxtchar++] = isupper(++c)?tolower(c):toupper(c);
104: chars[nxtchar++] = c;
105: cclcnt += 2;
106: }
107: else {
108: if (nxtchar >= MAXLIN) overflo();
109: chars[nxtchar++] = ++c;
110: cclcnt++;
111: }
112: }
113: continue;
114: }
115: }
116: if (iflag&&isalpha(c)) {
117: if (nxtchar >= MAXLIN-1) overflo();
118: chars[nxtchar++] = isupper(c)?tolower(c):toupper(c);
119: chars[nxtchar++] = c;
120: cclcnt += 2;
121: }
122: else {
123: if (nxtchar >= MAXLIN) overflo();
124: chars[nxtchar++] = c;
125: cclcnt++;
126: }
127: } while ((c = nextch()) != ']');
128: chars[count] = cclcnt;
129: return (x);
130: case '\\':
131: if ((c = nextch()) == '\0') synerror();
132: else if (c == '\n') c = nextch();
133: defchar:
134: default: yylval = c; return (CHAR);
135: }
136: }
137:
138: static int mailfd = -1;
139:
140: nextch() {
141: register c;
142: if (fflag) {
143: if ((c = Fgetc(expfile)) < 0)
144: c = 0;
145: }
146: else c = *input++;
147: if(mailfd >= 0) Fputc(mailfd, c? c : '\n');
148: return(c);
149: }
150:
151: synerror() {
152: fprint(2, "egrep: syntax error\n");
153: exit(2);
154: }
155:
156: enter(x) int x; {
157: if(line >= MAXLIN) overflo();
158: name[line] = x;
159: left[line] = 0;
160: right[line] = 0;
161: return(line++);
162: }
163:
164: cclenter(x) int x; {
165: register linno;
166: linno = enter(x);
167: right[linno] = count;
168: return (linno);
169: }
170:
171: node(x, l, r) {
172: if(line >= MAXLIN) overflo();
173: name[line] = x;
174: left[line] = l;
175: right[line] = r;
176: parent[l] = line;
177: parent[r] = line;
178: return(line++);
179: }
180:
181: unary(x, d) {
182: if(line >= MAXLIN) overflo();
183: name[line] = x;
184: left[line] = d;
185: right[line] = 0;
186: parent[d] = line;
187: return(line++);
188: }
189: overflo() {
190: fprint(2, "egrep: regular expression too long\n");
191: exit(2);
192: }
193: #include <errno.h>
194: #define NAME "/tmp/grepdata"
195: mailprep()
196: {
197: umask(0);
198: mailfd = open(NAME, 1);
199: if((mailfd < 0) && (errno != ECONC))
200: mailfd = creat(NAME, 03666);
201: if(mailfd >= 0){
202: Finit(mailfd, (char *)0);
203: Fseek(mailfd, 0L, 2);
204: Fprint(mailfd, "\321egrep: ");
205: }
206: }
207:
208: maildone()
209: {
210: if(mailfd >= 0){
211: Fflush(mailfd);
212: close(mailfd);
213: }
214: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.