diff options
author | Pixel <Pixel> | 2002-05-04 17:53:08 +0000 |
---|---|---|
committer | Pixel <Pixel> | 2002-05-04 17:53:08 +0000 |
commit | 24fb33726eca4e8c5a88797adc9c17f4d541f543 (patch) | |
tree | 72b385bd9e880e699e43c7db3ba12817f0e8e45e /Xenogears/compil.lex |
Initial revision
Diffstat (limited to 'Xenogears/compil.lex')
-rw-r--r-- | Xenogears/compil.lex | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/Xenogears/compil.lex b/Xenogears/compil.lex new file mode 100644 index 0000000..f6ceda8 --- /dev/null +++ b/Xenogears/compil.lex @@ -0,0 +1,383 @@ + #include <string.h> + /* 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 *); + +%% + +<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_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); + } + +<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; + 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); + } + +<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(1, 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(2, 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(1, yyout); + putc(3, yyout); + } + +<I>"<Wait>" { + cur_num_lines = 1; + putc(3, yyout); + } + +<I>"<Delay"\ +[[:digit:]]+">" { + 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); + } + } + +<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)); + putc(0xf, yyout); + putc(o1, yyout); + putc(o2, yyout); + BEGIN(I); + } + +<Op>[^<]*">" { + yytext[strlen(yytext - 1)] = 0; + fprintf(stderr, "Error: invalid OpCode '%s'\n", yytext); + errstate = 1; + BEGIN(I); + } + +<I>" " yputc(0x10, 2); +<I>"+" yputc(0x11, 2); +<I>"," yputc(0x12, 2); +<I>"-" yputc(0x13, 2); +<I>"." yputc(0x14, 2); +<I>"/" yputc(0x15, 2); +<I>[[:digit:]] yputc(*yytext - 0x1a, 2); +<I>[[:upper:]] yputc(*yytext - 0x21, 2); +<I>"[" yputc(0x3a, 2); +<I>"]" yputc(0x3b, 2); +<I>"=" yputc(0x3c, 2); +<I>[[:lower:]] yputc(*yytext - 0x24, 2); +<I>"!" yputc(0x57, 2); +<I>"\"" yputc(0x58, 2); +<I>"#" yputc(0x59, 2); +<I>"%" yputc(0x5a, 2); +<I>"&" yputc(0x5b, 2); +<I>"'" yputc(0x5c, 2); +<I>"(" yputc(0x5d, 2); +<I>")" yputc(0x5e, 2); +<I>":" yputc(0x5f, 2); +<I>"?" yputc(0x60, 2); +<I>"<"[[:digit:]]">" yputc(*(yytext + 1) + 0x31, 3); +<I>"<%>" yputc(0x6b, 3); +<I>"<&>" yputc(0x6c, 3); +<I>"*" yputc(0x6d, 3); +<I>"<C>" yputc(0x6e, 3); +<I>"<S>" yputc(0x6f, 3); +<I>"<T>" yputc(0x70, 3); +<I>"<*>" yputc(0x71, 3); +<I>"<R>" yputc(0x72, 3); +<I>"<L>" yputc(0x73, 3); +<I>"<U>" yputc(0x74, 3); +<I>"<D>" yputc(0x75, 3); +<I>"<.>" yputc(0x76, 3); +<I>"<:>" yputc(0x77, 3); +<I>"</>" yputc(0x79, 3); +<I>"<..>" yputc(0x7a, 3); +<I>"<`>" yputc(0x7b, 3); +<I>"<+>" yputc(0x7d, 3); +<I>"<->" yputc(0x7e, 3); +<I>"<X>" yputc(0x7f, 3); +<I>"<[>" yputc(0x80, 3); +<I>"<]>" yputc(0x81, 3); +<I>"<(>" yputc(0x84, 3); +<I>"<)>" yputc(0x85, 3); +<I>"<#>" yputc(0x86, 3); +<I>"`" yputc(0x87, 3); +<I>"°" yputc(0x88, 3); +<I>"<=>" yputc(0x89, 3); +<I>"<?>" yputc(0x8a, 3); +<I>"<!>" yputc(0x8b, 3); +<I>"_" yputc(0x8c, 3); +<I>"~" yputc(0x8d, 3); +<I>"<...>" yputc(0x8e, 3); +<I>"<'>" yputc(0x8f, 3); + +<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>à|â|ä unput('a'); +<I>é|è|ê|ë unput('e'); +<I>î|ï unput('i'); +<I>ô|ö unput('o'); +<I>û|ü|ù unput('u'); +<I>ç unput('c'); +<I>"<oe>" unput('e'); unput('o'); +<I>"<ae>" unput('e'); unput('a'); + +<I>"<Fei>" unputs("<Gear 00>"); +<I>"<Elly>" unputs("<Gear 01>"); +<I>"<Citan>" unputs("<Gear 02>"); +<I>"<Bart>" unputs("<Gear 03>"); +<I>"<Billy>" unputs("<Gear 04>"); +<I>"<Rico>" unputs("<Gear 05>"); +<I>"<Emeralda>" unputs("<Gear 06>"); +<I>"<Chu-Chu>" unputs("<Gear 07>"); +<I>"<Maria>" unputs("<Gear 08>"); +<I>"<Citan-2>" unputs("<Gear 09>"); +<I>"<Emeralda-2>" unputs("<Gear 10>"); +<I>"<Weltall>" unputs("<Gear 11>"); +<I>"<Waltall-2>" unputs("<Gear 12>"); +<I>"<Vierge>" unputs("<Gear 13>"); +<I>"<Heimdal>" unputs("<Gear 14>"); +<I>"<Brigandier>" unputs("<Gear 15>"); +<I>"<Renmazuo>" unputs("<Gear 16>"); +<I>"<Stier>" unputs("<Gear 17>"); +<I>"<BigChu-chu>" unputs("<Gear 18>"); +<I>"<Seibzehn>" unputs("<Gear 19>"); +<I>"<Crescens>" unputs("<Gear 20>"); +<I>"<Regurus>" unputs("<Gear 21>"); +<I>"<Fenrir>" unputs("<Gear 22>"); +<I>"<Andvari>" unputs("<Gear 23>"); +<I>"<Renmazuo>" unputs("<Gear 24>"); +<I>"<Stier-2>" unputs("<Gear 25>"); +<I>"<Xenogears>" unputs("<Gear 26>"); +<I>"<BARTHOS>" unputs("<Gear 27>"); +<I>"<Yggdra>" unputs("<Gear 29>"); +<I>"<Perso1>" unputs("<Gear 128>"); +<I>"<Perso2>" unputs("<Gear 129>"); +<I>"<Perso3>" unputs("<Gear 130>"); + + +<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); + 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); + } + +<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>. { + 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 <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); +} + +void unputs(char * s) { + int l = strlen(s), i; + + for (i = l - 1; i >= 0; i--) { + unput(s[i]); + } +} |