|
@ -4,7 +4,7 @@ |
|
|
#include <string.h> |
|
|
#include <string.h> |
|
|
#include <stdlib.h> |
|
|
#include <stdlib.h> |
|
|
; |
|
|
; |
|
|
enum op { String, Query, Star, Plus, Or, And } ; |
|
|
|
|
|
|
|
|
enum op { String, Query, Star, Plus, Or, And, Class, Dot, Exc } ; |
|
|
|
|
|
|
|
|
typedef union Node Node; |
|
|
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 Plus { enum op type; Node *children[1]; }; |
|
|
struct Or { enum op type; Node *children[2]; }; |
|
|
struct Or { enum op type; Node *children[2]; }; |
|
|
struct And { 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 { |
|
|
union Node { |
|
|
enum op type; |
|
|
enum op type; |
|
@ -25,6 +27,8 @@ union Node { |
|
|
struct Or Or; |
|
|
struct Or Or; |
|
|
struct And And; |
|
|
struct And And; |
|
|
struct Class Class; |
|
|
struct Class Class; |
|
|
|
|
|
struct Dot Dot; |
|
|
|
|
|
struct Exc Exc; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Node *mkString(char *s) |
|
|
Node *mkString(char *s) |
|
@ -85,6 +89,21 @@ Node *mkPlus(Node *n) |
|
|
return node; |
|
|
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) |
|
|
void print(Node *node) |
|
|
{ |
|
|
{ |
|
|
switch (node->type) { |
|
|
switch (node->type) { |
|
@ -113,6 +132,17 @@ void print(Node *node) |
|
|
print(node->And.children[1]); |
|
|
print(node->And.children[1]); |
|
|
printf("And"); |
|
|
printf("And"); |
|
|
return; |
|
|
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(); |
|
|
abort(); |
|
|
} |
|
|
} |
|
@ -134,21 +164,24 @@ start = - o:or { yylval = o } |
|
|
or = a:and "|" - o:or { $$ = mkOr(o, a) } |
|
|
or = a:and "|" - o:or { $$ = mkOr(o, a) } |
|
|
| a:and { $$ = 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) } |
|
|
postfix = s:atom ( "?" - { s = mkQuery(s) } |
|
|
| "*" - { s = mkStar(s) } |
|
|
| "*" - { s = mkStar(s) } |
|
|
| "+" - { s = mkPlus(s) } |
|
|
| "+" - { s = mkPlus(s) } |
|
|
)? { $$ = s} |
|
|
)? { $$ = s} |
|
|
|
|
|
|
|
|
atom = string | class |
|
|
|
|
|
|
|
|
atom = string | class | dot |
|
|
|
|
|
|
|
|
string = '"' < [^"]* > '"' { $$ = mkString(yytext) } - |
|
|
string = '"' < [^"]* > '"' { $$ = mkString(yytext) } - |
|
|
|
|
|
|
|
|
class = '[' <[]*> ']' { $$=mkClass(yytext) } - |
|
|
class = '[' <[]*> ']' { $$=mkClass(yytext) } - |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dot = '.' {$$=mkDot()} - |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- = space* |
|
|
- = space* |
|
|