diff --git a/parse.leg b/parse.leg index bbd1e62..c1ea926 100644 --- a/parse.leg +++ b/parse.leg @@ -4,7 +4,7 @@ #include #include ; -enum op { String, Query, Star, Plus, Or, And } ; +enum op { String, Query, Star, Plus, Or, And, Class, Dot, Exc } ; typedef union Node Node; @@ -14,7 +14,9 @@ struct Star { enum op type; Node *children[1]; }; struct Plus { enum op type; Node *children[1]; }; struct Or { enum op type; Node *children[2]; }; struct And { enum op type; Node *children[2]; }; -struct Class { enum op type; char *stringValue; int len; }; +struct Class { enum op type; char *stringValue; int len; }; +struct Dot { enum op type;}; +struct Exc { enum op type; Node *children[1]; }; union Node { enum op type; @@ -25,6 +27,8 @@ union Node { struct Or Or; struct And And; struct Class Class; + struct Dot Dot; + struct Exc Exc; }; Node *mkString(char *s) @@ -85,6 +89,21 @@ Node *mkPlus(Node *n) return node; } +Node *mkDot() +{ + Node *node= calloc(1, sizeof(struct Dot)); + node->type= Dot; + return node; +} + +Node *mkExc(Node *n) +{ + Node *node= calloc(1, sizeof(struct Exc)); + node->type= Exc; + node->Exc.children[0]= n; + return node; +} + void print(Node *node) { switch (node->type) { @@ -113,6 +132,17 @@ void print(Node *node) print(node->And.children[1]); printf("And"); return; + case Class: + printf("Class"); + printf("\"%s\"", node->Class.stringValue); + return; + case Dot: + printf("Dot"); + return; + case Exc: + printf("!"); + print(node->Exc.children[0]); + return; } abort(); } @@ -134,21 +164,24 @@ start = - o:or { yylval = o } or = a:and "|" - o:or { $$ = mkOr(o, a) } | a:and { $$ = a } -and = p:postfix a:and { $$ = mkAnd(p, a) } - | p:postfix { $$ = p } +and = p:prefix a:and { $$ = mkAnd(p, a) } + | p:prefix { $$ = p } + +prefix = "!"- p : postfix {$$ = mkExc(p)} + | p: postfix {$$ = p} postfix = s:atom ( "?" - { s = mkQuery(s) } | "*" - { s = mkStar(s) } | "+" - { s = mkPlus(s) } )? { $$ = s} -atom = string | class +atom = string | class | dot string = '"' < [^"]* > '"' { $$ = mkString(yytext) } - class = '[' <[]*> ']' { $$=mkClass(yytext) } - - +dot = '.' {$$=mkDot()} - - = space*