Dynamic PEG for interpreted languages.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

208 lignes
4.0 KiB

%{
#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;
}