diff options
Diffstat (limited to 'Xenogears/compil-2.lex')
-rw-r--r-- | Xenogears/compil-2.lex | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/Xenogears/compil-2.lex b/Xenogears/compil-2.lex new file mode 100644 index 0000000..805a964 --- /dev/null +++ b/Xenogears/compil-2.lex @@ -0,0 +1,254 @@ + /* 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); + +%% + +<INITIAL>"<Blocks:"\ *[[:digit:]]+">"\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_lines = 2; + + BEGIN(O); + } + +<INITIAL>.* { + fprintf(stderr, "Invalid file, must begin with <Blocks: XX>\n"); + errstate = 1; + num_lines = 2; + num_blocks = 9999; + } + +<O>"<Text_block lines:"\ *[[:digit:]]+\ + { + if (cur_num_block >= num_blocks) { + fprintf(stderr, "Error: too much blocks at line %i\n", num_lines); + errstate = 1; + } + block_lines = atoi(yytext + 18); + BEGIN(W); + } + +<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; + BEGIN(I); + } + +<W>.* { + fprintf(stderr, "Error: invalid arguments to command Text_block at line %i: '%s'\n", num_lines, yytext); + errstate = 1; + BEGIN(O); + } + +<I>\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('\n', yyout); + } + +<I>"<New>\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('\n', yyout); + } + +<I>"<Wait>\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('\n', yyout); + } + +<I>"<Wait>" { + cur_num_lines = 1; + } + +<I>"<Delay"\ +[[:digit:]]+">" { + int d = atoi(yytext + 7); + if (d > 255) { + fprintf(stderr, "Error: delay too important: %i\n", d); + errstate = 1; + } + } + +<I>"<Gear"\ +[[:digit:]]+">" { + 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; + } + } + +<I>"<Opcode"\ +/[[:digit:]]+\ +[[:digit:]]+">" { + BEGIN(Op); + } + +<Op>[[:digit:]]+\ +[[:digit:]]+">" { + int o1, o2; + o1 = atoi(yytext); + o2 = atoi(yytext + (o1 < 10 ? 2 : o1 < 100 ? 3 : 4)); + BEGIN(I); + } + +<Op>[^<]*">" { + yytext[strlen(yytext - 1)] = 0; + fprintf(stderr, "Error: invalid OpCode '%s'\n", yytext); + errstate = 1; + BEGIN(I); + } + +<I>"<"[[:digit:]]">" unput(*(yytext + 1)); +<I>"<".">" unput(*(yytext + 1)); +<I>"<..>" unput('.'); unput('.'); +<I>"<...>" unput('.'); unput('.'); unput('.'); + +<I>"<Extra1"\ +[[:digit:]]+">" { + 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); + } + } + +<I>"<Extra2"\ +[[:digit:]]+">" { + 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); + } + } + +<I>"<Bare"\ +[[:xdigit:]]{1,2}">" { + 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); + } + } + +<I>"<oe>" unput('e'); unput('o'); +<I>"<ae>" unput('e'); unput('a'); + +<I>"\n<End_of_block>" { + 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); + num_lines++; + cur_num_block++; + putc('\n', yyout); + putc('\n', yyout); + BEGIN(O); + } + +<I>"<"[^\>\n]*">" { + yytext[strlen(yytext) - 1] = 0; + fprintf(stderr, "Error: Invalid command at line %i: '%s'\n", num_lines, yytext + 1); + errstate = 1; + } + +<O>\n num_lines++; +<O>. /* Eat up comments */ + +<I>. { + putc(*yytext, yyout); + } + +. { + 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 <output> [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); +} |