#include /* In text block */ %s I /* Outside of text block */ %s O /* Waiting for Width argument */ %s W /* Waiting for OpCode arguments */ %s Op int num_blocks = 0; int num_lines = 0; int cur_num_lines = 0; int cur_num_block = 0; int line_width = 0; int max_line_width = 0; int block_lines = 0; int block_width = 0; int errstate = 0; void yputc(int c, int a); void unputs(char *); %% ""\n { int i; char zeros[4] = {0, 0, 0, 0}; num_blocks = atoi(yytext + 8); fprintf(stderr, "Number of blocks: %i\n", num_blocks); num_blocks--; fwrite(&num_blocks, 4, 1, yyout); num_blocks++; for (i = 0; i < num_blocks; i++) { fwrite(zeros, 4, 1, yyout); } num_lines = 2; BEGIN(O); } .* { fprintf(stderr, "Invalid file, must begin with \n"); errstate = 1; num_lines = 2; num_blocks = 9999; } "= num_blocks) { fprintf(stderr, "Error: too much blocks at line %i\n", num_lines); errstate = 1; } block_lines = atoi(yytext + 18); BEGIN(W); } "width:"\ *[[:digit:]]+">\n" { block_width = atoi(yytext + 6); fprintf(stderr, "Begin of block %i at line %i -- lines = %i, width = %i\n", cur_num_block, num_lines, block_lines, block_width); num_lines++; line_width = 0; max_line_width = 0; cur_num_lines = 1; if (num_blocks != 9999) { long p = ftell(yyout); fseek(yyout, 4 + cur_num_block * 2, SEEK_SET); fwrite(&p, 2, 1, yyout); fseek(yyout, (num_blocks - 1) * 2, SEEK_CUR); putc(block_width, yyout); putc(block_lines, yyout); fseek(yyout, 0, SEEK_END); } BEGIN(I); } .* { fprintf(stderr, "Error: invalid arguments to command Text_block at line %i: '%s'\n", num_lines, yytext); errstate = 1; BEGIN(O); } "\n" { if (line_width > block_width) { fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width); } if (line_width > max_line_width) max_line_width = line_width; line_width = 0; num_lines++; cur_num_lines++; if (cur_num_lines > block_lines) { fprintf(stderr, "Warning: too much lines for text block %i at line %i (%i > %i)\n", cur_num_block, num_lines, cur_num_lines, block_lines); } putc(1, yyout); } "\n" { if (line_width > block_width) { fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width); } if (line_width > max_line_width) max_line_width = line_width; line_width = 0; num_lines++; cur_num_lines = 1; putc(2, yyout); } "\n" { if (line_width > block_width) { fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width); } if (line_width > max_line_width) max_line_width = line_width; line_width = 0; num_lines++; cur_num_lines = 1; putc(1, yyout); putc(3, yyout); } "" { cur_num_lines = 1; putc(3, yyout); } "" { int d = atoi(yytext + 7); if (d > 255) { fprintf(stderr, "Error: delay too important: %i\n", d); errstate = 1; } else { putc(0xf, yyout); putc(0, yyout); putc(d, yyout); } } "" { int d = atoi(yytext + 5); if (d > 255) { fprintf(stderr, "Error: gear number too important: %i\n", d); errstate = 1; } else { putc(0xf, yyout); putc(5, yyout); putc(d, yyout); line_width += 16; } } "" { BEGIN(Op); } [[:digit:]]+\ +[[:digit:]]+">" { int o1, o2; o1 = atoi(yytext); o2 = atoi(yytext + (o1 < 10 ? 2 : o1 < 100 ? 3 : 4)); putc(0xf, yyout); putc(o1, yyout); putc(o2, yyout); BEGIN(I); } [^<]*">" { yytext[strlen(yytext - 1)] = 0; fprintf(stderr, "Error: invalid OpCode '%s'\n", yytext); errstate = 1; BEGIN(I); } " " yputc(0x10, 2); "+" yputc(0x11, 2); "," yputc(0x12, 2); "-" yputc(0x13, 2); "." yputc(0x14, 2); "/" yputc(0x15, 2); [[:digit:]] yputc(*yytext - 0x1a, 2); [[:upper:]] yputc(*yytext - 0x21, 2); "[" yputc(0x3a, 2); "]" yputc(0x3b, 2); "=" yputc(0x3c, 2); [[:lower:]] yputc(*yytext - 0x24, 2); "!" yputc(0x57, 2); "\"" yputc(0x58, 2); "#" yputc(0x59, 2); "%" yputc(0x5a, 2); "&" yputc(0x5b, 2); "'" yputc(0x5c, 2); "(" yputc(0x5d, 2); ")" yputc(0x5e, 2); ":" yputc(0x5f, 2); "?" yputc(0x60, 2); "<"[[:digit:]]">" yputc(*(yytext + 1) + 0x31, 3); "<%>" yputc(0x6b, 3); "<&>" yputc(0x6c, 3); "*" yputc(0x6d, 3); "" yputc(0x6e, 3); "" yputc(0x6f, 3); "" yputc(0x70, 3); "<*>" yputc(0x71, 3); "" yputc(0x72, 3); "" yputc(0x73, 3); "" yputc(0x74, 3); "" yputc(0x75, 3); "<.>" yputc(0x76, 3); "<:>" yputc(0x77, 3); "" yputc(0x79, 3); "<..>" yputc(0x7a, 3); "<`>" yputc(0x7b, 3); "<+>" yputc(0x7d, 3); "<->" yputc(0x7e, 3); "" yputc(0x7f, 3); "<[>" yputc(0x80, 3); "<]>" yputc(0x81, 3); "<(>" yputc(0x84, 3); "<)>" yputc(0x85, 3); "<#>" yputc(0x86, 3); "`" yputc(0x87, 3); "°" yputc(0x88, 3); "<=>" yputc(0x89, 3); "" yputc(0x8a, 3); "" yputc(0x8b, 3); "_" yputc(0x8c, 3); "~" yputc(0x8d, 3); "<...>" yputc(0x8e, 3); "<'>" yputc(0x8f, 3); "" { int d = atoi(yytext + 7); if (d > 255) { fprintf(stderr, "Error: Extra1 number too important: %i\n", d); errstate = 1; } else { putc(0xfe, yyout); putc(d, yyout); } } "" { int d = atoi(yytext + 7); if (d > 255) { fprintf(stderr, "Error: Extra2 number too important: %i\n", d); errstate = 1; } else { putc(0xff, yyout); putc(d, yyout); } } "" { char str[5] = {'0', 'x', 0, 0, 0}; int d; for (yytext += 6; *yytext == ' '; yytext++); str[2] = *(yytext++); str[3] = *(yytext++); sscanf(str, "%i", &d); if (d > 255) { fprintf(stderr, "Error: Bare number too important: %i\n", d); errstate = 1; } else { putc(d, yyout); } } à|â|ä unput('a'); é|è|ê|ë unput('e'); î|ï unput('i'); ô|ö unput('o'); û|ü|ù unput('u'); ç unput('c'); "" unput('e'); unput('o'); "" unput('e'); unput('a'); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "" unputs(""); "\n" { if (line_width > max_line_width) max_line_width = line_width; if (max_line_width < block_width) fprintf(stderr, "Warning: block %i too large (%i < %i)\n", cur_num_block, max_line_width, block_width); if (line_width > block_width) fprintf(stderr, "Warning: line %i too long (%i > %i).\n", num_lines, line_width, block_width); num_lines++; cur_num_block++; putc(0, yyout); BEGIN(O); } "<"[^\>\n]*">" { yytext[strlen(yytext) - 1] = 0; fprintf(stderr, "Error: Invalid command at line %i: '%s'\n", num_lines, yytext + 1); errstate = 1; } \n num_lines++; . /* Eat up comments */ . { fprintf(stderr, "Invalid character at line %i: '%c'\n", num_lines, *yytext); errstate = 1; } . { fprintf(stderr, "Hu uh, something's wrong at line %i...\n", num_lines); } %% int yywrap(void) { if (cur_num_block < num_blocks) { fprintf(stderr, "Warning: Too few blocks at end of file.\n"); } exit(errstate ? -1 : 0); } int main(int argc, char ** argv) { if ((argc < 2) || (argc > 3)) { fprintf(stderr, "Usage: %s [input]\n", argv[0]); exit(-1); } if (!(yyout = fopen(argv[1], "wb"))) { fprintf(stderr, "Error: can't open file %s\n", argv[1]); exit(-1); } if (argc == 3) { if (!(yyin = fopen(argv[2], "rb"))) { fprintf(stderr, "Error: can't open file %s\n", argv[2]); exit(-1); } } fprintf(stderr, "Creating file %s\n", argv[1]); yylex(); exit(errstate ? -1 : 0); } void yputc(int c, int a) { line_width += a; putc(c, yyout); } void unputs(char * s) { int l = strlen(s), i; for (i = l - 1; i >= 0; i--) { unput(s[i]); } }