From 5cf398595c06c006290a250b52d365ffb440efbb Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 2 Jul 2021 16:22:38 +0200 Subject: [PATCH] ajout leg --- Makefile | 7 + parse.c | 740 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ parse.leg | 130 ++++++++++ 3 files changed, 877 insertions(+) create mode 100644 Makefile create mode 100644 parse.c create mode 100644 parse.leg diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7057ded --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +CFLAGS = -Wall + +parse : parse.c + +parse.c : parse.leg + leg $< > $@.new + mv $@.new $@ diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..b3c85e3 --- /dev/null +++ b/parse.c @@ -0,0 +1,740 @@ +/* A recursive-descent parser generated by peg 0.1.18 */ + +#include +#include +#include +#define YYRULECOUNT 9 +#line 1 "parse.leg" + + +#include +#include +#include +; +enum op { String, Query, Star, Plus } ; + +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]; }; + +union Node { + enum op type; + struct String String; + struct Query Query; + struct Star Star; + struct Plus Plus; +}; + +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 *mkStar(Node *n) +{ + Node *node= calloc(1, sizeof(struct Star)); + node->type= Star; + node->Star.children[0]= n; + return node; +} + +Node *mkPlus(Node *n) +{ + Node *node= calloc(1, sizeof(struct Plus)); + node->type= Plus; + node->Plus.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; + } + abort(); +} + +void println(Node *node) +{ + print(node); + printf("\n"); +} + +#define YYSTYPE Node * + +YYSTYPE yylval = 0; + + +#ifndef YY_MALLOC +#define YY_MALLOC(C, N) malloc(N) +#endif +#ifndef YY_REALLOC +#define YY_REALLOC(C, P, N) realloc(P, N) +#endif +#ifndef YY_FREE +#define YY_FREE(C, P) free(P) +#endif +#ifndef YY_LOCAL +#define YY_LOCAL(T) static T +#endif +#ifndef YY_ACTION +#define YY_ACTION(T) static T +#endif +#ifndef YY_RULE +#define YY_RULE(T) static T +#endif +#ifndef YY_PARSE +#define YY_PARSE(T) T +#endif +#ifndef YYPARSE +#define YYPARSE yyparse +#endif +#ifndef YYPARSEFROM +#define YYPARSEFROM yyparsefrom +#endif +#ifndef YYRELEASE +#define YYRELEASE yyrelease +#endif +#ifndef YY_BEGIN +#define YY_BEGIN ( yy->__begin= yy->__pos, 1) +#endif +#ifndef YY_END +#define YY_END ( yy->__end= yy->__pos, 1) +#endif +#ifdef YY_DEBUG +# define yyprintf(args) fprintf args +#else +# define yyprintf(args) +#endif +#ifndef YYSTYPE +#define YYSTYPE int +#endif +#ifndef YY_STACK_SIZE +#define YY_STACK_SIZE 128 +#endif + +#ifndef YY_BUFFER_SIZE +#define YY_BUFFER_SIZE 1024 +#endif + +#ifndef YY_PART + +typedef struct _yycontext yycontext; +typedef void (*yyaction)(yycontext *yy, char *yytext, int yyleng); +typedef struct _yythunk { int begin, end; yyaction action; struct _yythunk *next; } yythunk; + +struct _yycontext { + char *__buf; + int __buflen; + int __pos; + int __limit; + char *__text; + int __textlen; + int __begin; + int __end; + int __textmax; + yythunk *__thunks; + int __thunkslen; + int __thunkpos; + YYSTYPE __; + YYSTYPE *__val; + YYSTYPE *__vals; + int __valslen; +#ifdef YY_CTX_MEMBERS + YY_CTX_MEMBERS +#endif +}; + +#ifdef YY_CTX_LOCAL +#define YY_CTX_PARAM_ yycontext *yyctx, +#define YY_CTX_PARAM yycontext *yyctx +#define YY_CTX_ARG_ yyctx, +#define YY_CTX_ARG yyctx +#ifndef YY_INPUT +#define YY_INPUT(yy, buf, result, max_size) \ + { \ + int yyc= getchar(); \ + result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ + yyprintf((stderr, "<%c>", yyc)); \ + } +#endif +#else +#define YY_CTX_PARAM_ +#define YY_CTX_PARAM +#define YY_CTX_ARG_ +#define YY_CTX_ARG +yycontext _yyctx= { 0, 0 }; +yycontext *yyctx= &_yyctx; +#ifndef YY_INPUT +#define YY_INPUT(buf, result, max_size) \ + { \ + int yyc= getchar(); \ + result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \ + yyprintf((stderr, "<%c>", yyc)); \ + } +#endif +#endif + +YY_LOCAL(int) yyrefill(yycontext *yy) +{ + int yyn; + while (yy->__buflen - yy->__pos < 512) + { + yy->__buflen *= 2; + yy->__buf= (char *)YY_REALLOC(yy, yy->__buf, yy->__buflen); + } +#ifdef YY_CTX_LOCAL + YY_INPUT(yy, (yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos)); +#else + YY_INPUT((yy->__buf + yy->__pos), yyn, (yy->__buflen - yy->__pos)); +#endif + if (!yyn) return 0; + yy->__limit += yyn; + return 1; +} + +YY_LOCAL(int) yymatchDot(yycontext *yy) +{ + if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; + ++yy->__pos; + return 1; +} + +YY_LOCAL(int) yymatchChar(yycontext *yy, int c) +{ + if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; + if ((unsigned char)yy->__buf[yy->__pos] == c) + { + ++yy->__pos; + yyprintf((stderr, " ok yymatchChar(yy, %c) @ %s\n", c, yy->__buf+yy->__pos)); + return 1; + } + yyprintf((stderr, " fail yymatchChar(yy, %c) @ %s\n", c, yy->__buf+yy->__pos)); + return 0; +} + +YY_LOCAL(int) yymatchString(yycontext *yy, const char *s) +{ + int yysav= yy->__pos; + while (*s) + { + if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; + if (yy->__buf[yy->__pos] != *s) + { + yy->__pos= yysav; + return 0; + } + ++s; + ++yy->__pos; + } + return 1; +} + +YY_LOCAL(int) yymatchClass(yycontext *yy, unsigned char *bits) +{ + int c; + if (yy->__pos >= yy->__limit && !yyrefill(yy)) return 0; + c= (unsigned char)yy->__buf[yy->__pos]; + if (bits[c >> 3] & (1 << (c & 7))) + { + ++yy->__pos; + yyprintf((stderr, " ok yymatchClass @ %s\n", yy->__buf+yy->__pos)); + return 1; + } + yyprintf((stderr, " fail yymatchClass @ %s\n", yy->__buf+yy->__pos)); + return 0; +} + +YY_LOCAL(void) yyDo(yycontext *yy, yyaction action, int begin, int end) +{ + while (yy->__thunkpos >= yy->__thunkslen) + { + yy->__thunkslen *= 2; + yy->__thunks= (yythunk *)YY_REALLOC(yy, yy->__thunks, sizeof(yythunk) * yy->__thunkslen); + } + yy->__thunks[yy->__thunkpos].begin= begin; + yy->__thunks[yy->__thunkpos].end= end; + yy->__thunks[yy->__thunkpos].action= action; + ++yy->__thunkpos; +} + +YY_LOCAL(int) yyText(yycontext *yy, int begin, int end) +{ + int yyleng= end - begin; + if (yyleng <= 0) + yyleng= 0; + else + { + while (yy->__textlen < (yyleng + 1)) + { + yy->__textlen *= 2; + yy->__text= (char *)YY_REALLOC(yy, yy->__text, yy->__textlen); + } + memcpy(yy->__text, yy->__buf + begin, yyleng); + } + yy->__text[yyleng]= '\0'; + return yyleng; +} + +YY_LOCAL(void) yyDone(yycontext *yy) +{ + int pos; + for (pos= 0; pos < yy->__thunkpos; ++pos) + { + yythunk *thunk= &yy->__thunks[pos]; + int yyleng= thunk->end ? yyText(yy, thunk->begin, thunk->end) : thunk->begin; + yyprintf((stderr, "DO [%d] %p %s\n", pos, thunk->action, yy->__text)); + thunk->action(yy, yy->__text, yyleng); + } + yy->__thunkpos= 0; +} + +YY_LOCAL(void) yyCommit(yycontext *yy) +{ + if ((yy->__limit -= yy->__pos)) + { + memmove(yy->__buf, yy->__buf + yy->__pos, yy->__limit); + } + yy->__begin -= yy->__pos; + yy->__end -= yy->__pos; + yy->__pos= yy->__thunkpos= 0; +} + +YY_LOCAL(int) yyAccept(yycontext *yy, int tp0) +{ + if (tp0) + { + fprintf(stderr, "accept denied at %d\n", tp0); + return 0; + } + else + { + yyDone(yy); + yyCommit(yy); + } + return 1; +} + +YY_LOCAL(void) yyPush(yycontext *yy, char *text, int count) +{ + yy->__val += count; + while (yy->__valslen <= yy->__val - yy->__vals) + { + long offset= yy->__val - yy->__vals; + yy->__valslen *= 2; + yy->__vals= (YYSTYPE *)YY_REALLOC(yy, yy->__vals, sizeof(YYSTYPE) * yy->__valslen); + yy->__val= yy->__vals + offset; + } +} +YY_LOCAL(void) yyPop(yycontext *yy, char *text, int count) { yy->__val -= count; } +YY_LOCAL(void) yySet(yycontext *yy, char *text, int count) { yy->__val[count]= yy->__; } + +#endif /* YY_PART */ + +#define YYACCEPT yyAccept(yy, yythunkpos0) + +YY_RULE(int) yy_space(yycontext *yy); /* 9 */ +YY_RULE(int) yy_class(yycontext *yy); /* 8 */ +YY_RULE(int) yy_string(yycontext *yy); /* 7 */ +YY_RULE(int) yy_atom(yycontext *yy); /* 6 */ +YY_RULE(int) yy_postfix(yycontext *yy); /* 5 */ +YY_RULE(int) yy_and(yycontext *yy); /* 4 */ +YY_RULE(int) yy_or(yycontext *yy); /* 3 */ +YY_RULE(int) yy__(yycontext *yy); /* 2 */ +YY_RULE(int) yy_start(yycontext *yy); /* 1 */ + +YY_ACTION(void) yy_1_string(yycontext *yy, char *yytext, int yyleng) +{ +#define __ yy->__ +#define yypos yy->__pos +#define yythunkpos yy->__thunkpos + yyprintf((stderr, "do yy_1_string\n")); + { +#line 105 + __ = mkString(yytext) ; + } +#undef yythunkpos +#undef yypos +#undef yy +} +YY_ACTION(void) yy_4_postfix(yycontext *yy, char *yytext, int yyleng) +{ +#define s yy->__val[-1] +#define __ yy->__ +#define yypos yy->__pos +#define yythunkpos yy->__thunkpos + yyprintf((stderr, "do yy_4_postfix\n")); + { +#line 101 + __ = s; + } +#undef yythunkpos +#undef yypos +#undef yy +#undef s +} +YY_ACTION(void) yy_3_postfix(yycontext *yy, char *yytext, int yyleng) +{ +#define s yy->__val[-1] +#define __ yy->__ +#define yypos yy->__pos +#define yythunkpos yy->__thunkpos + yyprintf((stderr, "do yy_3_postfix\n")); + { +#line 100 + s = mkPlus(s) ; + } +#undef yythunkpos +#undef yypos +#undef yy +#undef s +} +YY_ACTION(void) yy_2_postfix(yycontext *yy, char *yytext, int yyleng) +{ +#define s yy->__val[-1] +#define __ yy->__ +#define yypos yy->__pos +#define yythunkpos yy->__thunkpos + yyprintf((stderr, "do yy_2_postfix\n")); + { +#line 99 + s = mkStar(s) ; + } +#undef yythunkpos +#undef yypos +#undef yy +#undef s +} +YY_ACTION(void) yy_1_postfix(yycontext *yy, char *yytext, int yyleng) +{ +#define s yy->__val[-1] +#define __ yy->__ +#define yypos yy->__pos +#define yythunkpos yy->__thunkpos + yyprintf((stderr, "do yy_1_postfix\n")); + { +#line 98 + s = mkQuery(s) ; + } +#undef yythunkpos +#undef yypos +#undef yy +#undef s +} +YY_ACTION(void) yy_2_and(yycontext *yy, char *yytext, int yyleng) +{ +#define a yy->__val[-1] +#define p yy->__val[-2] +#define __ yy->__ +#define yypos yy->__pos +#define yythunkpos yy->__thunkpos + yyprintf((stderr, "do yy_2_and\n")); + { +#line 96 + __ = p ; + } +#undef yythunkpos +#undef yypos +#undef yy +#undef a +#undef p +} +YY_ACTION(void) yy_1_and(yycontext *yy, char *yytext, int yyleng) +{ +#define a yy->__val[-1] +#define p yy->__val[-2] +#define __ yy->__ +#define yypos yy->__pos +#define yythunkpos yy->__thunkpos + yyprintf((stderr, "do yy_1_and\n")); + { +#line 95 + __ = mkAnd(p, a) ; + } +#undef yythunkpos +#undef yypos +#undef yy +#undef a +#undef p +} +YY_ACTION(void) yy_2_or(yycontext *yy, char *yytext, int yyleng) +{ +#define o yy->__val[-1] +#define a yy->__val[-2] +#define __ yy->__ +#define yypos yy->__pos +#define yythunkpos yy->__thunkpos + yyprintf((stderr, "do yy_2_or\n")); + { +#line 93 + __ = a ; + } +#undef yythunkpos +#undef yypos +#undef yy +#undef o +#undef a +} +YY_ACTION(void) yy_1_or(yycontext *yy, char *yytext, int yyleng) +{ +#define o yy->__val[-1] +#define a yy->__val[-2] +#define __ yy->__ +#define yypos yy->__pos +#define yythunkpos yy->__thunkpos + yyprintf((stderr, "do yy_1_or\n")); + { +#line 92 + __ = mkOr(o, a) ; + } +#undef yythunkpos +#undef yypos +#undef yy +#undef o +#undef a +} +YY_ACTION(void) yy_1_start(yycontext *yy, char *yytext, int yyleng) +{ +#define o yy->__val[-1] +#define __ yy->__ +#define yypos yy->__pos +#define yythunkpos yy->__thunkpos + yyprintf((stderr, "do yy_1_start\n")); + { +#line 90 + yylval = o ; + } +#undef yythunkpos +#undef yypos +#undef yy +#undef o +} + +YY_RULE(int) yy_space(yycontext *yy) +{ int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; + yyprintf((stderr, "%s\n", "space")); + { int yypos2= yy->__pos, yythunkpos2= yy->__thunkpos; if (!yymatchClass(yy, (unsigned char *)"\000\002\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000")) goto l3; goto l2; + l3:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchChar(yy, '\n')) goto l4; + l5:; + { int yypos6= yy->__pos, yythunkpos6= yy->__thunkpos; if (!yymatchChar(yy, '\r')) goto l6; goto l5; + l6:; yy->__pos= yypos6; yy->__thunkpos= yythunkpos6; + } goto l2; + l4:; yy->__pos= yypos2; yy->__thunkpos= yythunkpos2; if (!yymatchChar(yy, '\r')) goto l1; + l7:; + { int yypos8= yy->__pos, yythunkpos8= yy->__thunkpos; if (!yymatchChar(yy, '\n')) goto l8; goto l7; + l8:; yy->__pos= yypos8; yy->__thunkpos= yythunkpos8; + } + } + l2:; + yyprintf((stderr, " ok %s @ %s\n", "space", yy->__buf+yy->__pos)); + return 1; + l1:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "space", yy->__buf+yy->__pos)); + return 0; +} +YY_RULE(int) yy_class(yycontext *yy) +{ int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; + yyprintf((stderr, "%s\n", "class")); if (!yymatchChar(yy, '[')) goto l9; if (!yymatchDot(yy)) goto l9; if (!yymatchDot(yy)) goto l9; if (!yymatchDot(yy)) goto l9; if (!yymatchChar(yy, ']')) goto l9; + yyprintf((stderr, " ok %s @ %s\n", "class", yy->__buf+yy->__pos)); + return 1; + l9:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "class", yy->__buf+yy->__pos)); + return 0; +} +YY_RULE(int) yy_string(yycontext *yy) +{ int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; + yyprintf((stderr, "%s\n", "string")); if (!yymatchChar(yy, '"')) goto l10; yyText(yy, yy->__begin, yy->__end); { +#define yytext yy->__text +#define yyleng yy->__textlen +if (!(YY_BEGIN)) goto l10; +#undef yytext +#undef yyleng + } + l11:; + { int yypos12= yy->__pos, yythunkpos12= yy->__thunkpos; if (!yymatchClass(yy, (unsigned char *)"\377\377\377\377\373\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377")) goto l12; goto l11; + l12:; yy->__pos= yypos12; yy->__thunkpos= yythunkpos12; + } yyText(yy, yy->__begin, yy->__end); { +#define yytext yy->__text +#define yyleng yy->__textlen +if (!(YY_END)) goto l10; +#undef yytext +#undef yyleng + } if (!yymatchChar(yy, '"')) goto l10; yyDo(yy, yy_1_string, yy->__begin, yy->__end); if (!yy__(yy)) goto l10; + yyprintf((stderr, " ok %s @ %s\n", "string", yy->__buf+yy->__pos)); + return 1; + l10:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "string", yy->__buf+yy->__pos)); + return 0; +} +YY_RULE(int) yy_atom(yycontext *yy) +{ int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; + yyprintf((stderr, "%s\n", "atom")); + { int yypos14= yy->__pos, yythunkpos14= yy->__thunkpos; if (!yy_string(yy)) goto l15; goto l14; + l15:; yy->__pos= yypos14; yy->__thunkpos= yythunkpos14; if (!yy_class(yy)) goto l13; + } + l14:; + yyprintf((stderr, " ok %s @ %s\n", "atom", yy->__buf+yy->__pos)); + return 1; + l13:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "atom", yy->__buf+yy->__pos)); + return 0; +} +YY_RULE(int) yy_postfix(yycontext *yy) +{ int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyDo(yy, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "postfix")); if (!yy_atom(yy)) goto l16; yyDo(yy, yySet, -1, 0); + { int yypos17= yy->__pos, yythunkpos17= yy->__thunkpos; + { int yypos19= yy->__pos, yythunkpos19= yy->__thunkpos; if (!yymatchChar(yy, '?')) goto l20; if (!yy__(yy)) goto l20; yyDo(yy, yy_1_postfix, yy->__begin, yy->__end); goto l19; + l20:; yy->__pos= yypos19; yy->__thunkpos= yythunkpos19; if (!yymatchChar(yy, '*')) goto l21; if (!yy__(yy)) goto l21; yyDo(yy, yy_2_postfix, yy->__begin, yy->__end); goto l19; + l21:; yy->__pos= yypos19; yy->__thunkpos= yythunkpos19; if (!yymatchChar(yy, '+')) goto l17; if (!yy__(yy)) goto l17; yyDo(yy, yy_3_postfix, yy->__begin, yy->__end); + } + l19:; goto l18; + l17:; yy->__pos= yypos17; yy->__thunkpos= yythunkpos17; + } + l18:; yyDo(yy, yy_4_postfix, yy->__begin, yy->__end); + yyprintf((stderr, " ok %s @ %s\n", "postfix", yy->__buf+yy->__pos)); yyDo(yy, yyPop, 1, 0); + return 1; + l16:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "postfix", yy->__buf+yy->__pos)); + return 0; +} +YY_RULE(int) yy_and(yycontext *yy) +{ int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyDo(yy, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "and")); + { int yypos23= yy->__pos, yythunkpos23= yy->__thunkpos; if (!yy_postfix(yy)) goto l24; yyDo(yy, yySet, -2, 0); if (!yy_and(yy)) goto l24; yyDo(yy, yySet, -1, 0); yyDo(yy, yy_1_and, yy->__begin, yy->__end); goto l23; + l24:; yy->__pos= yypos23; yy->__thunkpos= yythunkpos23; if (!yy_postfix(yy)) goto l22; yyDo(yy, yySet, -2, 0); yyDo(yy, yy_2_and, yy->__begin, yy->__end); + } + l23:; + yyprintf((stderr, " ok %s @ %s\n", "and", yy->__buf+yy->__pos)); yyDo(yy, yyPop, 2, 0); + return 1; + l22:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "and", yy->__buf+yy->__pos)); + return 0; +} +YY_RULE(int) yy_or(yycontext *yy) +{ int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyDo(yy, yyPush, 2, 0); + yyprintf((stderr, "%s\n", "or")); + { int yypos26= yy->__pos, yythunkpos26= yy->__thunkpos; if (!yy_and(yy)) goto l27; yyDo(yy, yySet, -2, 0); if (!yymatchChar(yy, '|')) goto l27; if (!yy__(yy)) goto l27; if (!yy_or(yy)) goto l27; yyDo(yy, yySet, -1, 0); yyDo(yy, yy_1_or, yy->__begin, yy->__end); goto l26; + l27:; yy->__pos= yypos26; yy->__thunkpos= yythunkpos26; if (!yy_and(yy)) goto l25; yyDo(yy, yySet, -2, 0); yyDo(yy, yy_2_or, yy->__begin, yy->__end); + } + l26:; + yyprintf((stderr, " ok %s @ %s\n", "or", yy->__buf+yy->__pos)); yyDo(yy, yyPop, 2, 0); + return 1; + l25:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "or", yy->__buf+yy->__pos)); + return 0; +} +YY_RULE(int) yy__(yycontext *yy) +{ + yyprintf((stderr, "%s\n", "_")); + l29:; + { int yypos30= yy->__pos, yythunkpos30= yy->__thunkpos; if (!yy_space(yy)) goto l30; goto l29; + l30:; yy->__pos= yypos30; yy->__thunkpos= yythunkpos30; + } + yyprintf((stderr, " ok %s @ %s\n", "_", yy->__buf+yy->__pos)); + return 1; +} +YY_RULE(int) yy_start(yycontext *yy) +{ int yypos0= yy->__pos, yythunkpos0= yy->__thunkpos; yyDo(yy, yyPush, 1, 0); + yyprintf((stderr, "%s\n", "start")); if (!yy__(yy)) goto l31; if (!yy_or(yy)) goto l31; yyDo(yy, yySet, -1, 0); yyDo(yy, yy_1_start, yy->__begin, yy->__end); + yyprintf((stderr, " ok %s @ %s\n", "start", yy->__buf+yy->__pos)); yyDo(yy, yyPop, 1, 0); + return 1; + l31:; yy->__pos= yypos0; yy->__thunkpos= yythunkpos0; + yyprintf((stderr, " fail %s @ %s\n", "start", yy->__buf+yy->__pos)); + return 0; +} + +#ifndef YY_PART + +typedef int (*yyrule)(yycontext *yy); + +YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart) +{ + int yyok; + if (!yyctx->__buflen) + { + yyctx->__buflen= YY_BUFFER_SIZE; + yyctx->__buf= (char *)YY_MALLOC(yyctx, yyctx->__buflen); + yyctx->__textlen= YY_BUFFER_SIZE; + yyctx->__text= (char *)YY_MALLOC(yyctx, yyctx->__textlen); + yyctx->__thunkslen= YY_STACK_SIZE; + yyctx->__thunks= (yythunk *)YY_MALLOC(yyctx, sizeof(yythunk) * yyctx->__thunkslen); + yyctx->__valslen= YY_STACK_SIZE; + yyctx->__vals= (YYSTYPE *)YY_MALLOC(yyctx, sizeof(YYSTYPE) * yyctx->__valslen); + yyctx->__begin= yyctx->__end= yyctx->__pos= yyctx->__limit= yyctx->__thunkpos= 0; + } + yyctx->__begin= yyctx->__end= yyctx->__pos; + yyctx->__thunkpos= 0; + yyctx->__val= yyctx->__vals; + yyok= yystart(yyctx); + if (yyok) yyDone(yyctx); + yyCommit(yyctx); + return yyok; +} + +YY_PARSE(int) YYPARSE(YY_CTX_PARAM) +{ + return YYPARSEFROM(YY_CTX_ARG_ yy_start); +} + +YY_PARSE(yycontext *) YYRELEASE(yycontext *yyctx) +{ + if (yyctx->__buflen) + { + yyctx->__buflen= 0; + YY_FREE(yyctx, yyctx->__buf); + YY_FREE(yyctx, yyctx->__text); + YY_FREE(yyctx, yyctx->__thunks); + YY_FREE(yyctx, yyctx->__vals); + } + return yyctx; +} + +#endif +#line 113 "parse.leg" + + +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; +} + diff --git a/parse.leg b/parse.leg new file mode 100644 index 0000000..b032995 --- /dev/null +++ b/parse.leg @@ -0,0 +1,130 @@ +%{ + +#include +#include +#include +; +enum op { String, Query, Star, Plus } ; + +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]; }; + +union Node { + enum op type; + struct String String; + struct Query Query; + struct Star Star; + struct Plus Plus; +}; + +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 *mkStar(Node *n) +{ + Node *node= calloc(1, sizeof(struct Star)); + node->type= Star; + node->Star.children[0]= n; + return node; +} + +Node *mkPlus(Node *n) +{ + Node *node= calloc(1, sizeof(struct Plus)); + node->type= Plus; + node->Plus.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; + } + 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:postfix a:and { $$ = mkAnd(p, a) } + | p:postfix { $$ = p } + +postfix = s:atom ( "?" - { s = mkQuery(s) } + | "*" - { s = mkStar(s) } + | "+" - { s = mkPlus(s) } + )? { $$ = s} + +atom = string | class + +string = '"' < [^"]* > '"' { $$ = mkString(yytext) } - + +class = '[' ... ']' + +- = 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; +}