ゆの in yacc
パーサかませばなんでもありだな……
%{ #include <stdio.h> #include <string.h> %} %union { char *str; } %token X %token <str> STRING %type <str> face mouths left_part right_part mouth %% sayhello: face '<' STRING '!' { fputs($1, stdout); fputc(' ', stdout); fputs($3, stdout); fputc('!', stdout); fputs("\n", stdout); free($1); } face: left_part mouths right_part { $$ = malloc(strlen($1) + strlen($2) + strlen($3) + 1); strcpy($$, $1); strcat($$, $2); strcat($$, $3); free($1); free($2); free($3); } mouths: mouth { $$ = $1; } | mouth mouths { $$ = malloc(strlen($1) + strlen($2) + 1); strcpy($$, $1); strcat($$, $2); free($1); free($2); } left_part: X '/' { $$ = strdup("ひだまりスケッチ"); } right_part: '/' X { $$ = strdup("365"); } mouth: '_' { $$ = strdup("×"); } %% int yylex(void) { int c; static char str[1024]; char *p; c = fgetc(stdin); while (c != EOF && isspace(c)) c = fgetc(stdin); if (c == EOF) return 0; if (ispunct(c)) return c; p = str; while (c != EOF && ! isspace(c) && ! ispunct(c)) { *p++ = c; c = fgetc(stdin); } if (c != EOF) ungetc(c, stdin); *p++ = 0; if (! strcmp(str, "X")) return X; yylval.str = str; return STRING; } int yyerror(const char *msg) { fprintf(stderr, "parser error: %s\n", msg); return 0; } int main(int argc, char *argv[]) { yyparse(); }
バッファオーバーフロー等未対策。念のため。
% bison yuno.y % gcc -o yuno yuno.tab.c % ./yuno X / _ / X < 来週も見てくださいね! ひだまりスケッチ×365 来週も見てくださいね! X / ___ / X < 来週も見てくださいね! ひだまりスケッチ×××365 来週も見てくださいね!