summaryrefslogtreecommitdiff
path: root/sys/src/cmd/grep/grep.y
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/grep/grep.y
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/grep/grep.y')
-rwxr-xr-xsys/src/cmd/grep/grep.y236
1 files changed, 236 insertions, 0 deletions
diff --git a/sys/src/cmd/grep/grep.y b/sys/src/cmd/grep/grep.y
new file mode 100755
index 000000000..6feca3a83
--- /dev/null
+++ b/sys/src/cmd/grep/grep.y
@@ -0,0 +1,236 @@
+%{
+#include "grep.h"
+%}
+
+%union
+{
+ int val;
+ char* str;
+ Re2 re;
+}
+
+%type <re> expr prog
+%type <re> expr0 expr1 expr2 expr3 expr4
+%token <str> LCLASS
+%token <val> LCHAR
+%token LLPAREN LRPAREN LALT LSTAR LPLUS LQUES
+%token LBEGIN LEND LDOT LBAD LNEWLINE
+%%
+
+prog: /* empty */
+ {
+ yyerror("empty pattern");
+ }
+| expr newlines
+ {
+ $$.beg = ral(Tend);
+ $$.end = $$.beg;
+ $$ = re2cat(re2star(re2or(re2char(0x00, '\n'-1), re2char('\n'+1, 0xff))), $$);
+ $$ = re2cat($1, $$);
+ $$ = re2cat(re2star(re2char(0x00, 0xff)), $$);
+ topre = $$;
+ }
+
+expr:
+ expr0
+| expr newlines expr0
+ {
+ $$ = re2or($1, $3);
+ }
+
+expr0:
+ expr1
+| LSTAR { literal = 1; } expr1
+ {
+ $$ = $3;
+ }
+
+expr1:
+ expr2
+| expr1 LALT expr2
+ {
+ $$ = re2or($1, $3);
+ }
+
+expr2:
+ expr3
+| expr2 expr3
+ {
+ $$ = re2cat($1, $2);
+ }
+
+expr3:
+ expr4
+| expr3 LSTAR
+ {
+ $$ = re2star($1);
+ }
+| expr3 LPLUS
+ {
+ $$.beg = ral(Talt);
+ patchnext($1.end, $$.beg);
+ $$.beg->alt = $1.beg;
+ $$.end = $$.beg;
+ $$.beg = $1.beg;
+ }
+| expr3 LQUES
+ {
+ $$.beg = ral(Talt);
+ $$.beg->alt = $1.beg;
+ $$.end = $1.end;
+ appendnext($$.end, $$.beg);
+ }
+
+expr4:
+ LCHAR
+ {
+ $$.beg = ral(Tclass);
+ $$.beg->lo = $1;
+ $$.beg->hi = $1;
+ $$.end = $$.beg;
+ }
+| LBEGIN
+ {
+ $$.beg = ral(Tbegin);
+ $$.end = $$.beg;
+ }
+| LEND
+ {
+ $$.beg = ral(Tend);
+ $$.end = $$.beg;
+ }
+| LDOT
+ {
+ $$ = re2class("^\n");
+ }
+| LCLASS
+ {
+ $$ = re2class($1);
+ }
+| LLPAREN expr1 LRPAREN
+ {
+ $$ = $2;
+ }
+
+newlines:
+ LNEWLINE
+| newlines LNEWLINE
+%%
+
+void
+yyerror(char *e, ...)
+{
+ va_list args;
+
+ fprint(2, "grep: ");
+ if(filename)
+ fprint(2, "%s:%ld: ", filename, lineno);
+ else if (pattern)
+ fprint(2, "%s: ", pattern);
+ va_start(args, e);
+ vfprint(2, e, args);
+ va_end(args);
+ fprint(2, "\n");
+ exits("syntax");
+}
+
+long
+yylex(void)
+{
+ char *q, *eq;
+ int c, s;
+
+ if(peekc) {
+ s = peekc;
+ peekc = 0;
+ return s;
+ }
+ c = getrec();
+ if(literal) {
+ if(c != 0 && c != '\n') {
+ yylval.val = c;
+ return LCHAR;
+ }
+ literal = 0;
+ }
+ switch(c) {
+ default:
+ yylval.val = c;
+ s = LCHAR;
+ break;
+ case '\\':
+ c = getrec();
+ yylval.val = c;
+ s = LCHAR;
+ if(c == '\n')
+ s = LNEWLINE;
+ break;
+ case '[':
+ goto getclass;
+ case '(':
+ s = LLPAREN;
+ break;
+ case ')':
+ s = LRPAREN;
+ break;
+ case '|':
+ s = LALT;
+ break;
+ case '*':
+ s = LSTAR;
+ break;
+ case '+':
+ s = LPLUS;
+ break;
+ case '?':
+ s = LQUES;
+ break;
+ case '^':
+ s = LBEGIN;
+ break;
+ case '$':
+ s = LEND;
+ break;
+ case '.':
+ s = LDOT;
+ break;
+ case 0:
+ peekc = -1;
+ case '\n':
+ s = LNEWLINE;
+ break;
+ }
+ return s;
+
+getclass:
+ q = u.string;
+ eq = q + nelem(u.string) - 5;
+ c = getrec();
+ if(c == '^') {
+ q[0] = '^';
+ q[1] = '\n';
+ q[2] = '-';
+ q[3] = '\n';
+ q += 4;
+ c = getrec();
+ }
+ for(;;) {
+ if(q >= eq)
+ error("class too long");
+ if(c == ']' || c == 0)
+ break;
+ if(c == '\\') {
+ *q++ = c;
+ c = getrec();
+ if(c == 0)
+ break;
+ }
+ *q++ = c;
+ c = getrec();
+ }
+ *q = 0;
+ if(c == 0)
+ return LBAD;
+ yylval.str = u.string;
+ return LCLASS;
+}