Blob
1 %{2 #include "grep.h"3 %}5 %union6 {7 int val;8 char* str;9 Re2 re;10 }12 %type <re> expr prog13 %type <re> expr0 expr1 expr2 expr3 expr414 %token <str> LCLASS15 %token <val> LCHAR16 %token LLPAREN LRPAREN LALT LSTAR LPLUS LQUES17 %token LBEGIN LEND LDOT LBAD LNEWLINE18 %%20 prog:21 expr newlines22 {23 $$.beg = ral(Tend);24 $$.end = $$.beg;25 $$ = re2cat(re2star(re2or(re2char(0x00, '\n'-1), re2char('\n'+1, 0xff))), $$);26 $$ = re2cat($1, $$);27 $$ = re2cat(re2star(re2char(0x00, 0xff)), $$);28 topre = $$;29 }31 expr:32 expr033 | expr newlines expr034 {35 $$ = re2or($1, $3);36 }38 expr0:39 expr140 | LSTAR { literal = 1; } expr141 {42 $$ = $3;43 }45 expr1:46 expr247 | expr1 LALT expr248 {49 $$ = re2or($1, $3);50 }52 expr2:53 expr354 | expr2 expr355 {56 $$ = re2cat($1, $2);57 }59 expr3:60 expr461 | expr3 LSTAR62 {63 $$ = re2star($1);64 }65 | expr3 LPLUS66 {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 LQUES74 {75 $$.beg = ral(Talt);76 $$.beg->u.alt = $1.beg;77 $$.end = $1.end;78 appendnext($$.end, $$.beg);79 }81 expr4:82 LCHAR83 {84 $$.beg = ral(Tclass);85 $$.beg->u.x.lo = $1;86 $$.beg->u.x.hi = $1;87 $$.end = $$.beg;88 }89 | LBEGIN90 {91 $$.beg = ral(Tbegin);92 $$.end = $$.beg;93 }94 | LEND95 {96 $$.beg = ral(Tend);97 $$.end = $$.beg;98 }99 | LDOT100 {101 $$ = re2class("^\n");102 }103 | LCLASS104 {105 $$ = re2class($1);106 }107 | LLPAREN expr1 LRPAREN108 {109 $$ = $2;110 }112 newlines:113 LNEWLINE114 | newlines LNEWLINE115 %%117 void118 yyerror(char *e, ...)119 {120 if(filename)121 fprint(2, "grep: %s:%ld: %s\n", filename, lineno, e);122 else123 fprint(2, "grep: %s\n", e);124 exits("syntax");125 }127 int128 yylex(void)129 {130 char *q, *eq;131 int c, s;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;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 }