%{
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
;
|
|
enum op { String, Query, Star, Plus, Or, And, Class, Dot, Exc } ;
|
|
|
|
typedef union Node Node;
|
|
|
|
struct String { enum op type; char *string; };
|
|
struct Query { enum op type; Node *children[1]; };
|
|
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 Dot { enum op type;};
|
|
struct Exc { enum op type; Node *children[1]; };
|
|
|
|
union Node {
|
|
enum op type;
|
|
struct String String;
|
|
struct Query Query;
|
|
struct Star Star;
|
|
struct Plus Plus;
|
|
struct Or Or;
|
|
struct And And;
|
|
struct Class Class;
|
|
struct Dot Dot;
|
|
struct Exc Exc;
|
|
};
|
|
|
|
Node *mkString(char *s)
|
|
{
|
|
Node *node= calloc(1, sizeof(struct String));
|
|
node->type= String;
|
|
node->String.string= strdup(s);
|
|
return node;
|
|
}
|
|
|
|
|
|
|
|
Node *mkQuery(Node *n)
|
|
{
|
|
Node *node= calloc(1, sizeof(struct Query));
|
|
node->type= Query;
|
|
node->Query.children[0]= n;
|
|
return node;
|
|
}
|
|
|
|
Node *mkOr(Node *node1, Node *node2)
|
|
{
|
|
Node *node= calloc(1, sizeof(struct Or));
|
|
node->Or.children[0]= node1;
|
|
node->Or.children[1]= node2;
|
|
return node;
|
|
}
|
|
|
|
Node *mkAnd(Node *node1, Node *node2)
|
|
{
|
|
Node *node= calloc(1, sizeof(struct And));
|
|
node->And.children[0]= node1;
|
|
node->And.children[1]= node2;
|
|
return node;
|
|
}
|
|
|
|
Node *mkStar(Node *n)
|
|
{
|
|
Node *node= calloc(1, sizeof(struct Star));
|
|
node->type= Star;
|
|
node->Star.children[0]= n;
|
|
return node;
|
|
}
|
|
|
|
Node *mkClass(char* str)
|
|
{
|
|
Node *node= calloc(1, sizeof(struct Class));
|
|
node->Class.stringValue= str;
|
|
node->Class.len=strlen(str);
|
|
return node;
|
|
}
|
|
|
|
Node *mkPlus(Node *n)
|
|
{
|
|
Node *node= calloc(1, sizeof(struct Plus));
|
|
node->type= Plus;
|
|
node->Plus.children[0]= 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) {
|
|
case String:
|
|
printf("\"%s\"", node->String.string);
|
|
return;
|
|
case Query:
|
|
print(node->Query.children[0]);
|
|
printf("?");
|
|
return;
|
|
case Star:
|
|
print(node->Query.children[0]);
|
|
printf("*");
|
|
return;
|
|
case Plus:
|
|
print(node->Query.children[0]);
|
|
printf("+");
|
|
return;
|
|
case Or:
|
|
print(node->Or.children[0]);
|
|
print(node->Or.children[1]);
|
|
printf("Or");
|
|
return;
|
|
case And:
|
|
print(node->And.children[0]);
|
|
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();
|
|
}
|
|
|
|
void println(Node *node)
|
|
{
|
|
print(node);
|
|
printf("\n");
|
|
}
|
|
|
|
#define YYSTYPE Node *
|
|
|
|
YYSTYPE yylval = 0;
|
|
|
|
%}
|
|
|
|
start = - o:or { yylval = o }
|
|
|
|
or = a:and "|" - o:or { $$ = mkOr(o, a) }
|
|
| a:and { $$ = a }
|
|
|
|
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 | dot
|
|
|
|
string = '"' < [^"]* > '"' { $$ = mkString(yytext) } -
|
|
|
|
class = '[' <[]*> ']' { $$=mkClass(yytext) } -
|
|
|
|
dot = '.' {$$=mkDot()} -
|
|
|
|
|
|
- = space*
|
|
|
|
space = [ \t] | '\n' '\r'* | '\r' '\n'*
|
|
|
|
%%
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
while (yyparse()) {
|
|
println(yylval);
|
|
}
|
|
|
|
return 0;
|
|
|
|
(void)yySet;
|
|
(void)yyPop;
|
|
(void)yyPush;
|
|
(void)yyAccept;
|
|
(void)yymatchDot;
|
|
(void)yymatchString;
|
|
(void)yymatchChar;
|
|
}
|