summaryrefslogtreecommitdiff
path: root/Xenogears/compil-2.lex
diff options
context:
space:
mode:
Diffstat (limited to 'Xenogears/compil-2.lex')
-rw-r--r--Xenogears/compil-2.lex254
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);
+}