diff --git a/docs/rh-log.txt b/docs/rh-log.txt index fd6cae8219..f64bb51b1d 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,22 @@ January 25, 2008 +- Undid some of the changes from lempar.c v1.30->v1.31, because it broke + error handling. +- Fixed: dehsupp/scanner.re defined "}" as the token RPAREN. dehsupp/parse.y + also defined action_list_def as needing a RBARCE. I'm surprised it worked + at all before. I guess Lemon really was too accepting. I have verified that + the lump it outputs is unchanged from before. +- Changed the way that xlatcc handles include statements so that I don't need + to modify the logic of lempar.c. I also discovered that the grammar was + improperly defined and only accepted the first statement. It worked before + because Lemon used to accept multiple times before reaching the EOF token. + I have also verified that it is still generating the proper lumps. +- Removed some unused wadsrc files from the repository. +- Fixed my re2c upgrade. +- Back to lemon.c v1.53 now. The bad change was v1.51: "Changes lemon so + that the generated parser does not accept prior to seeing the EOF token." + This seems like a valid change, which means I need to rethink my strategy + for handling include statements, since this change breaks what I was + doing before. - Lemon is now producing parsers that don't accept anything, so I'm going back to v1.43 and trying each intermediate version to see where things went wrong. diff --git a/src/sc_man_scanner.h b/src/sc_man_scanner.h index 7271eb93f4..b298cffdaa 100644 --- a/src/sc_man_scanner.h +++ b/src/sc_man_scanner.h @@ -1,4 +1,4 @@ -/* Generated by re2c 0.10.5 */ +/* Generated by re2c 0.12.3 */ #line 1 "src/sc_man_scanner.re" #define YYCTYPE char #define YYCURSOR cursor @@ -42,7 +42,7 @@ std2: if((YYLIMIT - YYCURSOR) < 18) YYFILL(18); yych = *YYCURSOR; - switch(yych){ + switch(yych) { case 0x09: case 0x0B: case 0x0C: @@ -181,7 +181,7 @@ yy5: #line 182 "src/sc_man_scanner.h" yy6: yych = *++YYCURSOR; - switch(yych){ + switch(yych) { case 'A': case 'a': goto yy536; case 'H': @@ -309,7 +309,7 @@ yy12: goto yy174; yy13: yych = *++YYCURSOR; - switch(yych){ + switch(yych) { case 'B': case 'b': goto yy346; case 'E': @@ -330,7 +330,7 @@ yy13: } yy14: yych = *++YYCURSOR; - switch(yych){ + switch(yych) { case 'I': case 'i': goto yy326; case 'L': diff --git a/tools/dehsupp/dehsupp.c b/tools/dehsupp/dehsupp.c index 86595acfa1..8e805510a6 100644 --- a/tools/dehsupp/dehsupp.c +++ b/tools/dehsupp/dehsupp.c @@ -48,6 +48,9 @@ int main (int argc, char **argv) printf ("Could not open %s\n", argv[1]); return -2; } +#if !defined(NDEBUG) && 0 + ParseTrace(fopen("trace.txt", "w"), ""); +#endif SourceLine = 1; yyparse (); fclose (Source); diff --git a/tools/dehsupp/dehsupp.vcproj b/tools/dehsupp/dehsupp.vcproj index 6649be2051..bdce02aa26 100644 --- a/tools/dehsupp/dehsupp.vcproj +++ b/tools/dehsupp/dehsupp.vcproj @@ -424,7 +424,7 @@ @@ -444,7 +444,7 @@ diff --git a/tools/dehsupp/parse.c b/tools/dehsupp/parse.c index da7a6cbac0..93a50ab962 100644 --- a/tools/dehsupp/parse.c +++ b/tools/dehsupp/parse.c @@ -5,11 +5,12 @@ ** in the input file. */ #include #include +#include #line 1 "parse.y" #include #include "dehsupp.h" -#line 13 "parse.c" +#line 14 "parse.c" /* Next is all token values, in a form suitable for use by makeheaders. ** This section will be null unless lemon is run with the -m switch. */ @@ -48,7 +49,8 @@ ** This is typically a union of many types, one of ** which is ParseTOKENTYPE. The entry in the union ** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. +** YYSTACKDEPTH is the maximum depth of the parser's stack. If +** zero the stack is dynamically sized using realloc() ** ParseARG_SDECL A static variable declaration for the %extra_argument ** ParseARG_PDECL A parameter declaration for the %extra_argument ** ParseARG_STORE Code to store %extra_argument into yypParser @@ -59,23 +61,25 @@ ** defined, then do no error processing. */ #define YYCODETYPE unsigned char -#define YYNOCODE 68 -#define YYACTIONTYPE unsigned char +#define YYNOCODE 67 +#define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE struct Token typedef union { ParseTOKENTYPE yy0; - int yy62; - int yy135; + int yy64; + int yy133; } YYMINORTYPE; +#ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 +#endif #define ParseARG_SDECL #define ParseARG_PDECL #define ParseARG_FETCH #define ParseARG_STORE -#define YYNSTATE 140 -#define YYNRULE 77 -#define YYERRORSYMBOL 35 -#define YYERRSYMDT yy135 +#define YYNSTATE 170 +#define YYNRULE 87 +#define YYERRORSYMBOL 34 +#define YYERRSYMDT yy133 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) @@ -128,85 +132,96 @@ typedef union { ** yy_default[] Default action for each state. */ static const YYACTIONTYPE yy_action[] = { - /* 0 */ 137, 131, 130, 126, 120, 119, 118, 117, 109, 101, - /* 10 */ 95, 94, 80, 14, 17, 20, 23, 18, 15, 71, - /* 20 */ 20, 23, 18, 15, 86, 60, 45, 68, 76, 84, - /* 30 */ 93, 77, 36, 74, 66, 57, 73, 16, 14, 17, - /* 40 */ 20, 23, 18, 15, 17, 20, 23, 18, 15, 11, - /* 50 */ 33, 16, 14, 17, 20, 23, 18, 15, 21, 32, - /* 60 */ 82, 50, 128, 61, 72, 16, 14, 17, 20, 23, - /* 70 */ 18, 15, 54, 139, 18, 15, 132, 32, 16, 14, - /* 80 */ 17, 20, 23, 18, 15, 96, 97, 98, 55, 99, - /* 90 */ 78, 138, 16, 14, 17, 20, 23, 18, 15, 19, - /* 100 */ 19, 83, 77, 36, 40, 90, 24, 24, 44, 100, - /* 110 */ 129, 103, 103, 67, 62, 81, 58, 8, 65, 70, - /* 120 */ 69, 79, 59, 64, 22, 33, 38, 9, 52, 63, - /* 130 */ 56, 107, 30, 85, 218, 1, 7, 127, 87, 47, - /* 140 */ 136, 10, 89, 49, 88, 48, 13, 115, 91, 3, - /* 150 */ 46, 121, 133, 2, 92, 28, 12, 29, 34, 53, - /* 160 */ 37, 39, 51, 4, 134, 135, 102, 111, 43, 25, - /* 170 */ 124, 6, 75, 106, 41, 26, 113, 42, 5, 108, - /* 180 */ 35, 31, 125, 219, 105, 110, 104, 219, 123, 116, - /* 190 */ 27, 122, 114, 112, + /* 0 */ 170, 32, 25, 22, 24, 26, 23, 28, 27, 21, + /* 10 */ 56, 147, 101, 35, 83, 165, 17, 87, 108, 145, + /* 20 */ 137, 144, 57, 66, 77, 88, 99, 58, 101, 35, + /* 30 */ 92, 65, 98, 67, 167, 166, 164, 162, 161, 159, + /* 40 */ 158, 157, 156, 153, 152, 150, 25, 22, 24, 26, + /* 50 */ 23, 28, 27, 24, 26, 23, 28, 27, 29, 16, + /* 60 */ 25, 22, 24, 26, 23, 28, 27, 26, 23, 28, + /* 70 */ 27, 140, 31, 25, 22, 24, 26, 23, 28, 27, + /* 80 */ 33, 97, 80, 100, 151, 104, 72, 25, 22, 24, + /* 90 */ 26, 23, 28, 27, 22, 24, 26, 23, 28, 27, + /* 100 */ 32, 60, 63, 21, 53, 117, 111, 112, 113, 51, + /* 110 */ 17, 85, 46, 48, 169, 144, 9, 79, 31, 39, + /* 120 */ 75, 54, 84, 82, 73, 18, 76, 10, 38, 44, + /* 130 */ 155, 81, 47, 89, 93, 95, 28, 27, 106, 78, + /* 140 */ 91, 71, 30, 69, 52, 62, 19, 107, 102, 143, + /* 150 */ 258, 1, 59, 146, 168, 109, 142, 49, 4, 55, + /* 160 */ 103, 45, 41, 94, 8, 2, 5, 43, 114, 50, + /* 170 */ 42, 141, 96, 115, 116, 40, 37, 12, 34, 131, + /* 180 */ 118, 105, 36, 138, 163, 128, 121, 13, 15, 110, + /* 190 */ 20, 259, 119, 86, 139, 149, 126, 7, 148, 160, + /* 200 */ 136, 120, 90, 134, 130, 6, 135, 61, 124, 154, + /* 210 */ 122, 133, 64, 259, 259, 123, 129, 74, 11, 127, + /* 220 */ 70, 14, 3, 125, 259, 132, 68, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - /* 10 */ 48, 49, 10, 2, 3, 4, 5, 6, 7, 17, - /* 20 */ 4, 5, 6, 7, 22, 23, 61, 25, 26, 27, - /* 30 */ 50, 51, 52, 31, 32, 33, 34, 1, 2, 3, - /* 40 */ 4, 5, 6, 7, 3, 4, 5, 6, 7, 13, - /* 50 */ 52, 1, 2, 3, 4, 5, 6, 7, 13, 52, - /* 60 */ 21, 63, 64, 13, 19, 1, 2, 3, 4, 5, - /* 70 */ 6, 7, 65, 66, 6, 7, 12, 52, 1, 2, - /* 80 */ 3, 4, 5, 6, 7, 28, 29, 30, 58, 59, - /* 90 */ 13, 66, 1, 2, 3, 4, 5, 6, 7, 4, - /* 100 */ 4, 50, 51, 52, 52, 59, 11, 11, 56, 14, - /* 110 */ 15, 16, 16, 13, 13, 13, 13, 13, 13, 19, - /* 120 */ 19, 19, 19, 19, 13, 52, 52, 13, 54, 24, - /* 130 */ 19, 14, 13, 19, 36, 37, 18, 64, 19, 57, - /* 140 */ 20, 18, 21, 55, 12, 62, 13, 21, 21, 11, - /* 150 */ 53, 21, 21, 13, 20, 18, 13, 18, 52, 52, - /* 160 */ 52, 52, 52, 18, 20, 52, 20, 52, 52, 18, - /* 170 */ 20, 18, 60, 14, 52, 18, 52, 52, 18, 21, - /* 180 */ 52, 52, 20, 67, 21, 20, 20, 67, 21, 20, - /* 190 */ 18, 21, 21, 20, + /* 0 */ 0, 51, 1, 2, 3, 4, 5, 6, 7, 4, + /* 10 */ 10, 49, 50, 51, 13, 65, 11, 17, 58, 14, + /* 20 */ 15, 16, 22, 23, 24, 25, 26, 49, 50, 51, + /* 30 */ 30, 31, 32, 33, 37, 38, 39, 40, 41, 42, + /* 40 */ 43, 44, 45, 46, 47, 48, 1, 2, 3, 4, + /* 50 */ 5, 6, 7, 3, 4, 5, 6, 7, 13, 13, + /* 60 */ 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, + /* 70 */ 7, 12, 51, 1, 2, 3, 4, 5, 6, 7, + /* 80 */ 51, 34, 34, 34, 63, 13, 34, 1, 2, 3, + /* 90 */ 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, + /* 100 */ 51, 34, 34, 4, 57, 58, 27, 28, 29, 61, + /* 110 */ 11, 34, 60, 64, 65, 16, 13, 13, 51, 51, + /* 120 */ 13, 53, 19, 19, 34, 13, 19, 13, 51, 62, + /* 130 */ 63, 19, 55, 19, 13, 34, 6, 7, 21, 13, + /* 140 */ 19, 13, 13, 34, 54, 19, 13, 19, 19, 51, + /* 150 */ 35, 36, 19, 21, 20, 20, 51, 56, 13, 51, + /* 160 */ 19, 52, 51, 19, 18, 18, 11, 51, 20, 51, + /* 170 */ 51, 51, 19, 21, 20, 51, 51, 18, 51, 21, + /* 180 */ 20, 59, 51, 20, 20, 14, 21, 18, 18, 21, + /* 190 */ 13, 66, 20, 19, 21, 20, 20, 18, 12, 21, + /* 200 */ 20, 20, 19, 21, 20, 18, 21, 19, 14, 20, + /* 210 */ 20, 20, 19, 66, 66, 20, 20, 19, 18, 20, + /* 220 */ 19, 18, 18, 21, 66, 20, 19, }; #define YY_SHIFT_USE_DFLT (-1) -#define YY_SHIFT_MAX 87 +#define YY_SHIFT_MAX 107 static const short yy_shift_ofst[] = { - /* 0 */ -1, 2, 95, 95, 96, 96, 96, 96, 96, 96, - /* 10 */ 39, 96, 96, 57, 96, 96, 96, 96, 96, 96, - /* 20 */ 96, 96, 96, 96, 96, 130, 126, 163, 121, 117, - /* 30 */ 39, 50, 77, 36, 64, 91, 91, 91, 91, 91, - /* 40 */ 91, 11, 41, 16, 45, 100, 101, 102, 103, 105, - /* 50 */ 104, 68, 111, 68, 114, 119, 169, 160, 171, 173, - /* 60 */ 172, 170, 167, 165, 162, 158, 157, 159, 153, 150, - /* 70 */ 166, 151, 146, 145, 139, 143, 137, 140, 131, 134, - /* 80 */ 138, 127, 133, 132, 123, 120, 118, 144, + /* 0 */ -1, 0, 99, 99, 5, 5, 99, 99, 117, 99, + /* 10 */ 99, 173, 171, 168, 165, 158, 99, 99, 99, 99, + /* 20 */ 79, 99, 99, 99, 99, 99, 99, 99, 99, 99, + /* 30 */ 117, 45, 1, 72, 59, 86, 86, 86, 86, 86, + /* 40 */ 86, 92, 50, 63, 103, 104, 107, 112, 114, 121, + /* 50 */ 130, 126, 128, 129, 133, 130, 155, 179, 186, 184, + /* 60 */ 188, 189, 191, 193, 196, 200, 203, 204, 205, 207, + /* 70 */ 199, 202, 201, 198, 195, 194, 190, 187, 185, 182, + /* 80 */ 183, 181, 180, 178, 175, 174, 172, 170, 169, 164, + /* 90 */ 163, 160, 159, 152, 154, 153, 148, 144, 147, 146, + /* 100 */ 141, 145, 135, 134, 132, 46, 177, 176, }; -#define YY_REDUCE_USE_DFLT (-39) +#define YY_REDUCE_USE_DFLT (-51) #define YY_REDUCE_MAX 30 static const short yy_reduce_ofst[] = { - /* 0 */ 98, -38, -20, 51, 7, -2, 52, 74, 73, 25, - /* 10 */ 30, 129, 128, 112, 125, 124, 122, 116, 115, 113, - /* 20 */ 110, 109, 108, 107, 106, 97, 83, 88, 82, -35, - /* 30 */ 46, + /* 0 */ 115, -3, 67, 49, -38, -22, 77, 68, 47, 21, + /* 10 */ -50, 48, 52, 101, 90, 109, 131, 127, 125, 124, + /* 20 */ 122, 120, 119, 118, 116, 111, 108, 105, 98, 29, + /* 30 */ -40, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 141, 140, 155, 155, 213, 208, 184, 176, 217, 217, - /* 10 */ 192, 217, 217, 217, 217, 217, 217, 217, 217, 217, - /* 20 */ 217, 217, 217, 217, 217, 172, 204, 180, 188, 200, - /* 30 */ 217, 217, 217, 217, 217, 195, 159, 178, 177, 186, - /* 40 */ 185, 166, 168, 167, 217, 217, 217, 217, 217, 217, - /* 50 */ 217, 163, 217, 162, 217, 217, 217, 217, 217, 217, - /* 60 */ 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - /* 70 */ 217, 217, 217, 217, 217, 217, 217, 156, 217, 217, - /* 80 */ 217, 217, 217, 217, 217, 217, 217, 217, 154, 189, - /* 90 */ 194, 190, 187, 157, 153, 152, 196, 197, 198, 193, - /* 100 */ 158, 151, 183, 161, 199, 181, 202, 201, 182, 150, - /* 110 */ 179, 164, 203, 165, 206, 205, 175, 149, 148, 147, - /* 120 */ 146, 173, 211, 174, 171, 207, 145, 210, 209, 160, - /* 130 */ 144, 143, 170, 216, 191, 169, 212, 142, 215, 214, + /* 0 */ 171, 257, 247, 253, 185, 185, 218, 208, 228, 257, + /* 10 */ 257, 242, 237, 223, 213, 203, 257, 257, 257, 257, + /* 20 */ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + /* 30 */ 257, 257, 257, 257, 257, 189, 231, 220, 219, 209, + /* 40 */ 210, 196, 198, 197, 257, 257, 257, 257, 257, 257, + /* 50 */ 192, 257, 257, 257, 257, 193, 257, 257, 257, 257, + /* 60 */ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + /* 70 */ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + /* 80 */ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + /* 90 */ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + /* 100 */ 257, 186, 257, 257, 257, 257, 257, 257, 230, 226, + /* 110 */ 224, 232, 233, 234, 222, 225, 227, 229, 221, 217, + /* 120 */ 216, 214, 235, 212, 239, 215, 211, 236, 238, 207, + /* 130 */ 206, 204, 202, 240, 205, 244, 201, 190, 241, 243, + /* 140 */ 200, 199, 195, 194, 191, 188, 250, 187, 184, 245, + /* 150 */ 183, 249, 182, 181, 246, 248, 180, 179, 178, 177, + /* 160 */ 256, 176, 175, 251, 174, 255, 173, 172, 252, 254, }; #define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) @@ -252,7 +267,12 @@ struct yyParser { int yyidx; /* Index of top element in stack */ int yyerrcnt; /* Shifts left before out of the error */ ParseARG_SDECL /* A place to hold %extra_argument */ +#if YYSTACKDEPTH<=0 + int yystksz; /* Current side of the stack */ + yyStackEntry *yystack; /* The parser's stack */ +#else yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ +#endif }; typedef struct yyParser yyParser; @@ -298,17 +318,17 @@ static const char *const yyTokenName[] = { "RPAREN", "COMMA", "STRING", "ENDL", "NUM", "Actions", "LBRACE", "RBRACE", "SEMICOLON", "SYM", "OrgHeights", "ActionList", - "RBARCE", "CodePConv", "OrgSprNames", "StateMap", - "FirstState", "SpawnState", "DeathState", "SoundMap", - "InfoNames", "ThingBits", "RenderStyles", "error", - "main", "translation_unit", "external_declaration", "print_statement", - "actions_def", "org_heights_def", "action_list_def", "codep_conv_def", - "org_spr_names_def", "state_map_def", "sound_map_def", "info_names_def", - "thing_bits_def", "render_styles_def", "print_list", "print_item", - "exp", "actions_list", "org_heights_list", "action_list_list", - "codep_conv_list", "org_spr_names_list", "state_map_list", "state_map_entry", - "state_type", "sound_map_list", "info_names_list", "thing_bits_list", - "thing_bits_entry", "render_styles_list", "render_styles_entry", + "CodePConv", "OrgSprNames", "StateMap", "FirstState", + "SpawnState", "DeathState", "SoundMap", "InfoNames", + "ThingBits", "RenderStyles", "error", "main", + "translation_unit", "external_declaration", "print_statement", "actions_def", + "org_heights_def", "action_list_def", "codep_conv_def", "org_spr_names_def", + "state_map_def", "sound_map_def", "info_names_def", "thing_bits_def", + "render_styles_def", "print_list", "print_item", "exp", + "actions_list", "org_heights_list", "action_list_list", "codep_conv_list", + "org_spr_names_list", "state_map_list", "state_map_entry", "state_type", + "sound_map_list", "info_names_list", "thing_bits_list", "thing_bits_entry", + "render_styles_list", "render_styles_entry", }; #endif /* NDEBUG */ @@ -348,69 +368,86 @@ static const char *const yyRuleName[] = { /* 29 */ "exp ::= MINUS exp", /* 30 */ "exp ::= LPAREN exp RPAREN", /* 31 */ "actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON", - /* 32 */ "actions_list ::=", - /* 33 */ "actions_list ::= SYM", - /* 34 */ "actions_list ::= actions_list COMMA SYM", - /* 35 */ "org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON", - /* 36 */ "org_heights_list ::=", - /* 37 */ "org_heights_list ::= exp", - /* 38 */ "org_heights_list ::= org_heights_list COMMA exp", - /* 39 */ "action_list_def ::= ActionList LBRACE action_list_list RBARCE SEMICOLON", - /* 40 */ "action_list_list ::=", - /* 41 */ "action_list_list ::= SYM", - /* 42 */ "action_list_list ::= action_list_list COMMA SYM", - /* 43 */ "codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON", - /* 44 */ "codep_conv_list ::=", - /* 45 */ "codep_conv_list ::= exp", - /* 46 */ "codep_conv_list ::= codep_conv_list COMMA exp", - /* 47 */ "org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON", - /* 48 */ "org_spr_names_list ::=", - /* 49 */ "org_spr_names_list ::= SYM", - /* 50 */ "org_spr_names_list ::= org_spr_names_list COMMA SYM", - /* 51 */ "state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON", - /* 52 */ "state_map_list ::=", - /* 53 */ "state_map_list ::= state_map_entry", - /* 54 */ "state_map_list ::= state_map_list COMMA state_map_entry", - /* 55 */ "state_map_entry ::= SYM COMMA state_type COMMA exp", - /* 56 */ "state_type ::= FirstState", - /* 57 */ "state_type ::= SpawnState", - /* 58 */ "state_type ::= DeathState", - /* 59 */ "sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON", - /* 60 */ "sound_map_list ::=", - /* 61 */ "sound_map_list ::= STRING", - /* 62 */ "sound_map_list ::= sound_map_list COMMA STRING", - /* 63 */ "info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON", - /* 64 */ "info_names_list ::=", - /* 65 */ "info_names_list ::= SYM", - /* 66 */ "info_names_list ::= info_names_list COMMA SYM", - /* 67 */ "thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON", - /* 68 */ "thing_bits_list ::=", - /* 69 */ "thing_bits_list ::= thing_bits_entry", - /* 70 */ "thing_bits_list ::= thing_bits_list COMMA thing_bits_entry", - /* 71 */ "thing_bits_entry ::= exp COMMA exp COMMA SYM", - /* 72 */ "render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON", - /* 73 */ "render_styles_list ::=", - /* 74 */ "render_styles_list ::= render_styles_entry", - /* 75 */ "render_styles_list ::= render_styles_list COMMA render_styles_entry", - /* 76 */ "render_styles_entry ::= exp COMMA SYM", + /* 32 */ "actions_def ::= Actions LBRACE error RBRACE SEMICOLON", + /* 33 */ "actions_list ::=", + /* 34 */ "actions_list ::= SYM", + /* 35 */ "actions_list ::= actions_list COMMA SYM", + /* 36 */ "org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON", + /* 37 */ "org_heights_def ::= OrgHeights LBRACE error RBRACE SEMICOLON", + /* 38 */ "org_heights_list ::=", + /* 39 */ "org_heights_list ::= exp", + /* 40 */ "org_heights_list ::= org_heights_list COMMA exp", + /* 41 */ "action_list_def ::= ActionList LBRACE action_list_list RBRACE SEMICOLON", + /* 42 */ "action_list_def ::= ActionList LBRACE error RBRACE SEMICOLON", + /* 43 */ "action_list_list ::=", + /* 44 */ "action_list_list ::= SYM", + /* 45 */ "action_list_list ::= action_list_list COMMA SYM", + /* 46 */ "codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON", + /* 47 */ "codep_conv_def ::= CodePConv LBRACE error RBRACE SEMICOLON", + /* 48 */ "codep_conv_list ::=", + /* 49 */ "codep_conv_list ::= exp", + /* 50 */ "codep_conv_list ::= codep_conv_list COMMA exp", + /* 51 */ "org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON", + /* 52 */ "org_spr_names_def ::= OrgSprNames LBRACE error RBRACE SEMICOLON", + /* 53 */ "org_spr_names_list ::=", + /* 54 */ "org_spr_names_list ::= SYM", + /* 55 */ "org_spr_names_list ::= org_spr_names_list COMMA SYM", + /* 56 */ "state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON", + /* 57 */ "state_map_def ::= StateMap LBRACE error RBRACE SEMICOLON", + /* 58 */ "state_map_list ::=", + /* 59 */ "state_map_list ::= state_map_entry", + /* 60 */ "state_map_list ::= state_map_list COMMA state_map_entry", + /* 61 */ "state_map_entry ::= SYM COMMA state_type COMMA exp", + /* 62 */ "state_type ::= FirstState", + /* 63 */ "state_type ::= SpawnState", + /* 64 */ "state_type ::= DeathState", + /* 65 */ "sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON", + /* 66 */ "sound_map_def ::= SoundMap LBRACE error RBRACE SEMICOLON", + /* 67 */ "sound_map_list ::=", + /* 68 */ "sound_map_list ::= STRING", + /* 69 */ "sound_map_list ::= sound_map_list COMMA STRING", + /* 70 */ "info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON", + /* 71 */ "info_names_def ::= InfoNames LBRACE error RBRACE SEMICOLON", + /* 72 */ "info_names_list ::=", + /* 73 */ "info_names_list ::= SYM", + /* 74 */ "info_names_list ::= info_names_list COMMA SYM", + /* 75 */ "thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON", + /* 76 */ "thing_bits_def ::= ThingBits LBRACE error RBRACE SEMICOLON", + /* 77 */ "thing_bits_list ::=", + /* 78 */ "thing_bits_list ::= thing_bits_entry", + /* 79 */ "thing_bits_list ::= thing_bits_list COMMA thing_bits_entry", + /* 80 */ "thing_bits_entry ::= exp COMMA exp COMMA SYM", + /* 81 */ "render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON", + /* 82 */ "render_styles_def ::= RenderStyles LBRACE error RBRACE SEMICOLON", + /* 83 */ "render_styles_list ::=", + /* 84 */ "render_styles_list ::= render_styles_entry", + /* 85 */ "render_styles_list ::= render_styles_list COMMA render_styles_entry", + /* 86 */ "render_styles_entry ::= exp COMMA SYM", }; #endif /* NDEBUG */ +#if YYSTACKDEPTH<=0 /* -** This function returns the symbolic name associated with a token -** value. +** Try to increase the size of the parser stack. */ -const char *ParseTokenName(int tokenType){ +static void yyGrowStack(yyParser *p){ + int newSize; + yyStackEntry *pNew; + + newSize = p->yystksz*2 + 100; + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + if( pNew ){ + p->yystack = pNew; + p->yystksz = newSize; #ifndef NDEBUG - if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){ - return yyTokenName[tokenType]; - }else{ - return "Unknown"; - } -#else - return ""; + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", + yyTracePrompt, p->yystksz); + } #endif + } } +#endif /* ** This function allocates a new parser. @@ -429,6 +466,9 @@ void *ParseAlloc(void *(*mallocProc)(size_t)){ pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); if( pParser ){ pParser->yyidx = -1; +#if YYSTACKDEPTH<=0 + yyGrowStack(pParser); +#endif } return pParser; } @@ -450,43 +490,42 @@ static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ ** which appear on the RHS of the rule, but which are not used ** inside the C code. */ - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - case 27: - case 28: - case 29: - case 30: - case 31: - case 32: - case 33: - case 34: -#line 8 "parse.y" + case 1: /* OR */ + case 2: /* XOR */ + case 3: /* AND */ + case 4: /* MINUS */ + case 5: /* PLUS */ + case 6: /* MULTIPLY */ + case 7: /* DIVIDE */ + case 8: /* NEG */ + case 9: /* EOI */ + case 10: /* PRINT */ + case 11: /* LPAREN */ + case 12: /* RPAREN */ + case 13: /* COMMA */ + case 14: /* STRING */ + case 15: /* ENDL */ + case 16: /* NUM */ + case 17: /* Actions */ + case 18: /* LBRACE */ + case 19: /* RBRACE */ + case 20: /* SEMICOLON */ + case 21: /* SYM */ + case 22: /* OrgHeights */ + case 23: /* ActionList */ + case 24: /* CodePConv */ + case 25: /* OrgSprNames */ + case 26: /* StateMap */ + case 27: /* FirstState */ + case 28: /* SpawnState */ + case 29: /* DeathState */ + case 30: /* SoundMap */ + case 31: /* InfoNames */ + case 32: /* ThingBits */ + case 33: /* RenderStyles */ +#line 10 "parse.y" { if ((yypminor->yy0).string) free((yypminor->yy0).string); } -#line 490 "parse.c" +#line 529 "parse.c" break; default: break; /* If no destructor action specified: do nothing */ } @@ -537,6 +576,9 @@ void ParseFree( yyParser *pParser = (yyParser*)p; if( pParser==0 ) return; while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + free(pParser->yystack); +#endif (*freeProc)((void*)pParser); } @@ -558,9 +600,7 @@ static int yy_find_shift_action( if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ return yy_default[stateno]; } - if( iLookAhead==YYNOCODE ){ - return YY_NO_ACTION; - } + assert( iLookAhead!=YYNOCODE ); i += iLookAhead; if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ if( iLookAhead>0 ){ @@ -611,21 +651,36 @@ static int yy_find_reduce_action( YYCODETYPE iLookAhead /* The look-ahead token */ ){ int i; - /* int stateno = pParser->yystack[pParser->yyidx].stateno; */ - if( stateno>YY_REDUCE_MAX || - (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){ - return yy_default[stateno]; - } - if( iLookAhead==YYNOCODE ){ - return YY_NO_ACTION; + (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){ + return yy_default[stateno]; } + assert( i!=YY_REDUCE_USE_DFLT ); + assert( iLookAhead!=YYNOCODE ); i += iLookAhead; if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ return yy_default[stateno]; }else{ - return yy_action[i]; + return yy_action[i]; } + return yy_action[i]; +} + +/* +** The following routine is called if the stack overflows. +*/ +static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){ + ParseARG_FETCH; + yypParser->yyidx--; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will execute if the parser + ** stack every overflows */ + ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ } /* @@ -639,20 +694,20 @@ static void yy_shift( ){ yyStackEntry *yytos; yypParser->yyidx++; +#if YYSTACKDEPTH>0 if( yypParser->yyidx>=YYSTACKDEPTH ){ - ParseARG_FETCH; - yypParser->yyidx--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack ever overflows */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ - return; + yyStackOverflow(yypParser, yypMinor); + return; } +#else + if( yypParser->yyidx>=yypParser->yystksz ){ + yyGrowStack(yypParser); + if( yypParser->yyidx>=yypParser->yystksz ){ + yyStackOverflow(yypParser, yypMinor); + return; + } + } +#endif yytos = &yypParser->yystack[yypParser->yyidx]; yytos->stateno = yyNewState; yytos->major = yyMajor; @@ -663,7 +718,7 @@ static void yy_shift( fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); + fprintf(yyTraceFILE," (%d)%s",yypParser->yystack[i].stateno,yyTokenName[yypParser->yystack[i].major]); fprintf(yyTraceFILE,"\n"); } #endif @@ -676,83 +731,93 @@ static const struct { YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ unsigned char nrhs; /* Number of right-hand side symbols in the rule */ } yyRuleInfo[] = { - { 36, 1 }, - { 37, 0 }, - { 37, 2 }, - { 38, 1 }, - { 38, 1 }, - { 38, 1 }, - { 38, 1 }, - { 38, 1 }, - { 38, 1 }, - { 38, 1 }, - { 38, 1 }, - { 38, 1 }, - { 38, 1 }, - { 38, 1 }, - { 39, 4 }, - { 50, 0 }, + { 35, 1 }, + { 36, 0 }, + { 36, 2 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 38, 4 }, + { 49, 0 }, + { 49, 1 }, + { 49, 3 }, + { 50, 1 }, + { 50, 1 }, { 50, 1 }, - { 50, 3 }, - { 51, 1 }, - { 51, 1 }, { 51, 1 }, + { 51, 3 }, + { 51, 3 }, + { 51, 3 }, + { 51, 3 }, + { 51, 3 }, + { 51, 3 }, + { 51, 3 }, + { 51, 2 }, + { 51, 3 }, + { 39, 5 }, + { 39, 5 }, + { 52, 0 }, { 52, 1 }, { 52, 3 }, - { 52, 3 }, - { 52, 3 }, - { 52, 3 }, - { 52, 3 }, - { 52, 3 }, - { 52, 3 }, - { 52, 2 }, - { 52, 3 }, + { 40, 5 }, { 40, 5 }, { 53, 0 }, { 53, 1 }, { 53, 3 }, { 41, 5 }, + { 41, 5 }, { 54, 0 }, { 54, 1 }, { 54, 3 }, { 42, 5 }, + { 42, 5 }, { 55, 0 }, { 55, 1 }, { 55, 3 }, { 43, 5 }, + { 43, 5 }, { 56, 0 }, { 56, 1 }, { 56, 3 }, { 44, 5 }, + { 44, 5 }, { 57, 0 }, { 57, 1 }, { 57, 3 }, + { 58, 5 }, + { 59, 1 }, + { 59, 1 }, + { 59, 1 }, { 45, 5 }, - { 58, 0 }, - { 58, 1 }, - { 58, 3 }, - { 59, 5 }, - { 60, 1 }, - { 60, 1 }, + { 45, 5 }, + { 60, 0 }, { 60, 1 }, + { 60, 3 }, + { 46, 5 }, { 46, 5 }, { 61, 0 }, { 61, 1 }, { 61, 3 }, { 47, 5 }, + { 47, 5 }, { 62, 0 }, { 62, 1 }, { 62, 3 }, + { 63, 5 }, { 48, 5 }, - { 63, 0 }, - { 63, 1 }, - { 63, 3 }, - { 64, 5 }, - { 49, 5 }, - { 65, 0 }, - { 65, 1 }, + { 48, 5 }, + { 64, 0 }, + { 64, 1 }, + { 64, 3 }, { 65, 3 }, - { 66, 3 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -806,206 +871,360 @@ static void yy_reduce( ** #line ** break; */ - case 14: -#line 37 "parse.y" + case 0: /* main ::= translation_unit */ + case 1: /*translation_unit ::= */ + case 2: /*translation_unit ::= translation_unit external_declaration */ + case 3: /*external_declaration ::= print_statement */ + case 4: /*external_declaration ::= actions_def */ + case 5: /*external_declaration ::= org_heights_def */ + case 6: /*external_declaration ::= action_list_def */ + case 7: /*external_declaration ::= codep_conv_def */ + case 8: /*external_declaration ::= org_spr_names_def */ + case 9: /*external_declaration ::= state_map_def */ + case 10: /*external_declaration ::= sound_map_def */ + case 11: /*external_declaration ::= info_names_def */ + case 12: /*external_declaration ::= thing_bits_def */ + case 13: /*external_declaration ::= render_styles_def */ + case 15: /*print_list ::= */ + case 16: /*print_list ::= print_item */ + case 33: /*actions_list ::= */ + case 38: /*org_heights_list ::= */ + case 43: /*action_list_list ::= */ + case 48: /*codep_conv_list ::= */ + case 53: /*org_spr_names_list ::= */ + case 58: /*state_map_list ::= */ + case 59: /*state_map_list ::= state_map_entry */ + case 67: /*sound_map_list ::= */ + case 72: /*info_names_list ::= */ + case 77: /*thing_bits_list ::= */ + case 78: /*thing_bits_list ::= thing_bits_entry */ + case 83: /*render_styles_list ::= */ + case 84: /*render_styles_list ::= render_styles_entry */ +#line 21 "parse.y" +{ +} +#line 907 "parse.c" + break; + case 14: /* print_statement ::= PRINT LPAREN print_list RPAREN */ +#line 39 "parse.y" { printf ("\n"); yy_destructor(10,&yymsp[-3].minor); yy_destructor(11,&yymsp[-2].minor); yy_destructor(12,&yymsp[0].minor); } -#line 818 "parse.c" +#line 917 "parse.c" break; - case 18: + case 17: /* print_list ::= print_item COMMA print_list */ + case 60: /*state_map_list ::= state_map_list COMMA state_map_entry */ + case 79: /*thing_bits_list ::= thing_bits_list COMMA thing_bits_entry */ + case 85: /*render_styles_list ::= render_styles_list COMMA render_styles_entry */ #line 45 "parse.y" -{ printf ("%s", yymsp[0].minor.yy0.string); } -#line 823 "parse.c" - break; - case 19: -#line 46 "parse.y" -{ printf ("%d", yymsp[0].minor.yy62); } -#line 828 "parse.c" - break; - case 20: -#line 47 "parse.y" -{ printf ("\n"); yy_destructor(15,&yymsp[0].minor); -} -#line 834 "parse.c" - break; - case 21: -#line 50 "parse.y" -{ yygotominor.yy62 = yymsp[0].minor.yy0.val; } -#line 839 "parse.c" - break; - case 22: -#line 51 "parse.y" -{ yygotominor.yy62 = yymsp[-2].minor.yy62 + yymsp[0].minor.yy62; yy_destructor(5,&yymsp[-1].minor); -} -#line 845 "parse.c" - break; - case 23: -#line 52 "parse.y" -{ yygotominor.yy62 = yymsp[-2].minor.yy62 - yymsp[0].minor.yy62; yy_destructor(4,&yymsp[-1].minor); -} -#line 851 "parse.c" - break; - case 24: -#line 53 "parse.y" -{ yygotominor.yy62 = yymsp[-2].minor.yy62 * yymsp[0].minor.yy62; yy_destructor(6,&yymsp[-1].minor); -} -#line 857 "parse.c" - break; - case 25: -#line 54 "parse.y" -{ yygotominor.yy62 = yymsp[-2].minor.yy62 / yymsp[0].minor.yy62; yy_destructor(7,&yymsp[-1].minor); -} -#line 863 "parse.c" - break; - case 26: -#line 55 "parse.y" -{ yygotominor.yy62 = yymsp[-2].minor.yy62 | yymsp[0].minor.yy62; yy_destructor(1,&yymsp[-1].minor); -} -#line 869 "parse.c" - break; - case 27: -#line 56 "parse.y" -{ yygotominor.yy62 = yymsp[-2].minor.yy62 & yymsp[0].minor.yy62; yy_destructor(3,&yymsp[-1].minor); -} -#line 875 "parse.c" - break; - case 28: -#line 57 "parse.y" -{ yygotominor.yy62 = yymsp[-2].minor.yy62 ^ yymsp[0].minor.yy62; yy_destructor(2,&yymsp[-1].minor); -} -#line 881 "parse.c" - break; - case 29: -#line 58 "parse.y" -{ yygotominor.yy62 = -yymsp[0].minor.yy62; yy_destructor(4,&yymsp[-1].minor); -} -#line 887 "parse.c" - break; - case 30: -#line 59 "parse.y" -{ yygotominor.yy62 = yymsp[-1].minor.yy62; yy_destructor(11,&yymsp[-2].minor); - yy_destructor(12,&yymsp[0].minor); -} -#line 894 "parse.c" - break; - case 33: -#line 65 "parse.y" -{ AddAction (yymsp[0].minor.yy0.string); } -#line 899 "parse.c" - break; - case 34: -#line 66 "parse.y" -{ AddAction (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); -} -#line 905 "parse.c" - break; - case 37: -#line 72 "parse.y" -{ AddHeight (yymsp[0].minor.yy62); } -#line 910 "parse.c" - break; - case 38: -#line 73 "parse.y" -{ AddHeight (yymsp[0].minor.yy62); yy_destructor(13,&yymsp[-1].minor); -} -#line 916 "parse.c" - break; - case 41: -#line 79 "parse.y" -{ AddActionMap (yymsp[0].minor.yy0.string); } -#line 921 "parse.c" - break; - case 42: -#line 80 "parse.y" -{ AddActionMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +{ + yy_destructor(13,&yymsp[-1].minor); } #line 927 "parse.c" break; - case 45: -#line 86 "parse.y" -{ AddCodeP (yymsp[0].minor.yy62); } + case 18: /* print_item ::= STRING */ +#line 47 "parse.y" +{ printf ("%s", yymsp[0].minor.yy0.string); } #line 932 "parse.c" break; - case 46: -#line 87 "parse.y" -{ AddCodeP (yymsp[0].minor.yy62); yy_destructor(13,&yymsp[-1].minor); -} -#line 938 "parse.c" + case 19: /* print_item ::= exp */ +#line 48 "parse.y" +{ printf ("%d", yymsp[0].minor.yy64); } +#line 937 "parse.c" break; - case 49: -#line 93 "parse.y" -{ AddSpriteName (yymsp[0].minor.yy0.string); } + case 20: /* print_item ::= ENDL */ +#line 49 "parse.y" +{ printf ("\n"); yy_destructor(15,&yymsp[0].minor); +} #line 943 "parse.c" break; - case 50: -#line 94 "parse.y" -{ AddSpriteName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); + case 21: /* exp ::= NUM */ +#line 52 "parse.y" +{ yygotominor.yy64 = yymsp[0].minor.yy0.val; } +#line 948 "parse.c" + break; + case 22: /* exp ::= exp PLUS exp */ +#line 53 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 + yymsp[0].minor.yy64; yy_destructor(5,&yymsp[-1].minor); } -#line 949 "parse.c" +#line 954 "parse.c" break; - case 55: -#line 103 "parse.y" -{ AddStateMap (yymsp[-4].minor.yy0.string, yymsp[-2].minor.yy62, yymsp[0].minor.yy62); yy_destructor(13,&yymsp[-3].minor); - yy_destructor(13,&yymsp[-1].minor); + case 23: /* exp ::= exp MINUS exp */ +#line 54 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 - yymsp[0].minor.yy64; yy_destructor(4,&yymsp[-1].minor); } -#line 956 "parse.c" +#line 960 "parse.c" break; - case 56: -#line 106 "parse.y" -{ yygotominor.yy62 = 0; yy_destructor(28,&yymsp[0].minor); + case 24: /* exp ::= exp MULTIPLY exp */ +#line 55 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 * yymsp[0].minor.yy64; yy_destructor(6,&yymsp[-1].minor); } -#line 962 "parse.c" +#line 966 "parse.c" break; - case 57: -#line 107 "parse.y" -{ yygotominor.yy62 = 1; yy_destructor(29,&yymsp[0].minor); + case 25: /* exp ::= exp DIVIDE exp */ +#line 56 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 / yymsp[0].minor.yy64; yy_destructor(7,&yymsp[-1].minor); } -#line 968 "parse.c" +#line 972 "parse.c" break; - case 58: -#line 108 "parse.y" -{ yygotominor.yy62 = 2; yy_destructor(30,&yymsp[0].minor); + case 26: /* exp ::= exp OR exp */ +#line 57 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 | yymsp[0].minor.yy64; yy_destructor(1,&yymsp[-1].minor); } -#line 974 "parse.c" +#line 978 "parse.c" break; - case 61: -#line 114 "parse.y" -{ AddSoundMap (yymsp[0].minor.yy0.string); } -#line 979 "parse.c" - break; - case 62: -#line 115 "parse.y" -{ AddSoundMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); + case 27: /* exp ::= exp AND exp */ +#line 58 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 & yymsp[0].minor.yy64; yy_destructor(3,&yymsp[-1].minor); } -#line 985 "parse.c" +#line 984 "parse.c" break; - case 65: -#line 121 "parse.y" -{ AddInfoName (yymsp[0].minor.yy0.string); } + case 28: /* exp ::= exp XOR exp */ +#line 59 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 ^ yymsp[0].minor.yy64; yy_destructor(2,&yymsp[-1].minor); +} #line 990 "parse.c" break; - case 66: -#line 122 "parse.y" -{ AddInfoName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); + case 29: /* exp ::= MINUS exp */ +#line 60 "parse.y" +{ yygotominor.yy64 = -yymsp[0].minor.yy64; yy_destructor(4,&yymsp[-1].minor); } #line 996 "parse.c" break; - case 71: -#line 131 "parse.y" -{ AddThingBits (yymsp[0].minor.yy0.string, yymsp[-4].minor.yy62, yymsp[-2].minor.yy62); yy_destructor(13,&yymsp[-3].minor); - yy_destructor(13,&yymsp[-1].minor); + case 30: /* exp ::= LPAREN exp RPAREN */ +#line 61 "parse.y" +{ yygotominor.yy64 = yymsp[-1].minor.yy64; yy_destructor(11,&yymsp[-2].minor); + yy_destructor(12,&yymsp[0].minor); } #line 1003 "parse.c" break; - case 76: -#line 140 "parse.y" -{ AddRenderStyle (yymsp[0].minor.yy0.string, yymsp[-2].minor.yy62); yy_destructor(13,&yymsp[-1].minor); + case 31: /* actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON */ + case 32: /*actions_def ::= Actions LBRACE error RBRACE SEMICOLON */ +#line 64 "parse.y" +{ + yy_destructor(17,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); } -#line 1009 "parse.c" +#line 1014 "parse.c" + break; + case 34: /* actions_list ::= SYM */ +#line 68 "parse.y" +{ AddAction (yymsp[0].minor.yy0.string); } +#line 1019 "parse.c" + break; + case 35: /* actions_list ::= actions_list COMMA SYM */ +#line 69 "parse.y" +{ AddAction (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +} +#line 1025 "parse.c" + break; + case 36: /* org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON */ + case 37: /*org_heights_def ::= OrgHeights LBRACE error RBRACE SEMICOLON */ +#line 72 "parse.y" +{ + yy_destructor(22,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1036 "parse.c" + break; + case 39: /* org_heights_list ::= exp */ +#line 76 "parse.y" +{ AddHeight (yymsp[0].minor.yy64); } +#line 1041 "parse.c" + break; + case 40: /* org_heights_list ::= org_heights_list COMMA exp */ +#line 77 "parse.y" +{ AddHeight (yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-1].minor); +} +#line 1047 "parse.c" + break; + case 41: /* action_list_def ::= ActionList LBRACE action_list_list RBRACE SEMICOLON */ + case 42: /*action_list_def ::= ActionList LBRACE error RBRACE SEMICOLON */ +#line 80 "parse.y" +{ + yy_destructor(23,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1058 "parse.c" + break; + case 44: /* action_list_list ::= SYM */ +#line 84 "parse.y" +{ AddActionMap (yymsp[0].minor.yy0.string); } +#line 1063 "parse.c" + break; + case 45: /* action_list_list ::= action_list_list COMMA SYM */ +#line 85 "parse.y" +{ AddActionMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +} +#line 1069 "parse.c" + break; + case 46: /* codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON */ + case 47: /*codep_conv_def ::= CodePConv LBRACE error RBRACE SEMICOLON */ +#line 88 "parse.y" +{ + yy_destructor(24,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1080 "parse.c" + break; + case 49: /* codep_conv_list ::= exp */ +#line 92 "parse.y" +{ AddCodeP (yymsp[0].minor.yy64); } +#line 1085 "parse.c" + break; + case 50: /* codep_conv_list ::= codep_conv_list COMMA exp */ +#line 93 "parse.y" +{ AddCodeP (yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-1].minor); +} +#line 1091 "parse.c" + break; + case 51: /* org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON */ + case 52: /*org_spr_names_def ::= OrgSprNames LBRACE error RBRACE SEMICOLON */ +#line 96 "parse.y" +{ + yy_destructor(25,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1102 "parse.c" + break; + case 54: /* org_spr_names_list ::= SYM */ +#line 100 "parse.y" +{ AddSpriteName (yymsp[0].minor.yy0.string); } +#line 1107 "parse.c" + break; + case 55: /* org_spr_names_list ::= org_spr_names_list COMMA SYM */ +#line 101 "parse.y" +{ AddSpriteName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +} +#line 1113 "parse.c" + break; + case 56: /* state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON */ + case 57: /*state_map_def ::= StateMap LBRACE error RBRACE SEMICOLON */ +#line 104 "parse.y" +{ + yy_destructor(26,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1124 "parse.c" + break; + case 61: /* state_map_entry ::= SYM COMMA state_type COMMA exp */ +#line 111 "parse.y" +{ AddStateMap (yymsp[-4].minor.yy0.string, yymsp[-2].minor.yy64, yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-3].minor); + yy_destructor(13,&yymsp[-1].minor); +} +#line 1131 "parse.c" + break; + case 62: /* state_type ::= FirstState */ +#line 114 "parse.y" +{ yygotominor.yy64 = 0; yy_destructor(27,&yymsp[0].minor); +} +#line 1137 "parse.c" + break; + case 63: /* state_type ::= SpawnState */ +#line 115 "parse.y" +{ yygotominor.yy64 = 1; yy_destructor(28,&yymsp[0].minor); +} +#line 1143 "parse.c" + break; + case 64: /* state_type ::= DeathState */ +#line 116 "parse.y" +{ yygotominor.yy64 = 2; yy_destructor(29,&yymsp[0].minor); +} +#line 1149 "parse.c" + break; + case 65: /* sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON */ + case 66: /*sound_map_def ::= SoundMap LBRACE error RBRACE SEMICOLON */ +#line 119 "parse.y" +{ + yy_destructor(30,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1160 "parse.c" + break; + case 68: /* sound_map_list ::= STRING */ +#line 123 "parse.y" +{ AddSoundMap (yymsp[0].minor.yy0.string); } +#line 1165 "parse.c" + break; + case 69: /* sound_map_list ::= sound_map_list COMMA STRING */ +#line 124 "parse.y" +{ AddSoundMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +} +#line 1171 "parse.c" + break; + case 70: /* info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON */ + case 71: /*info_names_def ::= InfoNames LBRACE error RBRACE SEMICOLON */ +#line 127 "parse.y" +{ + yy_destructor(31,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1182 "parse.c" + break; + case 73: /* info_names_list ::= SYM */ +#line 131 "parse.y" +{ AddInfoName (yymsp[0].minor.yy0.string); } +#line 1187 "parse.c" + break; + case 74: /* info_names_list ::= info_names_list COMMA SYM */ +#line 132 "parse.y" +{ AddInfoName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +} +#line 1193 "parse.c" + break; + case 75: /* thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON */ + case 76: /*thing_bits_def ::= ThingBits LBRACE error RBRACE SEMICOLON */ +#line 135 "parse.y" +{ + yy_destructor(32,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1204 "parse.c" + break; + case 80: /* thing_bits_entry ::= exp COMMA exp COMMA SYM */ +#line 142 "parse.y" +{ AddThingBits (yymsp[0].minor.yy0.string, yymsp[-4].minor.yy64, yymsp[-2].minor.yy64); yy_destructor(13,&yymsp[-3].minor); + yy_destructor(13,&yymsp[-1].minor); +} +#line 1211 "parse.c" + break; + case 81: /* render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON */ + case 82: /*render_styles_def ::= RenderStyles LBRACE error RBRACE SEMICOLON */ +#line 145 "parse.y" +{ + yy_destructor(33,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1222 "parse.c" + break; + case 86: /* render_styles_entry ::= exp COMMA SYM */ +#line 152 "parse.y" +{ AddRenderStyle (yymsp[0].minor.yy0.string, yymsp[-2].minor.yy64); yy_destructor(13,&yymsp[-1].minor); +} +#line 1228 "parse.c" break; }; yygoto = yyRuleInfo[yyruleno].lhs; @@ -1029,7 +1248,8 @@ static void yy_reduce( { yy_shift(yypParser,yyact,yygoto,&yygotominor); } - }else if( yyact == YYNSTATE + YYNRULE + 1 ){ + }else{ + assert( yyact == YYNSTATE + YYNRULE + 1 ); yy_accept(yypParser); } } @@ -1062,6 +1282,9 @@ static void yy_syntax_error( ){ ParseARG_FETCH; #define TOKEN (yyminor.yy0) +#line 8 "parse.y" + yyerror("Syntax error"); +#line 1288 "parse.c" ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ } @@ -1111,13 +1334,21 @@ void Parse( YYMINORTYPE yyminorunion; int yyact; /* The parser action. */ int yyendofinput; /* True if we are at the end of input */ +#ifdef YYERRORSYMBOL int yyerrorhit = 0; /* True if yymajor has invoked an error */ +#endif yyParser *yypParser; /* The parser */ /* (re)initialize the parser, if necessary */ yypParser = (yyParser*)yyp; if( yypParser->yyidx<0 ){ - /* if( yymajor==0 ) return; // not sure why this was here... */ +#if YYSTACKDEPTH<=0 + if( yypParser->yystksz <=0 ){ + memset(&yyminorunion, 0, sizeof(yyminorunion)); + yyStackOverflow(yypParser, &yyminorunion); + return; + } +#endif yypParser->yyidx = 0; yypParser->yyerrcnt = -1; yypParser->yystack[0].stateno = 0; @@ -1136,20 +1367,17 @@ void Parse( do{ yyact = yy_find_shift_action(yypParser,yymajor); if( yyactyyerrcnt--; - if( yyendofinput && yypParser->yyidx>=0 ){ - yymajor = 0; - }else{ - yymajor = YYNOCODE; - while( yypParser->yyidx>= 0 && (yyact = yy_find_shift_action(yypParser,YYNOCODE)) < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - } - } + yymajor = YYNOCODE; }else if( yyact < YYNSTATE + YYNRULE ){ yy_reduce(yypParser,yyact-YYNSTATE); - }else if( yyact == YY_ERROR_ACTION ){ + }else{ +#ifdef YYERRORSYMBOL int yymx; +#endif + assert( yyact == YY_ERROR_ACTION ); #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); @@ -1230,9 +1458,6 @@ void Parse( } yymajor = YYNOCODE; #endif - }else{ - yy_accept(yypParser); - yymajor = YYNOCODE; } }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); return; diff --git a/tools/dehsupp/parse.h b/tools/dehsupp/parse.h index c31082399a..932f082a5e 100644 --- a/tools/dehsupp/parse.h +++ b/tools/dehsupp/parse.h @@ -21,14 +21,13 @@ #define SYM 21 #define OrgHeights 22 #define ActionList 23 -#define RBARCE 24 -#define CodePConv 25 -#define OrgSprNames 26 -#define StateMap 27 -#define FirstState 28 -#define SpawnState 29 -#define DeathState 30 -#define SoundMap 31 -#define InfoNames 32 -#define ThingBits 33 -#define RenderStyles 34 +#define CodePConv 24 +#define OrgSprNames 25 +#define StateMap 26 +#define FirstState 27 +#define SpawnState 28 +#define DeathState 29 +#define SoundMap 30 +#define InfoNames 31 +#define ThingBits 32 +#define RenderStyles 33 diff --git a/tools/dehsupp/parse.y b/tools/dehsupp/parse.y index f12cacfa5b..4b6d4935c7 100644 --- a/tools/dehsupp/parse.y +++ b/tools/dehsupp/parse.y @@ -5,6 +5,8 @@ %token_type {struct Token} +%syntax_error { yyerror("Syntax error"); } + %token_destructor { if ($$.string) free($$.string); } %left OR. @@ -60,6 +62,7 @@ exp(A) ::= LPAREN exp(B) RPAREN. { A = B; } actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON. +actions_def ::= Actions LBRACE error RBRACE SEMICOLON. actions_list ::= . /* empty */ actions_list ::= SYM(A). { AddAction (A.string); } @@ -67,13 +70,15 @@ actions_list ::= actions_list COMMA SYM(A). { AddAction (A.string); } org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON. +org_heights_def ::= OrgHeights LBRACE error RBRACE SEMICOLON. org_heights_list ::= . /* empty */ org_heights_list ::= exp(A). { AddHeight (A); } org_heights_list ::= org_heights_list COMMA exp(A). { AddHeight (A); } -action_list_def ::= ActionList LBRACE action_list_list RBARCE SEMICOLON. +action_list_def ::= ActionList LBRACE action_list_list RBRACE SEMICOLON. +action_list_def ::= ActionList LBRACE error RBRACE SEMICOLON. action_list_list ::= . /* empty */ action_list_list ::= SYM(A). { AddActionMap (A.string); } @@ -81,6 +86,7 @@ action_list_list ::= action_list_list COMMA SYM(A). { AddActionMap (A.string); } codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON. +codep_conv_def ::= CodePConv LBRACE error RBRACE SEMICOLON. codep_conv_list ::= . /* empty */ codep_conv_list ::= exp(A). { AddCodeP (A); } @@ -88,6 +94,7 @@ codep_conv_list ::= codep_conv_list COMMA exp(A). { AddCodeP (A); } org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON. +org_spr_names_def ::= OrgSprNames LBRACE error RBRACE SEMICOLON. org_spr_names_list ::= . /* empty */ org_spr_names_list ::= SYM(A). { AddSpriteName (A.string); } @@ -95,6 +102,7 @@ org_spr_names_list ::= org_spr_names_list COMMA SYM(A). { AddSpriteName (A.strin state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON. +state_map_def ::= StateMap LBRACE error RBRACE SEMICOLON. state_map_list ::= . /* empty */ state_map_list ::= state_map_entry. @@ -109,6 +117,7 @@ state_type(A) ::= DeathState. { A = 2; } sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON. +sound_map_def ::= SoundMap LBRACE error RBRACE SEMICOLON. sound_map_list ::= . /* empty */ sound_map_list ::= STRING(A). { AddSoundMap (A.string); } @@ -116,6 +125,7 @@ sound_map_list ::= sound_map_list COMMA STRING(A). { AddSoundMap (A.string); } info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON. +info_names_def ::= InfoNames LBRACE error RBRACE SEMICOLON. info_names_list ::= . /* empty */ info_names_list ::= SYM(A). { AddInfoName (A.string); } @@ -123,6 +133,7 @@ info_names_list ::= info_names_list COMMA SYM(A). { AddInfoName (A.string); } thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON. +thing_bits_def ::= ThingBits LBRACE error RBRACE SEMICOLON. thing_bits_list ::= . /* empty */ thing_bits_list ::= thing_bits_entry. @@ -132,6 +143,7 @@ thing_bits_entry ::= exp(A) COMMA exp(B) COMMA SYM(C). { AddThingBits (C.string, render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON. +render_styles_def ::= RenderStyles LBRACE error RBRACE SEMICOLON. render_styles_list ::= . /* empty */ render_styles_list ::= render_styles_entry. diff --git a/tools/dehsupp/scanner.c b/tools/dehsupp/scanner.c index 89bf8b8e60..25a1fbfa36 100644 --- a/tools/dehsupp/scanner.c +++ b/tools/dehsupp/scanner.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.12.3 on Wed Jan 23 17:40:06 2008 */ +/* Generated by re2c 0.12.3 on Fri Jan 25 22:26:58 2008 */ #line 1 "scanner.re" #include #include @@ -66,17 +66,17 @@ std: unsigned int yyaccept = 0; if((YYLIMIT - YYCURSOR) < 13) YYFILL(13); -(13); yych = *YYCURSOR; switch(yych) { case 0x09: case 0x0B: case 0x0C: case ' ': goto yy22; - case 0x0A: goto yy46; + case 0x0A: goto yy48; case '"': goto yy20; case '&': goto yy28; case '(': goto yy36; + case ')': goto yy38; case '*': goto yy34; case '+': goto yy32; case ',': goto yy40; @@ -92,7 +92,7 @@ std: case '7': case '8': case '9': goto yy19; - case ';': goto yy44; + case ';': goto yy46; case 'A': goto yy7; case 'B': case 'E': @@ -149,92 +149,92 @@ std: case 'p': goto yy6; case '{': goto yy42; case '|': goto yy24; - case '}': goto yy38; - default: goto yy48; + case '}': goto yy44; + default: goto yy50; } yy2: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if(yych == '*') goto yy198; - if(yych == '/') goto yy196; + if(yych == '*') goto yy200; + if(yych == '/') goto yy198; yy3: #line 107 "scanner.re" { RET(DIVIDE); } #line 164 "scanner.c" yy4: ++YYCURSOR; - if((yych = *YYCURSOR) == 'n') goto yy192; - goto yy70; + if((yych = *YYCURSOR) == 'n') goto yy194; + goto yy72; yy5: #line 91 "scanner.re" { RET(SYM); } #line 172 "scanner.c" yy6: yych = *++YYCURSOR; - if(yych == 'r') goto yy187; - goto yy70; + if(yych == 'r') goto yy189; + goto yy72; yy7: yych = *++YYCURSOR; - if(yych == 'c') goto yy175; - goto yy70; + if(yych == 'c') goto yy177; + goto yy72; yy8: yych = *++YYCURSOR; - if(yych == 'r') goto yy156; - goto yy70; + if(yych == 'r') goto yy158; + goto yy72; yy9: yych = *++YYCURSOR; - if(yych == 'o') goto yy147; - goto yy70; + if(yych == 'o') goto yy149; + goto yy72; yy10: yych = *++YYCURSOR; if(yych <= 'p') { - if(yych <= 'n') goto yy70; - if(yych <= 'o') goto yy121; - goto yy122; + if(yych <= 'n') goto yy72; + if(yych <= 'o') goto yy123; + goto yy124; } else { - if(yych == 't') goto yy123; - goto yy70; + if(yych == 't') goto yy125; + goto yy72; } yy11: yych = *++YYCURSOR; - if(yych == 'n') goto yy112; - goto yy70; + if(yych == 'n') goto yy114; + goto yy72; yy12: yych = *++YYCURSOR; - if(yych == 'h') goto yy103; - goto yy70; + if(yych == 'h') goto yy105; + goto yy72; yy13: yych = *++YYCURSOR; - if(yych == 'e') goto yy93; - goto yy70; + if(yych == 'e') goto yy95; + goto yy72; yy14: yych = *++YYCURSOR; - if(yych == 'i') goto yy83; - goto yy70; + if(yych == 'i') goto yy85; + goto yy72; yy15: yych = *++YYCURSOR; - if(yych == 'e') goto yy71; - goto yy70; + if(yych == 'e') goto yy73; + goto yy72; yy16: yych = *++YYCURSOR; - goto yy70; + goto yy72; yy17: yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - if(yych == 'X') goto yy66; - if(yych == 'x') goto yy66; - goto yy65; + if(yych == 'X') goto yy68; + if(yych == 'x') goto yy68; + goto yy67; yy18: #line 94 "scanner.re" { RET(NUM); } #line 231 "scanner.c" yy19: yych = *++YYCURSOR; - goto yy63; + goto yy65; yy20: yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); - if(yych != 0x0A) goto yy52; + if(yych != 0x0A) goto yy54; yy21: #line 124 "scanner.re" { @@ -245,7 +245,7 @@ yy21: yy22: ++YYCURSOR; yych = *YYCURSOR; - goto yy50; + goto yy52; yy23: #line 99 "scanner.re" { goto std; } @@ -302,47 +302,52 @@ yy42: #line 303 "scanner.c" yy44: ++YYCURSOR; -#line 113 "scanner.re" - { RET(SEMICOLON); } +#line 112 "scanner.re" + { RET(RBRACE); } #line 308 "scanner.c" yy46: ++YYCURSOR; +#line 113 "scanner.re" + { RET(SEMICOLON); } +#line 313 "scanner.c" +yy48: + ++YYCURSOR; #line 117 "scanner.re" { if(cursor == s->eof) RET(EOI); s->pos = cursor; s->line++; goto std; } -#line 317 "scanner.c" -yy48: +#line 322 "scanner.c" +yy50: yych = *++YYCURSOR; goto yy21; -yy49: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; -yy50: - if(yych <= 0x0A) { - if(yych == 0x09) goto yy49; - goto yy23; - } else { - if(yych <= 0x0C) goto yy49; - if(yych == ' ') goto yy49; - goto yy23; - } yy51: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; yy52: - if(yych <= '!') { - if(yych != 0x0A) goto yy51; + if(yych <= 0x0A) { + if(yych == 0x09) goto yy51; + goto yy23; } else { - if(yych <= '"') goto yy55; - if(yych == '\\') goto yy54; - goto yy51; + if(yych <= 0x0C) goto yy51; + if(yych == ' ') goto yy51; + goto yy23; } yy53: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy54: + if(yych <= '!') { + if(yych != 0x0A) goto yy53; + } else { + if(yych <= '"') goto yy57; + if(yych == '\\') goto yy56; + goto yy53; + } +yy55: YYCURSOR = YYMARKER; if(yyaccept <= 1) { if(yyaccept <= 0) { @@ -353,120 +358,112 @@ yy53: } else { goto yy21; } -yy54: +yy56: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; if(yych <= 'b') { if(yych <= '7') { if(yych <= '&') { - if(yych == '"') goto yy51; - goto yy53; + if(yych == '"') goto yy53; + goto yy55; } else { - if(yych <= '\'') goto yy51; - if(yych <= '/') goto yy53; - goto yy58; + if(yych <= '\'') goto yy53; + if(yych <= '/') goto yy55; + goto yy60; } } else { if(yych <= '[') { - if(yych == '?') goto yy51; - goto yy53; + if(yych == '?') goto yy53; + goto yy55; } else { - if(yych <= '\\') goto yy51; - if(yych <= '`') goto yy53; - goto yy51; + if(yych <= '\\') goto yy53; + if(yych <= '`') goto yy55; + goto yy53; } } } else { if(yych <= 'r') { if(yych <= 'm') { - if(yych == 'f') goto yy51; - goto yy53; + if(yych == 'f') goto yy53; + goto yy55; } else { - if(yych <= 'n') goto yy51; - if(yych <= 'q') goto yy53; - goto yy51; + if(yych <= 'n') goto yy53; + if(yych <= 'q') goto yy55; + goto yy53; } } else { if(yych <= 'u') { - if(yych == 't') goto yy51; - goto yy53; + if(yych == 't') goto yy53; + goto yy55; } else { - if(yych <= 'v') goto yy51; - if(yych == 'x') goto yy57; - goto yy53; + if(yych <= 'v') goto yy53; + if(yych == 'x') goto yy59; + goto yy55; } } } -yy55: +yy57: ++YYCURSOR; #line 97 "scanner.re" { RET(STRING); } -#line 406 "scanner.c" -yy57: +#line 411 "scanner.c" +yy59: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; if(yych <= '@') { - if(yych <= '/') goto yy53; - if(yych <= '9') goto yy60; - goto yy53; - } else { - if(yych <= 'F') goto yy60; - if(yych <= '`') goto yy53; - if(yych <= 'f') goto yy60; - goto yy53; - } -yy58: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - if(yych <= '"') { - if(yych == 0x0A) goto yy53; - if(yych <= '!') goto yy51; + if(yych <= '/') goto yy55; + if(yych <= '9') goto yy62; goto yy55; } else { - if(yych <= '7') { - if(yych <= '/') goto yy51; - goto yy58; - } else { - if(yych == '\\') goto yy54; - goto yy51; - } + if(yych <= 'F') goto yy62; + if(yych <= '`') goto yy55; + if(yych <= 'f') goto yy62; + goto yy55; } yy60: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if(yych <= '9') { - if(yych <= '!') { - if(yych == 0x0A) goto yy53; - goto yy51; - } else { - if(yych <= '"') goto yy55; - if(yych <= '/') goto yy51; - goto yy60; - } + if(yych <= '"') { + if(yych == 0x0A) goto yy55; + if(yych <= '!') goto yy53; + goto yy57; } else { - if(yych <= '[') { - if(yych <= '@') goto yy51; - if(yych <= 'F') goto yy60; - goto yy51; + if(yych <= '7') { + if(yych <= '/') goto yy53; + goto yy60; } else { - if(yych <= '\\') goto yy54; - if(yych <= '`') goto yy51; - if(yych <= 'f') goto yy60; - goto yy51; + if(yych == '\\') goto yy56; + goto yy53; } } yy62: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy63: - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy62; - goto yy18; + if(yych <= '9') { + if(yych <= '!') { + if(yych == 0x0A) goto yy55; + goto yy53; + } else { + if(yych <= '"') goto yy57; + if(yych <= '/') goto yy53; + goto yy62; + } + } else { + if(yych <= '[') { + if(yych <= '@') goto yy53; + if(yych <= 'F') goto yy62; + goto yy53; + } else { + if(yych <= '\\') goto yy56; + if(yych <= '`') goto yy53; + if(yych <= 'f') goto yy62; + goto yy53; + } + } yy64: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); @@ -476,531 +473,539 @@ yy65: if(yych <= '9') goto yy64; goto yy18; yy66: - yych = *++YYCURSOR; - if(yych <= '@') { - if(yych <= '/') goto yy53; - if(yych >= ':') goto yy53; - } else { - if(yych <= 'F') goto yy67; - if(yych <= '`') goto yy53; - if(yych >= 'g') goto yy53; - } -yy67: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; +yy67: + if(yych <= '/') goto yy18; + if(yych <= '9') goto yy66; + goto yy18; +yy68: + yych = *++YYCURSOR; if(yych <= '@') { - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy67; - goto yy18; + if(yych <= '/') goto yy55; + if(yych >= ':') goto yy55; } else { - if(yych <= 'F') goto yy67; - if(yych <= '`') goto yy18; - if(yych <= 'f') goto yy67; - goto yy18; + if(yych <= 'F') goto yy69; + if(yych <= '`') goto yy55; + if(yych >= 'g') goto yy55; } yy69: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; -yy70: - if(yych <= 'Z') { - if(yych <= '/') goto yy5; + if(yych <= '@') { + if(yych <= '/') goto yy18; if(yych <= '9') goto yy69; - if(yych <= '@') goto yy5; - goto yy69; + goto yy18; } else { - if(yych <= '_') { - if(yych <= '^') goto yy5; - goto yy69; - } else { - if(yych <= '`') goto yy5; - if(yych <= 'z') goto yy69; - goto yy5; - } + if(yych <= 'F') goto yy69; + if(yych <= '`') goto yy18; + if(yych <= 'f') goto yy69; + goto yy18; } yy71: - yych = *++YYCURSOR; - if(yych != 'n') goto yy70; - yych = *++YYCURSOR; - if(yych != 'd') goto yy70; - yych = *++YYCURSOR; - if(yych != 'e') goto yy70; - yych = *++YYCURSOR; - if(yych != 'r') goto yy70; - yych = *++YYCURSOR; - if(yych != 'S') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'y') goto yy70; - yych = *++YYCURSOR; - if(yych != 'l') goto yy70; - yych = *++YYCURSOR; - if(yych != 'e') goto yy70; - yych = *++YYCURSOR; - if(yych != 's') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy82; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy82; - if(yych <= 'z') goto yy69; - } - } -yy82: -#line 89 "scanner.re" - { RET(RenderStyles); } -#line 560 "scanner.c" -yy83: - yych = *++YYCURSOR; - if(yych != 'r') goto yy70; - yych = *++YYCURSOR; - if(yych != 's') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'S') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'a') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'e') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy92; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy92; - if(yych <= 'z') goto yy69; - } - } -yy92: -#line 88 "scanner.re" - { RET(FirstState); } -#line 594 "scanner.c" -yy93: - yych = *++YYCURSOR; - if(yych != 'a') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'h') goto yy70; - yych = *++YYCURSOR; - if(yych != 'S') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'a') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'e') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy102; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy102; - if(yych <= 'z') goto yy69; - } - } -yy102: -#line 86 "scanner.re" - { RET(DeathState); } -#line 628 "scanner.c" -yy103: - yych = *++YYCURSOR; - if(yych != 'i') goto yy70; - yych = *++YYCURSOR; - if(yych != 'n') goto yy70; - yych = *++YYCURSOR; - if(yych != 'g') goto yy70; - yych = *++YYCURSOR; - if(yych != 'B') goto yy70; - yych = *++YYCURSOR; - if(yych != 'i') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 's') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy111; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy111; - if(yych <= 'z') goto yy69; - } - } -yy111: -#line 85 "scanner.re" - { RET(ThingBits); } -#line 660 "scanner.c" -yy112: - yych = *++YYCURSOR; - if(yych != 'f') goto yy70; - yych = *++YYCURSOR; - if(yych != 'o') goto yy70; - yych = *++YYCURSOR; - if(yych != 'N') goto yy70; - yych = *++YYCURSOR; - if(yych != 'a') goto yy70; - yych = *++YYCURSOR; - if(yych != 'm') goto yy70; - yych = *++YYCURSOR; - if(yych != 'e') goto yy70; - yych = *++YYCURSOR; - if(yych != 's') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy120; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy120; - if(yych <= 'z') goto yy69; - } - } -yy120: -#line 84 "scanner.re" - { RET(InfoNames); } -#line 692 "scanner.c" -yy121: - yych = *++YYCURSOR; - if(yych == 'u') goto yy140; - goto yy70; -yy122: - yych = *++YYCURSOR; - if(yych == 'a') goto yy131; - goto yy70; -yy123: - yych = *++YYCURSOR; - if(yych != 'a') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'e') goto yy70; - yych = *++YYCURSOR; - if(yych != 'M') goto yy70; - yych = *++YYCURSOR; - if(yych != 'a') goto yy70; - yych = *++YYCURSOR; - if(yych != 'p') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy130; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy130; - if(yych <= 'z') goto yy69; - } - } -yy130: -#line 82 "scanner.re" - { RET(StateMap); } -#line 730 "scanner.c" -yy131: - yych = *++YYCURSOR; - if(yych != 'w') goto yy70; - yych = *++YYCURSOR; - if(yych != 'n') goto yy70; - yych = *++YYCURSOR; - if(yych != 'S') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'a') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'e') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy139; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy139; - if(yych <= 'z') goto yy69; - } - } -yy139: -#line 87 "scanner.re" - { RET(SpawnState); } -#line 762 "scanner.c" -yy140: - yych = *++YYCURSOR; - if(yych != 'n') goto yy70; - yych = *++YYCURSOR; - if(yych != 'd') goto yy70; - yych = *++YYCURSOR; - if(yych != 'M') goto yy70; - yych = *++YYCURSOR; - if(yych != 'a') goto yy70; - yych = *++YYCURSOR; - if(yych != 'p') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy146; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy146; - if(yych <= 'z') goto yy69; - } - } -yy146: -#line 83 "scanner.re" - { RET(SoundMap); } -#line 790 "scanner.c" -yy147: - yych = *++YYCURSOR; - if(yych != 'd') goto yy70; - yych = *++YYCURSOR; - if(yych != 'e') goto yy70; - yych = *++YYCURSOR; - if(yych != 'P') goto yy70; - yych = *++YYCURSOR; - if(yych != 'C') goto yy70; - yych = *++YYCURSOR; - if(yych != 'o') goto yy70; - yych = *++YYCURSOR; - if(yych != 'n') goto yy70; - yych = *++YYCURSOR; - if(yych != 'v') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy155; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy155; - if(yych <= 'z') goto yy69; - } - } -yy155: -#line 80 "scanner.re" - { RET(CodePConv); } -#line 822 "scanner.c" -yy156: - yych = *++YYCURSOR; - if(yych != 'g') goto yy70; - yych = *++YYCURSOR; - if(yych == 'H') goto yy158; - if(yych == 'S') goto yy159; - goto yy70; -yy158: - yych = *++YYCURSOR; - if(yych == 'e') goto yy168; - goto yy70; -yy159: - yych = *++YYCURSOR; - if(yych != 'p') goto yy70; - yych = *++YYCURSOR; - if(yych != 'r') goto yy70; - yych = *++YYCURSOR; - if(yych != 'N') goto yy70; - yych = *++YYCURSOR; - if(yych != 'a') goto yy70; - yych = *++YYCURSOR; - if(yych != 'm') goto yy70; - yych = *++YYCURSOR; - if(yych != 'e') goto yy70; - yych = *++YYCURSOR; - if(yych != 's') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy167; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy167; - if(yych <= 'z') goto yy69; - } - } -yy167: -#line 81 "scanner.re" - { RET(OrgSprNames); } -#line 865 "scanner.c" -yy168: - yych = *++YYCURSOR; - if(yych != 'i') goto yy70; - yych = *++YYCURSOR; - if(yych != 'g') goto yy70; - yych = *++YYCURSOR; - if(yych != 'h') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 's') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy174; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy174; - if(yych <= 'z') goto yy69; - } - } -yy174: -#line 78 "scanner.re" - { RET(OrgHeights); } -#line 893 "scanner.c" -yy175: - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - yych = *++YYCURSOR; - if(yych != 'i') goto yy70; - yych = *++YYCURSOR; - if(yych != 'o') goto yy70; - yych = *++YYCURSOR; - if(yych != 'n') goto yy70; - yych = *++YYCURSOR; - if(yych == 'L') goto yy182; - if(yych != 's') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy181; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy181; - if(yych <= 'z') goto yy69; - } - } -yy181: -#line 77 "scanner.re" - { RET(Actions); } -#line 922 "scanner.c" -yy182: - yych = *++YYCURSOR; - if(yych != 'i') goto yy70; - yych = *++YYCURSOR; - if(yych != 's') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy186; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy186; - if(yych <= 'z') goto yy69; - } - } -yy186: -#line 79 "scanner.re" - { RET(ActionList); } -#line 946 "scanner.c" -yy187: - yych = *++YYCURSOR; - if(yych != 'i') goto yy70; - yych = *++YYCURSOR; - if(yych != 'n') goto yy70; - yych = *++YYCURSOR; - if(yych != 't') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy191; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy191; - if(yych <= 'z') goto yy69; - } - } -yy191: -#line 76 "scanner.re" - { RET(PRINT); } -#line 970 "scanner.c" -yy192: - yych = *++YYCURSOR; - if(yych != 'd') goto yy70; - yych = *++YYCURSOR; - if(yych != 'l') goto yy70; - ++YYCURSOR; - if((yych = *YYCURSOR) <= 'Z') { - if(yych <= '/') goto yy195; - if(yych <= '9') goto yy69; - if(yych >= 'A') goto yy69; - } else { - if(yych <= '_') { - if(yych >= '_') goto yy69; - } else { - if(yych <= '`') goto yy195; - if(yych <= 'z') goto yy69; - } - } -yy195: -#line 75 "scanner.re" - { RET(ENDL); } -#line 992 "scanner.c" -yy196: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - if(yych == 0x0A) goto yy200; - goto yy196; +yy72: + if(yych <= 'Z') { + if(yych <= '/') goto yy5; + if(yych <= '9') goto yy71; + if(yych <= '@') goto yy5; + goto yy71; + } else { + if(yych <= '_') { + if(yych <= '^') goto yy5; + goto yy71; + } else { + if(yych <= '`') goto yy5; + if(yych <= 'z') goto yy71; + goto yy5; + } + } +yy73: + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 'd') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 'r') goto yy72; + yych = *++YYCURSOR; + if(yych != 'S') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'y') goto yy72; + yych = *++YYCURSOR; + if(yych != 'l') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy84; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy84; + if(yych <= 'z') goto yy71; + } + } +yy84: +#line 89 "scanner.re" + { RET(RenderStyles); } +#line 565 "scanner.c" +yy85: + yych = *++YYCURSOR; + if(yych != 'r') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'S') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy94; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy94; + if(yych <= 'z') goto yy71; + } + } +yy94: +#line 88 "scanner.re" + { RET(FirstState); } +#line 599 "scanner.c" +yy95: + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'h') goto yy72; + yych = *++YYCURSOR; + if(yych != 'S') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy104; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy104; + if(yych <= 'z') goto yy71; + } + } +yy104: +#line 86 "scanner.re" + { RET(DeathState); } +#line 633 "scanner.c" +yy105: + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 'g') goto yy72; + yych = *++YYCURSOR; + if(yych != 'B') goto yy72; + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy113; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy113; + if(yych <= 'z') goto yy71; + } + } +yy113: +#line 85 "scanner.re" + { RET(ThingBits); } +#line 665 "scanner.c" +yy114: + yych = *++YYCURSOR; + if(yych != 'f') goto yy72; + yych = *++YYCURSOR; + if(yych != 'o') goto yy72; + yych = *++YYCURSOR; + if(yych != 'N') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 'm') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy122; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy122; + if(yych <= 'z') goto yy71; + } + } +yy122: +#line 84 "scanner.re" + { RET(InfoNames); } +#line 697 "scanner.c" +yy123: + yych = *++YYCURSOR; + if(yych == 'u') goto yy142; + goto yy72; +yy124: + yych = *++YYCURSOR; + if(yych == 'a') goto yy133; + goto yy72; +yy125: + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 'M') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 'p') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy132; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy132; + if(yych <= 'z') goto yy71; + } + } +yy132: +#line 82 "scanner.re" + { RET(StateMap); } +#line 735 "scanner.c" +yy133: + yych = *++YYCURSOR; + if(yych != 'w') goto yy72; + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 'S') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy141; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy141; + if(yych <= 'z') goto yy71; + } + } +yy141: +#line 87 "scanner.re" + { RET(SpawnState); } +#line 767 "scanner.c" +yy142: + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 'd') goto yy72; + yych = *++YYCURSOR; + if(yych != 'M') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 'p') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy148; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy148; + if(yych <= 'z') goto yy71; + } + } +yy148: +#line 83 "scanner.re" + { RET(SoundMap); } +#line 795 "scanner.c" +yy149: + yych = *++YYCURSOR; + if(yych != 'd') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 'P') goto yy72; + yych = *++YYCURSOR; + if(yych != 'C') goto yy72; + yych = *++YYCURSOR; + if(yych != 'o') goto yy72; + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 'v') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy157; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy157; + if(yych <= 'z') goto yy71; + } + } +yy157: +#line 80 "scanner.re" + { RET(CodePConv); } +#line 827 "scanner.c" +yy158: + yych = *++YYCURSOR; + if(yych != 'g') goto yy72; + yych = *++YYCURSOR; + if(yych == 'H') goto yy160; + if(yych == 'S') goto yy161; + goto yy72; +yy160: + yych = *++YYCURSOR; + if(yych == 'e') goto yy170; + goto yy72; +yy161: + yych = *++YYCURSOR; + if(yych != 'p') goto yy72; + yych = *++YYCURSOR; + if(yych != 'r') goto yy72; + yych = *++YYCURSOR; + if(yych != 'N') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 'm') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy169; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy169; + if(yych <= 'z') goto yy71; + } + } +yy169: +#line 81 "scanner.re" + { RET(OrgSprNames); } +#line 870 "scanner.c" +yy170: + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 'g') goto yy72; + yych = *++YYCURSOR; + if(yych != 'h') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy176; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy176; + if(yych <= 'z') goto yy71; + } + } +yy176: +#line 78 "scanner.re" + { RET(OrgHeights); } +#line 898 "scanner.c" +yy177: + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 'o') goto yy72; + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych == 'L') goto yy184; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy183; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy183; + if(yych <= 'z') goto yy71; + } + } +yy183: +#line 77 "scanner.re" + { RET(Actions); } +#line 927 "scanner.c" +yy184: + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy188; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy188; + if(yych <= 'z') goto yy71; + } + } +yy188: +#line 79 "scanner.re" + { RET(ActionList); } +#line 951 "scanner.c" +yy189: + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy193; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy193; + if(yych <= 'z') goto yy71; + } + } +yy193: +#line 76 "scanner.re" + { RET(PRINT); } +#line 975 "scanner.c" +yy194: + yych = *++YYCURSOR; + if(yych != 'd') goto yy72; + yych = *++YYCURSOR; + if(yych != 'l') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy197; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy197; + if(yych <= 'z') goto yy71; + } + } +yy197: +#line 75 "scanner.re" + { RET(ENDL); } +#line 997 "scanner.c" yy198: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy202; + goto yy198; +yy200: + ++YYCURSOR; #line 67 "scanner.re" { goto comment; } -#line 1003 "scanner.c" -yy200: +#line 1008 "scanner.c" +yy202: ++YYCURSOR; #line 69 "scanner.re" { @@ -1008,28 +1013,27 @@ yy200: s->tok = s->pos = cursor; s->line++; goto std; } -#line 1012 "scanner.c" +#line 1017 "scanner.c" } #line 128 "scanner.re" comment: -#line 1019 "scanner.c" +#line 1024 "scanner.c" { YYCTYPE yych; if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); -(2); yych = *YYCURSOR; - if(yych == 0x0A) goto yy206; - if(yych != '*') goto yy208; + if(yych == 0x0A) goto yy208; + if(yych != '*') goto yy210; ++YYCURSOR; - if((yych = *YYCURSOR) == '/') goto yy209; -yy205: + if((yych = *YYCURSOR) == '/') goto yy211; +yy207: #line 139 "scanner.re" { goto comment; } -#line 1032 "scanner.c" -yy206: +#line 1036 "scanner.c" +yy208: ++YYCURSOR; #line 134 "scanner.re" { @@ -1037,15 +1041,15 @@ yy206: s->tok = s->pos = cursor; s->line++; goto comment; } -#line 1041 "scanner.c" -yy208: +#line 1045 "scanner.c" +yy210: yych = *++YYCURSOR; - goto yy205; -yy209: + goto yy207; +yy211: ++YYCURSOR; #line 132 "scanner.re" { goto std; } -#line 1049 "scanner.c" +#line 1053 "scanner.c" } #line 140 "scanner.re" diff --git a/tools/dehsupp/scanner.re b/tools/dehsupp/scanner.re index 20baccb943..828e2ee58b 100644 --- a/tools/dehsupp/scanner.re +++ b/tools/dehsupp/scanner.re @@ -106,7 +106,7 @@ ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+); "*" { RET(MULTIPLY); } "/" { RET(DIVIDE); } "(" { RET(LPAREN); } - "}" { RET(RPAREN); } + ")" { RET(RPAREN); } "," { RET(COMMA); } "{" { RET(LBRACE); } "}" { RET(RBRACE); } diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 4916dbc9d2..100887930d 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -15,6 +15,7 @@ #include #include #include +#include #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) @@ -22,6 +23,12 @@ # endif #endif +#ifdef __WIN32__ +extern int access(); +#else +#include +#endif + /* #define PRIVATE static */ #define PRIVATE @@ -31,19 +38,11 @@ #define MAXRHS 1000 #endif -void *msort(void *list, void *next, int (*cmp)()); +static void *msort(void *list, void *next, int (*cmp)()); /******** From the file "action.h" *************************************/ -struct action *Action_new(); -struct action *Action_sort(); - -/********* From the file "assert.h" ************************************/ -void myassert(); -#ifndef NDEBUG -# define assert(X) if(!(X))myassert(__FILE__,__LINE__) -#else -# define assert(X) -#endif +static struct action *Action_new(void); +static struct action *Action_sort(struct action *); /********** From the file "build.h" ************************************/ void FindRulePrecedences(); @@ -114,7 +113,7 @@ int SetUnion(/* char *A,char *B */); /* A <- A U B, thru element N */ ** Principal data structures for the LEMON parser generator. */ -typedef enum {B_FALSE=0, B_TRUE} Boolean; +typedef enum {LEMON_FALSE=0, LEMON_TRUE} Boolean; /* Symbols (terminals and nonterminals) of the grammar are stored ** in the following: */ @@ -137,6 +136,7 @@ struct symbol { } assoc; /* Associativity if predecence is defined */ char *firstset; /* First-set for all rules of this symbol */ Boolean lambda; /* True if NT and can generate an empty string */ + int useCnt; /* Number of times used */ char *destructor; /* Code which executes whenever this symbol is ** popped from the stack during error processing */ int destructorln; /* Line number of destructor code */ @@ -155,6 +155,7 @@ struct symbol { struct rule { struct symbol *lhs; /* Left-hand side of the rule */ char *lhsalias; /* Alias for the LHS (NULL if none) */ + int lhsStart; /* True if left-hand side is the start symbol */ int ruleline; /* Line number for the rule */ int nrhs; /* Number of RHS symbols */ struct symbol **rhs; /* The RHS symbols */ @@ -196,7 +197,9 @@ struct action { ACCEPT, REDUCE, ERROR, - CONFLICT, /* Was a reduce, but part of a conflict */ + SSCONFLICT, /* A shift/shift conflict */ + SRCONFLICT, /* Was a reduce, but part of a conflict */ + RRCONFLICT, /* Was a reduce, but part of a conflict */ SH_RESOLVED, /* Was a shift. Precedence resolved conflict */ RD_RESOLVED, /* Was reduce. Precedence resolved conflict */ NOT_USED /* Deleted by compression */ @@ -335,14 +338,14 @@ void Configtable_clear(/* int(*)(struct config *) */); */ /* Allocate a new parser action */ -struct action *Action_new(){ +static struct action *Action_new(void){ static struct action *freelist = 0; struct action *new; if( freelist==0 ){ int i; int amt = 100; - freelist = (struct action *)malloc( sizeof(struct action)*amt ); + freelist = (struct action *)calloc(amt, sizeof(struct action)); if( freelist==0 ){ fprintf(stderr,"Unable to allocate memory for a new parser action."); exit(1); @@ -355,23 +358,27 @@ struct action *Action_new(){ return new; } -/* Compare two actions */ +/* Compare two actions for sorting purposes. Return negative, zero, or +** positive if the first action is less than, equal to, or greater than +** the first +*/ static int actioncmp(ap1,ap2) struct action *ap1; struct action *ap2; { int rc; rc = ap1->sp->index - ap2->sp->index; - if( rc==0 ) rc = (int)ap1->type - (int)ap2->type; if( rc==0 ){ + rc = (int)ap1->type - (int)ap2->type; + } + if( rc==0 && ap1->type==REDUCE ){ rc = ap1->x.rp->index - ap2->x.rp->index; } return rc; } /* Sort parser actions */ -struct action *Action_sort(ap) -struct action *ap; +static struct action *Action_sort(struct action *ap) { ap = (struct action *)msort(ap,&ap->next,actioncmp); return ap; @@ -438,7 +445,7 @@ void acttab_free(acttab *p){ /* Allocate a new acttab structure */ acttab *acttab_alloc(void){ - acttab *p = malloc( sizeof(*p) ); + acttab *p = calloc( 1, sizeof(*p) ); if( p==0 ){ fprintf(stderr,"Unable to allocate memory for a new acttab."); exit(1); @@ -559,17 +566,6 @@ int acttab_insert(acttab *p){ return i - p->mnLookahead; } -/********************** From the file "assert.c" ****************************/ -/* -** A more efficient way of handling assertions. -*/ -void myassert(file,line) -char *file; -int line; -{ - fprintf(stderr,"Assertion failed on line %d of file \"%s\"\n",line,file); - exit(1); -} /********************** From the file "build.c" *****************************/ /* ** Routines to construction the finite state machine for the LEMON @@ -623,7 +619,7 @@ struct lemon *lemp; int progress; for(i=0; insymbol; i++){ - lemp->symbols[i]->lambda = B_FALSE; + lemp->symbols[i]->lambda = LEMON_FALSE; } for(i=lemp->nterminal; insymbol; i++){ lemp->symbols[i]->firstset = SetNew(); @@ -636,10 +632,10 @@ struct lemon *lemp; if( rp->lhs->lambda ) continue; for(i=0; inrhs; i++){ struct symbol *sp = rp->rhs[i]; - if( sp->type!=TERMINAL || sp->lambda==B_FALSE ) break; + if( sp->type!=TERMINAL || sp->lambda==LEMON_FALSE ) break; } if( i==rp->nrhs ){ - rp->lhs->lambda = B_TRUE; + rp->lhs->lambda = LEMON_TRUE; progress = 1; } } @@ -662,10 +658,10 @@ struct lemon *lemp; } break; }else if( s1==s2 ){ - if( s1->lambda==B_FALSE ) break; + if( s1->lambda==LEMON_FALSE ) break; }else{ progress += SetUnion(s1->firstset,s2->firstset); - if( s2->lambda==B_FALSE ) break; + if( s2->lambda==LEMON_FALSE ) break; } } } @@ -722,6 +718,7 @@ does not work properly.",sp->name); ** left-hand side */ for(rp=sp->rule; rp; rp=rp->nextlhs){ struct config *newcfp; + rp->lhsStart = 1; newcfp = Configlist_addbasis(rp,0); SetAdd(newcfp->fws,0); } @@ -973,7 +970,7 @@ struct lemon *lemp; struct action *ap, *nap; struct state *stp; stp = lemp->sorted[i]; - assert( stp->ap ); + /* assert( stp->ap ); */ stp->ap = Action_sort(stp->ap); for(ap=stp->ap; ap && ap->next; ap=ap->next){ for(nap=ap->next; nap && nap->sp==ap->sp; nap=nap->next){ @@ -985,11 +982,11 @@ struct lemon *lemp; } /* Report an error for each rule that can never be reduced. */ - for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = B_FALSE; + for(rp=lemp->rule; rp; rp=rp->next) rp->canReduce = LEMON_FALSE; for(i=0; instate; i++){ struct action *ap; for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ - if( ap->type==REDUCE ) ap->x.rp->canReduce = B_TRUE; + if( ap->type==REDUCE ) ap->x.rp->canReduce = LEMON_TRUE; } } for(rp=lemp->rule; rp; rp=rp->next){ @@ -1021,7 +1018,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */ int errcnt = 0; assert( apx->sp==apy->sp ); /* Otherwise there would be no conflict */ if( apx->type==SHIFT && apy->type==SHIFT ){ - apy->type = CONFLICT; + apy->type = SSCONFLICT; errcnt++; } if( apx->type==SHIFT && apy->type==REDUCE ){ @@ -1029,7 +1026,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */ spy = apy->x.rp->precsym; if( spy==0 || spx->prec<0 || spy->prec<0 ){ /* Not enough precedence information. */ - apy->type = CONFLICT; + apy->type = SRCONFLICT; errcnt++; }else if( spx->prec>spy->prec ){ /* Lower precedence wins */ apy->type = RD_RESOLVED; @@ -1041,7 +1038,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */ apx->type = SH_RESOLVED; }else{ assert( spx->prec==spy->prec && spx->assoc==NONE ); - apy->type = CONFLICT; + apy->type = SRCONFLICT; errcnt++; } }else if( apx->type==REDUCE && apy->type==REDUCE ){ @@ -1049,7 +1046,7 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */ spy = apy->x.rp->precsym; if( spx==0 || spy==0 || spx->prec<0 || spy->prec<0 || spx->prec==spy->prec ){ - apy->type = CONFLICT; + apy->type = RRCONFLICT; errcnt++; }else if( spx->prec>spy->prec ){ apy->type = RD_RESOLVED; @@ -1060,10 +1057,14 @@ struct symbol *errsym; /* The error symbol (if defined. NULL otherwise) */ assert( apx->type==SH_RESOLVED || apx->type==RD_RESOLVED || - apx->type==CONFLICT || + apx->type==SSCONFLICT || + apx->type==SRCONFLICT || + apx->type==RRCONFLICT || apy->type==SH_RESOLVED || apy->type==RD_RESOLVED || - apy->type==CONFLICT + apy->type==SSCONFLICT || + apy->type==SRCONFLICT || + apy->type==RRCONFLICT ); /* The REDUCE/SHIFT case cannot happen because SHIFTs come before ** REDUCEs on the list. If we reach this point it must be because @@ -1089,7 +1090,7 @@ PRIVATE struct config *newconfig(){ if( freelist==0 ){ int i; int amt = 3; - freelist = (struct config *)malloc( sizeof(struct config)*amt ); + freelist = (struct config *)calloc( amt, sizeof(struct config) ); if( freelist==0 ){ fprintf(stderr,"Unable to allocate memory for a new configuration."); exit(1); @@ -1223,7 +1224,7 @@ struct lemon *lemp; break; }else{ SetUnion(newcfp->fws,xsp->firstset); - if( xsp->lambda==B_FALSE ) break; + if( xsp->lambda==LEMON_FALSE ) break; } } if( i==rp->nrhs ) Plink_add(&cfp->fplp,newcfp); @@ -1452,6 +1453,7 @@ char **argv; lem.basisflag = basisflag; Symbol_new("$"); lem.errsym = Symbol_new("error"); + lem.errsym->useCnt = 0; /* Parse the input file */ Parse(&lem); @@ -1477,7 +1479,7 @@ char **argv; Reprint(&lem); }else{ /* Initialize the size for all follow and first sets */ - SetSize(lem.nterminal); + SetSize(lem.nterminal+1); /* Find the precedence for every production rule (that has one) */ FindRulePrecedences(&lem); @@ -1623,7 +1625,7 @@ static void *merge(void *a,void *b,int (*cmp)(),size_t offset) ** The "next" pointers for elements in list are changed. */ #define LISTSIZE 30 -void *msort(void *list,void *next,int (*cmp)()) +static void *msort(void *list,void *next,int (*cmp)()) { size_t offset; char *ep; @@ -2108,8 +2110,8 @@ to follow the previous rule."); case IN_RHS: if( x[0]=='.' ){ struct rule *rp; - rp = (struct rule *)malloc( sizeof(struct rule) + - sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs ); + rp = (struct rule *)calloc( sizeof(struct rule) + + sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1); if( rp==0 ){ ErrorMsg(psp->filename,psp->tokenlineno, "Can't allocate enough memory for this rule."); @@ -2145,7 +2147,7 @@ to follow the previous rule."); }else if( isalpha(x[0]) ){ if( psp->nrhs>=MAXRHS ){ ErrorMsg(psp->filename,psp->tokenlineno, - "Too many symbols on RHS or rule beginning at \"%s\".", + "Too many symbols on RHS of rule beginning at \"%s\".", x); psp->errorcnt++; psp->state = RESYNC_AFTER_RULE_ERROR; @@ -2158,11 +2160,10 @@ to follow the previous rule."); struct symbol *msp = psp->rhs[psp->nrhs-1]; if( msp->type!=MULTITERMINAL ){ struct symbol *origsp = msp; - msp = malloc(sizeof(*msp)); - memset(msp, 0, sizeof(*msp)); + msp = calloc(1,sizeof(*msp)); msp->type = MULTITERMINAL; msp->nsubsym = 1; - msp->subsym = malloc(sizeof(struct symbol*)); + msp->subsym = calloc(1,sizeof(struct symbol*)); msp->subsym[0] = origsp; msp->name = origsp->name; psp->rhs[psp->nrhs-1] = msp; @@ -2407,7 +2408,7 @@ to follow the previous rule."); static void preprocess_input(char *z){ int i, j, k, n; int exclude = 0; - int start = 1; + int start = 0; int lineno = 1; int start_lineno = 1; for(i=0; z[i]; i++){ @@ -2484,7 +2485,7 @@ struct lemon *gp; char *cp, *nextcp; int startline = 0; - memset(&ps, 0, sizeof ps); + memset(&ps, '\0', sizeof(ps)); ps.gp = gp; ps.filename = gp->filename; ps.errorcnt = 0; @@ -2633,7 +2634,7 @@ struct plink *Plink_new(){ if( plink_freelist==0 ){ int i; int amt = 100; - plink_freelist = (struct plink *)malloc( sizeof(struct plink)*amt ); + plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) ); if( plink_freelist==0 ){ fprintf(stderr, "Unable to allocate memory for a new follow-set propagation link.\n"); @@ -2859,10 +2860,15 @@ int PrintAction(struct action *ap, FILE *fp, int indent){ case ERROR: fprintf(fp,"%*s error",indent,ap->sp->name); break; - case CONFLICT: + case SRCONFLICT: + case RRCONFLICT: fprintf(fp,"%*s reduce %-3d ** Parsing conflict **", indent,ap->sp->name,ap->x.rp->index); break; + case SSCONFLICT: + fprintf(fp,"%*s shift %d ** Parsing conflict **", + indent,ap->sp->name,ap->x.stp->statenum); + break; case SH_RESOLVED: case RD_RESOLVED: case NOT_USED: @@ -2884,7 +2890,6 @@ struct lemon *lemp; fp = file_open(lemp,".out","wb"); if( fp==0 ) return; - fprintf(fp," \b"); for(i=0; instate; i++){ stp = lemp->sorted[i]; fprintf(fp,"State %d:\n",stp->statenum); @@ -2914,6 +2919,27 @@ struct lemon *lemp; } fprintf(fp,"\n"); } + fprintf(fp, "----------------------------------------------------\n"); + fprintf(fp, "Symbols:\n"); + for(i=0; insymbol; i++){ + int j; + struct symbol *sp; + + sp = lemp->symbols[i]; + fprintf(fp, " %3d: %s", i, sp->name); + if( sp->type==NONTERMINAL ){ + fprintf(fp, ":"); + if( sp->lambda ){ + fprintf(fp, " "); + } + for(j=0; jnterminal; j++){ + if( sp->firstset && SetFind(sp->firstset, j) ){ + fprintf(fp, " %s", lemp->symbols[j]->name); + } + } + } + fprintf(fp, "\n"); + } fclose(fp); return; } @@ -2928,7 +2954,6 @@ int modemask; char *pathlist; char *path,*cp; char c; - extern int access(); #ifdef __WIN32__ for (cp = argv0 + strlen(argv0); cp-- > argv0; ) @@ -3229,8 +3254,13 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){ for(i=0; inrhs; i++) used[i] = 0; lhsused = 0; + if( rp->code==0 ){ + rp->code = "\n"; + rp->line = rp->ruleline; + } + append_str(0,0,0,0,0); - for(cp=(rp->code?rp->code:""); *cp; cp++){ + for(cp=rp->code; *cp; cp++){ if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){ char saved; for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++); @@ -3351,8 +3381,7 @@ int mhflag; /* True if generating makeheaders output */ /* Allocate and initialize types[] and allocate stddt[] */ arraysize = lemp->nsymbol * 2; - types = (char**)malloc( arraysize * sizeof(char*) ); - for(i=0; ivartype ){ maxdtlength = (int)strlen(lemp->vartype); @@ -3432,7 +3461,9 @@ int mhflag; /* True if generating makeheaders output */ fprintf(out," %s yy%d;\n",types[i],i+1); lineno++; free(types[i]); } - fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; + if( lemp->errsym->useCnt ){ + fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++; + } free(stddt); free(types); fprintf(out,"} YYMINORTYPE;\n"); lineno++; @@ -3482,6 +3513,25 @@ static int axset_compare(const void *a, const void *b){ return p2->nAction - p1->nAction; } +/* +** Write text on "out" that describes the rule "rp". +*/ +static void writeRuleText(FILE *out, struct rule *rp){ + int j; + fprintf(out,"%s ::=", rp->lhs->name); + for(j=0; jnrhs; j++){ + struct symbol *sp = rp->rhs[j]; + fprintf(out," %s", sp->name); + if( sp->type==MULTITERMINAL ){ + int k; + for(k=1; knsubsym; k++){ + fprintf(out,"|%s",sp->subsym[k]->name); + } + } + } +} + + /* Generate C source code for the parser */ void ReportTable(lemp, mhflag) struct lemon *lemp; @@ -3544,18 +3594,13 @@ int mhflag; /* Output in makeheaders format if true */ lemp->wildcard->index); lineno++; } print_stack_union(out,lemp,&lineno,mhflag); + fprintf(out, "#ifndef YYSTACKDEPTH\n"); lineno++; if( lemp->stacksize ){ - if( atoi(lemp->stacksize)<=0 ){ - ErrorMsg(lemp->filename,0, -"Illegal stack size: [%s]. The stack size should be an integer constant.", - lemp->stacksize); - lemp->errorcnt++; - lemp->stacksize = "100"; - } fprintf(out,"#define YYSTACKDEPTH %s\n",lemp->stacksize); lineno++; }else{ fprintf(out,"#define YYSTACKDEPTH 100\n"); lineno++; } + fprintf(out, "#endif\n"); lineno++; if( mhflag ){ fprintf(out,"#if INTERFACE\n"); lineno++; } @@ -3582,8 +3627,10 @@ int mhflag; /* Output in makeheaders format if true */ } fprintf(out,"#define YYNSTATE %d\n",lemp->nstate); lineno++; fprintf(out,"#define YYNRULE %d\n",lemp->nrule); lineno++; - fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; - fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; + if( lemp->errsym->useCnt ){ + fprintf(out,"#define YYERRORSYMBOL %d\n",lemp->errsym->index); lineno++; + fprintf(out,"#define YYERRSYMDT yy%d\n",lemp->errsym->dtnum); lineno++; + } if( lemp->has_fallback ){ fprintf(out,"#define YYFALLBACK 1\n"); lineno++; } @@ -3602,7 +3649,7 @@ int mhflag; /* Output in makeheaders format if true */ */ /* Compute the actions on all states and count them up */ - ax = malloc( sizeof(ax[0])*lemp->nstate*2 ); + ax = calloc(lemp->nstate*2 , sizeof(ax[0])); if( ax==0 ){ fprintf(stderr,"malloc failed\n"); exit(1); @@ -3782,17 +3829,8 @@ int mhflag; /* Output in makeheaders format if true */ */ for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ assert( rp->index==i ); - fprintf(out," /* %3d */ \"%s ::=", i, rp->lhs->name); - for(j=0; jnrhs; j++){ - struct symbol *sp = rp->rhs[j]; - fprintf(out," %s", sp->name); - if( sp->type==MULTITERMINAL ){ - int k; - for(k=1; knsubsym; k++){ - fprintf(out,"|%s",sp->subsym[k]->name); - } - } - } + fprintf(out," /* %3d */ \"", i); + writeRuleText(out, rp); fprintf(out,"\",\n"); lineno++; } tplt_xfer(lemp->name,in,out,&lineno); @@ -3805,7 +3843,8 @@ int mhflag; /* Output in makeheaders format if true */ for(i=0; insymbol; i++){ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type!=TERMINAL ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; + fprintf(out," case %d: /* %s */\n", + sp->index, sp->name); lineno++; } for(i=0; insymbol && lemp->symbols[i]->type!=TERMINAL; i++); if( insymbol ){ @@ -3819,7 +3858,8 @@ int mhflag; /* Output in makeheaders format if true */ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type==TERMINAL || sp->index<=0 || sp->destructor!=0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; + fprintf(out," case %d: /* %s */\n", + sp->index, sp->name); lineno++; dflt_sp = sp; } if( dflt_sp!=0 ){ @@ -3830,7 +3870,8 @@ int mhflag; /* Output in makeheaders format if true */ for(i=0; insymbol; i++){ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; - fprintf(out," case %d:\n",sp->index); lineno++; + fprintf(out," case %d: /* %s */\n", + sp->index, sp->name); lineno++; /* Combine duplicate destructors into a single case */ for(j=i+1; jnsymbol; j++){ @@ -3838,7 +3879,8 @@ int mhflag; /* Output in makeheaders format if true */ if( sp2 && sp2->type!=TERMINAL && sp2->destructor && sp2->dtnum==sp->dtnum && strcmp(sp->destructor,sp2->destructor)==0 ){ - fprintf(out," case %d:\n",sp2->index); lineno++; + fprintf(out," case %d: /* %s */\n", + sp2->index, sp2->name); lineno++; sp2->destructor = 0; } } @@ -3869,10 +3911,14 @@ int mhflag; /* Output in makeheaders format if true */ for(rp=lemp->rule; rp; rp=rp->next){ struct rule *rp2; if( rp->code==0 ) continue; - fprintf(out," case %d:\n",rp->index); lineno++; + fprintf(out," case %d: /* ",rp->index); + writeRuleText(out, rp); + fprintf(out, " */\n"); lineno++; for(rp2=rp->next; rp2; rp2=rp2->next){ if( rp2->code==rp->code ){ - fprintf(out," case %d:\n",rp2->index); lineno++; + fprintf(out," case %d: /*",rp2->index); + writeRuleText(out, rp2); + fprintf(out," */\n"); lineno++; rp2->code = 0; } } @@ -3964,6 +4010,7 @@ struct lemon *lemp; } if( ap->type!=REDUCE ) continue; rp = ap->x.rp; + if( rp->lhsStart ) continue; if( rp==rbest ) continue; n = 1; for(ap2=ap->next; ap2; ap2=ap2->next){ @@ -4072,13 +4119,11 @@ int n; /* Allocate a new set */ char *SetNew(){ char *s; - int i; - s = (char*)malloc( size ); + s = (char*)calloc( size, 1); if( s==0 ){ extern void memory_error(); memory_error(); } - for(i=0; i=0 && ename = Strsafe(x); sp->type = isupper(*x) ? TERMINAL : NONTERMINAL; @@ -4294,11 +4340,13 @@ char *x; sp->prec = -1; sp->assoc = UNK; sp->firstset = 0; - sp->lambda = B_FALSE; + sp->lambda = LEMON_FALSE; sp->destructor = 0; sp->datatype = 0; + sp->useCnt = 0; Symbol_insert(sp,sp->name); } + sp->useCnt++; return sp; } @@ -4468,7 +4516,7 @@ struct symbol **Symbol_arrayof() int i,size; if( x2a==0 ) return 0; size = x2a->count; - array = (struct symbol **)malloc( sizeof(struct symbol *)*size ); + array = (struct symbol **)calloc(size, sizeof(struct symbol *)); if( array ){ for(i=0; itbl[i].data; } @@ -4519,7 +4567,7 @@ struct config *a; struct state *State_new() { struct state *new; - new = (struct state *)malloc( sizeof(struct state) ); + new = (struct state *)calloc(1, sizeof(struct state) ); MemoryCheck(new); return new; } diff --git a/tools/lemon/lempar.c b/tools/lemon/lempar.c index 7058284292..d32a79490a 100644 --- a/tools/lemon/lempar.c +++ b/tools/lemon/lempar.c @@ -1,780 +1,775 @@ -/* Driver template for the LEMON parser generator. -** The author disclaims copyright to this source code. -*/ -/* First off, code is included which follows the "include" declaration -** in the input file. */ -#include -#include -#include -%% -/* Next is all token values, in a form suitable for use by makeheaders. -** This section will be null unless lemon is run with the -m switch. -*/ -/* -** These constants (all generated automatically by the parser generator) -** specify the various kinds of tokens (terminals) that the parser -** understands. -** -** Each symbol here is a terminal symbol in the grammar. -*/ -%% -/* Make sure the INTERFACE macro is defined. -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/* The next thing included is series of defines which control -** various aspects of the generated parser. -** YYCODETYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 terminals -** and nonterminals. "int" is used otherwise. -** YYNOCODE is a number of type YYCODETYPE which corresponds -** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash -** table. -** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. -** YYACTIONTYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 rules and -** states combined. "int" is used otherwise. -** ParseTOKENTYPE is the data type used for minor tokens given -** directly to the parser from the tokenizer. -** YYMINORTYPE is the data type used for all minor tokens. -** This is typically a union of many types, one of -** which is ParseTOKENTYPE. The entry in the union -** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. If -** zero the stack is dynamically sized using realloc() -** ParseARG_SDECL A static variable declaration for the %extra_argument -** ParseARG_PDECL A parameter declaration for the %extra_argument -** ParseARG_STORE Code to store %extra_argument into yypParser -** ParseARG_FETCH Code to extract %extra_argument from yypParser -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. -*/ -%% -#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) -#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) -#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) - -/* Next are that tables used to determine what action to take based on the -** current state and lookahead token. These tables are used to implement -** functions that take a state number and lookahead value and return an -** action integer. -** -** Suppose the action integer is N. Then the action is determined as -** follows -** -** 0 <= N < YYNSTATE Shift N. That is, push the lookahead -** token onto the stack and goto state N. -** -** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. -** -** N == YYNSTATE+YYNRULE A syntax error has occurred. -** -** N == YYNSTATE+YYNRULE+1 The parser accepts its input. -** -** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused -** slots in the yy_action[] table. -** -** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as -** -** yy_action[ yy_shift_ofst[S] + X ] -** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. -** -** The formula above is for computing the action when the lookahead is -** a terminal symbol. If the lookahead is a non-terminal (as occurs after -** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. -** -** The following are the tables generated in this section: -** -** yy_action[] A single table containing all actions. -** yy_lookahead[] A table containing the lookahead for each entry in -** yy_action. Used to detect hash collisions. -** yy_shift_ofst[] For each state, the offset into yy_action for -** shifting terminals. -** yy_reduce_ofst[] For each state, the offset into yy_action for -** shifting non-terminals after a reduce. -** yy_default[] Default action for each state. -*/ -%% -#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) - -/* The next table maps tokens into fallback tokens. If a construct -** like the following: -** -** %fallback ID X Y Z. -** -** appears in the grammer, then ID becomes a fallback token for X, Y, -** and Z. Whenever one of the tokens X, Y, or Z is input to the parser -** but it does not parse, the type of the token is changed to ID and -** the parse is retried before an error is thrown. -*/ -#ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { -%% -}; -#endif /* YYFALLBACK */ - -/* The following structure represents a single element of the -** parser's stack. Information stored includes: -** -** + The state number for the parser at this level of the stack. -** -** + The value of the token stored at this level of the stack. -** (In other words, the "major" token.) -** -** + The semantic value stored at this level of the stack. This is -** the information used by the action routines in the grammar. -** It is sometimes called the "minor" token. -*/ -struct yyStackEntry { - int stateno; /* The state-number */ - int major; /* The major token value. This is the code - ** number for the token at this stack level */ - YYMINORTYPE minor; /* The user-supplied minor token value. This - ** is the value of the token */ -}; -typedef struct yyStackEntry yyStackEntry; - -/* The state of the parser is completely contained in an instance of -** the following structure */ -struct yyParser { - int yyidx; /* Index of top element in stack */ - int yyerrcnt; /* Shifts left before out of the error */ - ParseARG_SDECL /* A place to hold %extra_argument */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -#endif -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -#include -static FILE *yyTraceFILE = 0; -static char *yyTracePrompt = 0; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Turn parser tracing on by giving a stream to which to write the trace -** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL -** -** Inputs: -**
    -**
  • A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -**
  • A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -**
-** -** Outputs: -** None. -*/ -void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ - yyTraceFILE = TraceFILE; - yyTracePrompt = zTracePrompt; - if( yyTraceFILE==0 ) yyTracePrompt = 0; - else if( yyTracePrompt==0 ) yyTraceFILE = 0; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing shifts, the names of all terminals and nonterminals -** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { -%% -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { -%% -}; -#endif /* NDEBUG */ - -#if YYSTACKDEPTH<=0 -/* -** Try to increase the size of the parser stack. -*/ -static void yyGrowStack(yyParser *p){ - int newSize; - yyStackEntry *pNew; - - newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - if( pNew ){ - p->yystack = pNew; - p->yystksz = newSize; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); - } -#endif - } -} -#endif - -/* -** This function allocates a new parser. -** The only argument is a pointer to a function which works like -** malloc. -** -** Inputs: -** A pointer to the function used to allocate memory. -** -** Outputs: -** A pointer to a parser. This pointer is used in subsequent calls -** to Parse and ParseFree. -*/ -void *ParseAlloc(void *(*mallocProc)(size_t)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); - if( pParser ){ - pParser->yyidx = -1; -#if YYSTACKDEPTH<=0 - yyGrowStack(pParser); -#endif - } - return pParser; -} - -/* The following function deletes the value associated with a -** symbol. The symbol can be either a terminal or nonterminal. -** "yymajor" is the symbol code, and "yypminor" is a pointer to -** the value. -*/ -static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen - ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is - ** being destroyed before it is finished parsing. - ** - ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are not used - ** inside the C code. - */ -%% - default: break; /* If no destructor action specified: do nothing */ - } -} - -/* -** Pop the parser's stack once. -** -** If there is a destructor routine associated with the token which -** is popped from the stack, then call it. -** -** Return the major token number for the symbol popped. -*/ -static int yy_pop_parser_stack(yyParser *pParser){ - YYCODETYPE yymajor; - yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - - if( pParser->yyidx<0 ) return 0; -#ifndef NDEBUG - if( yyTraceFILE && pParser->yyidx>=0 ){ - fprintf(yyTraceFILE,"%sPopping %s\n", - yyTracePrompt, - yyTokenName[yytos->major]); - } -#endif - yymajor = yytos->major; - yy_destructor( yymajor, &yytos->minor); - pParser->yyidx--; - return yymajor; -} - -/* -** Deallocate and destroy a parser. Destructors are all called for -** all stack elements before shutting the parser down. -** -** Inputs: -**
    -**
  • A pointer to the parser. This should be a pointer -** obtained from ParseAlloc. -**
  • A pointer to a function used to reclaim memory obtained -** from malloc. -**
-*/ -void ParseFree( - void *p, /* The parser to be deleted */ - void (*freeProc)(void*) /* Function used to reclaim memory */ -){ - yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); -} - -/* -** Find the appropriate action for a parser given the terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; - - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ - return yy_default[stateno]; - } - if( iLookAhead==YYNOCODE ){ - return YY_NO_ACTION; - } - i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ -#ifdef YYFALLBACK - int iFallback; /* Fallback token */ - if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - return yy_find_shift_action(pParser, iFallback); - } -#endif -#ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; - } - } -#endif /* YYWILDCARD */ - } - return yy_default[stateno]; - }else{ - return yy_action[i]; - } -} - -/* -** Find the appropriate action for a parser given the non-terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_reduce_action( - int stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - assert( stateno<=YY_REDUCE_MAX ); - i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - assert( i>=0 && iyyidx--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack every overflows */ -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ -} - -/* -** Perform a shift action. -*/ -static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */ -){ - yyStackEntry *yytos; - yypParser->yyidx++; -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ - yyStackOverflow(yypParser, yypMinor); - return; - } -#else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ - yyStackOverflow(yypParser, yypMinor); - return; - } - } -#endif - yytos = &yypParser->yystack[yypParser->yyidx]; - yytos->stateno = yyNewState; - yytos->major = yyMajor; - yytos->minor = *yypMinor; -#ifndef NDEBUG - if( yyTraceFILE && yypParser->yyidx>0 ){ - int i; - fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); - fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); - fprintf(yyTraceFILE,"\n"); - } -#endif -} - -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { -%% -}; - -static void yy_accept(yyParser*); /* Forward Declaration */ - -/* -** Perform a reduce action and the shift that must immediately -** follow the reduce. -*/ -static void yy_reduce( - yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ -){ - int yygoto; /* The next state */ - int yyact; /* The next action */ - YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, - yyRuleName[yyruleno]); - } -#endif /* NDEBUG */ - - /* Silence complaints from purify about yygotominor being uninitialized - ** in some cases when it is copied into the stack after the following - ** switch. yygotominor is uninitialized when a rule reduces that does - ** not set the value of its left-hand side nonterminal. Leaving the - ** value of the nonterminal uninitialized is utterly harmless as long - ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. - ** - ** 2007-01-16: The wireshark project (www.wireshark.org) reports that - ** without this code, their parser segfaults. I'm not sure what there - ** parser is doing to make this happen. This is the second bug report - ** from wireshark this week. Clearly they are stressing Lemon in ways - ** that it has not been previously stressed... (SQLite ticket #2172) - */ - memset(&yygotominor, 0, sizeof(yygotominor)); - - - switch( yyruleno ){ - /* Beginning here are the reduction cases. A typical example - ** follows: - ** case 0: - ** #line - ** { ... } // User supplied code - ** #line - ** break; - */ -%% - }; - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; - yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto); - if( yyact < YYNSTATE ){ -#ifdef NDEBUG - /* If we are not debugging and the reduce action popped at least - ** one element off the stack, then we can push the new element back - ** onto the stack here, and skip the stack overflow test in yy_shift(). - ** That gives a significant speed improvement. */ - if( yysize ){ - yypParser->yyidx++; - yymsp -= yysize-1; - yymsp->stateno = yyact; - yymsp->major = yygoto; - yymsp->minor = yygotominor; - }else -#endif - { - yy_shift(yypParser,yyact,yygoto,&yygotominor); - } - }else{ - assert( yyact == YYNSTATE + YYNRULE + 1 ); - yy_accept(yypParser); - } -} - -/* -** The following code executes when the parse fails -*/ -static void yy_parse_failed( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser fails */ -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following code executes when a syntax error first occurs. -*/ -static void yy_syntax_error( - yyParser *yypParser, /* The parser */ - int yymajor, /* The major type of the error token */ - YYMINORTYPE yyminor /* The minor type of the error token */ -){ - ParseARG_FETCH; -#define TOKEN (yyminor.yy0) -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser accepts */ -%% - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "ParseAlloc" which describes the current state of the parser. -** The second argument is the major token number. The third is -** the minor token. The fourth optional argument is whatever the -** user wants (and specified in the grammar) and is available for -** use by the action routines. -** -** Inputs: -**
    -**
  • A pointer to the parser (an opaque structure.) -**
  • The major token number. -**
  • The minor token number. -**
  • An option argument of a grammar-specified type. -**
-** -** Outputs: -** None. -*/ -void Parse( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - ParseTOKENTYPE yyminor /* The value for the token */ - ParseARG_PDECL /* Optional %extra_argument parameter */ -){ - YYMINORTYPE yyminorunion; - int yyact; /* The parser action. */ - int yyendofinput; /* True if we are at the end of input */ -#ifdef YYERRORSYMBOL - int yyerrorhit = 0; /* True if yymajor has invoked an error */ -#endif - yyParser *yypParser; /* The parser */ - - /* (re)initialize the parser, if necessary */ - yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - memset(&yyminorunion, 0, sizeof(yyminorunion)); - yyStackOverflow(yypParser, &yyminorunion); - return; - } -#endif - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; - yyendofinput = (yymajor==0); - ParseARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,yymajor); - if( yyactyyerrcnt--; - yymajor = YYNOCODE; - /* [RH] If we can reduce the stack now, do it. Otherwise, constructs */ - /* like "include " won't work because the next token after */ - /* the include will be shifted before the include is reduced. Then the */ - /* parser will act as if that token had been the first one in the */ - /* included file. */ - while( yypParser->yyidx>= 0 && (yyact = yy_find_shift_action(yypParser,YYNOCODE)) < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - } - }else if( yyact < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - }else{ -#ifdef YYERRORSYMBOL - int yymx; -#endif - assert( yyact == YY_ERROR_ACTION ); -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); - } -#endif -#ifdef YYERRORSYMBOL - /* A syntax error has occurred. - ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". - ** - ** This is what we do if the grammar does define ERROR: - ** - ** * Call the %syntax_error function. - ** - ** * Begin popping the stack until we enter a state where - ** it is legal to shift the error symbol, then shift - ** the error symbol. - ** - ** * Set the error count to three. - ** - ** * Begin accepting and shifting new tokens. No new error - ** processing will occur until three tokens have been - ** shifted successfully. - ** - */ - if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yymx = yypParser->yystack[yypParser->yyidx].major; - if( yymx==YYERRORSYMBOL || yyerrorhit ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sDiscard input token %s\n", - yyTracePrompt,yyTokenName[yymajor]); - } -#endif - yy_destructor(yymajor,&yyminorunion); - yymajor = YYNOCODE; - }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, - YYERRORSYMBOL)) >= YYNSTATE - ){ - yy_pop_parser_stack(yypParser); - } - if( yypParser->yyidx < 0 || yymajor==0 ){ - yy_destructor(yymajor,&yyminorunion); - yy_parse_failed(yypParser); - yymajor = YYNOCODE; - }else if( yymx!=YYERRORSYMBOL ){ - YYMINORTYPE u2; - u2.YYERRSYMDT = 0; - yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); - } - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -#else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** - ** * Report an error message, and throw away the input token. - ** - ** * If the input token is $, then fail the parse. - ** - ** As before, subsequent error messages are suppressed until - ** three input tokens have been successfully shifted. - */ - if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yypParser->yyerrcnt = 3; - yy_destructor(yymajor,&yyminorunion); - if( yyendofinput ){ - yy_parse_failed(yypParser); - } - yymajor = YYNOCODE; -#endif - } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); - return; -} +/* Driver template for the LEMON parser generator. +** The author disclaims copyright to this source code. +*/ +/* First off, code is included which follows the "include" declaration +** in the input file. */ +#include +#include +#include +%% +/* Next is all token values, in a form suitable for use by makeheaders. +** This section will be null unless lemon is run with the -m switch. +*/ +/* +** These constants (all generated automatically by the parser generator) +** specify the various kinds of tokens (terminals) that the parser +** understands. +** +** Each symbol here is a terminal symbol in the grammar. +*/ +%% +/* Make sure the INTERFACE macro is defined. +*/ +#ifndef INTERFACE +# define INTERFACE 1 +#endif +/* The next thing included is series of defines which control +** various aspects of the generated parser. +** YYCODETYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 terminals +** and nonterminals. "int" is used otherwise. +** YYNOCODE is a number of type YYCODETYPE which corresponds +** to no legal terminal or nonterminal number. This +** number is used to fill in empty slots of the hash +** table. +** YYFALLBACK If defined, this indicates that one or more tokens +** have fall-back values which should be used if the +** original value of the token will not parse. +** YYACTIONTYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 rules and +** states combined. "int" is used otherwise. +** ParseTOKENTYPE is the data type used for minor tokens given +** directly to the parser from the tokenizer. +** YYMINORTYPE is the data type used for all minor tokens. +** This is typically a union of many types, one of +** which is ParseTOKENTYPE. The entry in the union +** for base tokens is called "yy0". +** YYSTACKDEPTH is the maximum depth of the parser's stack. If +** zero the stack is dynamically sized using realloc() +** ParseARG_SDECL A static variable declaration for the %extra_argument +** ParseARG_PDECL A parameter declaration for the %extra_argument +** ParseARG_STORE Code to store %extra_argument into yypParser +** ParseARG_FETCH Code to extract %extra_argument from yypParser +** YYNSTATE the combined number of states. +** YYNRULE the number of rules in the grammar +** YYERRORSYMBOL is the code number of the error symbol. If not +** defined, then do no error processing. +*/ +%% +#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) +#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) +#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) + +/* Next are that tables used to determine what action to take based on the +** current state and lookahead token. These tables are used to implement +** functions that take a state number and lookahead value and return an +** action integer. +** +** Suppose the action integer is N. Then the action is determined as +** follows +** +** 0 <= N < YYNSTATE Shift N. That is, push the lookahead +** token onto the stack and goto state N. +** +** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. +** +** N == YYNSTATE+YYNRULE A syntax error has occurred. +** +** N == YYNSTATE+YYNRULE+1 The parser accepts its input. +** +** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused +** slots in the yy_action[] table. +** +** The action table is constructed as a single large table named yy_action[]. +** Given state S and lookahead X, the action is computed as +** +** yy_action[ yy_shift_ofst[S] + X ] +** +** If the index value yy_shift_ofst[S]+X is out of range or if the value +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] +** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table +** and that yy_default[S] should be used instead. +** +** The formula above is for computing the action when the lookahead is +** a terminal symbol. If the lookahead is a non-terminal (as occurs after +** a reduce action) then the yy_reduce_ofst[] array is used in place of +** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of +** YY_SHIFT_USE_DFLT. +** +** The following are the tables generated in this section: +** +** yy_action[] A single table containing all actions. +** yy_lookahead[] A table containing the lookahead for each entry in +** yy_action. Used to detect hash collisions. +** yy_shift_ofst[] For each state, the offset into yy_action for +** shifting terminals. +** yy_reduce_ofst[] For each state, the offset into yy_action for +** shifting non-terminals after a reduce. +** yy_default[] Default action for each state. +*/ +%% +#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) + +/* The next table maps tokens into fallback tokens. If a construct +** like the following: +** +** %fallback ID X Y Z. +** +** appears in the grammer, then ID becomes a fallback token for X, Y, +** and Z. Whenever one of the tokens X, Y, or Z is input to the parser +** but it does not parse, the type of the token is changed to ID and +** the parse is retried before an error is thrown. +*/ +#ifdef YYFALLBACK +static const YYCODETYPE yyFallback[] = { +%% +}; +#endif /* YYFALLBACK */ + +/* The following structure represents a single element of the +** parser's stack. Information stored includes: +** +** + The state number for the parser at this level of the stack. +** +** + The value of the token stored at this level of the stack. +** (In other words, the "major" token.) +** +** + The semantic value stored at this level of the stack. This is +** the information used by the action routines in the grammar. +** It is sometimes called the "minor" token. +*/ +struct yyStackEntry { + int stateno; /* The state-number */ + int major; /* The major token value. This is the code + ** number for the token at this stack level */ + YYMINORTYPE minor; /* The user-supplied minor token value. This + ** is the value of the token */ +}; +typedef struct yyStackEntry yyStackEntry; + +/* The state of the parser is completely contained in an instance of +** the following structure */ +struct yyParser { + int yyidx; /* Index of top element in stack */ + int yyerrcnt; /* Shifts left before out of the error */ + ParseARG_SDECL /* A place to hold %extra_argument */ +#if YYSTACKDEPTH<=0 + int yystksz; /* Current side of the stack */ + yyStackEntry *yystack; /* The parser's stack */ +#else + yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ +#endif +}; +typedef struct yyParser yyParser; + +#ifndef NDEBUG +#include +static FILE *yyTraceFILE = 0; +static char *yyTracePrompt = 0; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Turn parser tracing on by giving a stream to which to write the trace +** and a prompt to preface each trace message. Tracing is turned off +** by making either argument NULL +** +** Inputs: +**
    +**
  • A FILE* to which trace output should be written. +** If NULL, then tracing is turned off. +**
  • A prefix string written at the beginning of every +** line of trace output. If NULL, then tracing is +** turned off. +**
+** +** Outputs: +** None. +*/ +void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ + yyTraceFILE = TraceFILE; + yyTracePrompt = zTracePrompt; + if( yyTraceFILE==0 ) yyTracePrompt = 0; + else if( yyTracePrompt==0 ) yyTraceFILE = 0; +} +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* For tracing shifts, the names of all terminals and nonterminals +** are required. The following table supplies these names */ +static const char *const yyTokenName[] = { +%% +}; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* For tracing reduce actions, the names of all rules are required. +*/ +static const char *const yyRuleName[] = { +%% +}; +#endif /* NDEBUG */ + +#if YYSTACKDEPTH<=0 +/* +** Try to increase the size of the parser stack. +*/ +static void yyGrowStack(yyParser *p){ + int newSize; + yyStackEntry *pNew; + + newSize = p->yystksz*2 + 100; + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + if( pNew ){ + p->yystack = pNew; + p->yystksz = newSize; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", + yyTracePrompt, p->yystksz); + } +#endif + } +} +#endif + +/* +** This function allocates a new parser. +** The only argument is a pointer to a function which works like +** malloc. +** +** Inputs: +** A pointer to the function used to allocate memory. +** +** Outputs: +** A pointer to a parser. This pointer is used in subsequent calls +** to Parse and ParseFree. +*/ +void *ParseAlloc(void *(*mallocProc)(size_t)){ + yyParser *pParser; + pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); + if( pParser ){ + pParser->yyidx = -1; +#if YYSTACKDEPTH<=0 + yyGrowStack(pParser); +#endif + } + return pParser; +} + +/* The following function deletes the value associated with a +** symbol. The symbol can be either a terminal or nonterminal. +** "yymajor" is the symbol code, and "yypminor" is a pointer to +** the value. +*/ +static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ + switch( yymajor ){ + /* Here is inserted the actions which take place when a + ** terminal or non-terminal is destroyed. This can happen + ** when the symbol is popped from the stack during a + ** reduce or during error processing or when a parser is + ** being destroyed before it is finished parsing. + ** + ** Note: during a reduce, the only symbols destroyed are those + ** which appear on the RHS of the rule, but which are not used + ** inside the C code. + */ +%% + default: break; /* If no destructor action specified: do nothing */ + } +} + +/* +** Pop the parser's stack once. +** +** If there is a destructor routine associated with the token which +** is popped from the stack, then call it. +** +** Return the major token number for the symbol popped. +*/ +static int yy_pop_parser_stack(yyParser *pParser){ + YYCODETYPE yymajor; + yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; + + if( pParser->yyidx<0 ) return 0; +#ifndef NDEBUG + if( yyTraceFILE && pParser->yyidx>=0 ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + yymajor = yytos->major; + yy_destructor( yymajor, &yytos->minor); + pParser->yyidx--; + return yymajor; +} + +/* +** Deallocate and destroy a parser. Destructors are all called for +** all stack elements before shutting the parser down. +** +** Inputs: +**
    +**
  • A pointer to the parser. This should be a pointer +** obtained from ParseAlloc. +**
  • A pointer to a function used to reclaim memory obtained +** from malloc. +**
+*/ +void ParseFree( + void *p, /* The parser to be deleted */ + void (*freeProc)(void*) /* Function used to reclaim memory */ +){ + yyParser *pParser = (yyParser*)p; + if( pParser==0 ) return; + while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + free(pParser->yystack); +#endif + (*freeProc)((void*)pParser); +} + +/* +** Find the appropriate action for a parser given the terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_shift_action( + yyParser *pParser, /* The parser */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; + int stateno = pParser->yystack[pParser->yyidx].stateno; + + if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ + return yy_default[stateno]; + } + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + if( iLookAhead>0 ){ +#ifdef YYFALLBACK + int iFallback; /* Fallback token */ + if( iLookAhead %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + } +#endif + return yy_find_shift_action(pParser, iFallback); + } +#endif +#ifdef YYWILDCARD + { + int j = i - iLookAhead + YYWILDCARD; + if( j>=0 && j %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); + } +#endif /* NDEBUG */ + return yy_action[j]; + } + } +#endif /* YYWILDCARD */ + } + return yy_default[stateno]; + }else{ + return yy_action[i]; + } +} + +/* +** Find the appropriate action for a parser given the non-terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_reduce_action( + int stateno, /* Current state number */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; + if( stateno>YY_REDUCE_MAX || + (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){ + return yy_default[stateno]; + } + assert( i!=YY_REDUCE_USE_DFLT ); + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + return yy_default[stateno]; + }else{ + return yy_action[i]; + } + return yy_action[i]; +} + +/* +** The following routine is called if the stack overflows. +*/ +static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){ + ParseARG_FETCH; + yypParser->yyidx--; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will execute if the parser + ** stack every overflows */ +%% + ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ +} + +/* +** Perform a shift action. +*/ +static void yy_shift( + yyParser *yypParser, /* The parser to be shifted */ + int yyNewState, /* The new state to shift in */ + int yyMajor, /* The major token to shift in */ + YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */ +){ + yyStackEntry *yytos; + yypParser->yyidx++; +#if YYSTACKDEPTH>0 + if( yypParser->yyidx>=YYSTACKDEPTH ){ + yyStackOverflow(yypParser, yypMinor); + return; + } +#else + if( yypParser->yyidx>=yypParser->yystksz ){ + yyGrowStack(yypParser); + if( yypParser->yyidx>=yypParser->yystksz ){ + yyStackOverflow(yypParser, yypMinor); + return; + } + } +#endif + yytos = &yypParser->yystack[yypParser->yyidx]; + yytos->stateno = yyNewState; + yytos->major = yyMajor; + yytos->minor = *yypMinor; +#ifndef NDEBUG + if( yyTraceFILE && yypParser->yyidx>0 ){ + int i; + fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); + fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); + for(i=1; i<=yypParser->yyidx; i++) + fprintf(yyTraceFILE," (%d)%s",yypParser->yystack[i].stateno,yyTokenName[yypParser->yystack[i].major]); + fprintf(yyTraceFILE,"\n"); + } +#endif +} + +/* The following table contains information about every rule that +** is used during the reduce. +*/ +static const struct { + YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ + unsigned char nrhs; /* Number of right-hand side symbols in the rule */ +} yyRuleInfo[] = { +%% +}; + +static void yy_accept(yyParser*); /* Forward Declaration */ + +/* +** Perform a reduce action and the shift that must immediately +** follow the reduce. +*/ +static void yy_reduce( + yyParser *yypParser, /* The parser */ + int yyruleno /* Number of the rule by which to reduce */ +){ + int yygoto; /* The next state */ + int yyact; /* The next action */ + YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ + yyStackEntry *yymsp; /* The top of the parser's stack */ + int yysize; /* Amount to pop the stack */ + ParseARG_FETCH; + yymsp = &yypParser->yystack[yypParser->yyidx]; +#ifndef NDEBUG + if( yyTraceFILE && yyruleno>=0 + && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, + yyRuleName[yyruleno]); + } +#endif /* NDEBUG */ + + /* Silence complaints from purify about yygotominor being uninitialized + ** in some cases when it is copied into the stack after the following + ** switch. yygotominor is uninitialized when a rule reduces that does + ** not set the value of its left-hand side nonterminal. Leaving the + ** value of the nonterminal uninitialized is utterly harmless as long + ** as the value is never used. So really the only thing this code + ** accomplishes is to quieten purify. + ** + ** 2007-01-16: The wireshark project (www.wireshark.org) reports that + ** without this code, their parser segfaults. I'm not sure what there + ** parser is doing to make this happen. This is the second bug report + ** from wireshark this week. Clearly they are stressing Lemon in ways + ** that it has not been previously stressed... (SQLite ticket #2172) + */ + memset(&yygotominor, 0, sizeof(yygotominor)); + + + switch( yyruleno ){ + /* Beginning here are the reduction cases. A typical example + ** follows: + ** case 0: + ** #line + ** { ... } // User supplied code + ** #line + ** break; + */ +%% + }; + yygoto = yyRuleInfo[yyruleno].lhs; + yysize = yyRuleInfo[yyruleno].nrhs; + yypParser->yyidx -= yysize; + yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto); + if( yyact < YYNSTATE ){ +#ifdef NDEBUG + /* If we are not debugging and the reduce action popped at least + ** one element off the stack, then we can push the new element back + ** onto the stack here, and skip the stack overflow test in yy_shift(). + ** That gives a significant speed improvement. */ + if( yysize ){ + yypParser->yyidx++; + yymsp -= yysize-1; + yymsp->stateno = yyact; + yymsp->major = yygoto; + yymsp->minor = yygotominor; + }else +#endif + { + yy_shift(yypParser,yyact,yygoto,&yygotominor); + } + }else{ + assert( yyact == YYNSTATE + YYNRULE + 1 ); + yy_accept(yypParser); + } +} + +/* +** The following code executes when the parse fails +*/ +static void yy_parse_failed( + yyParser *yypParser /* The parser */ +){ + ParseARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser fails */ +%% + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* +** The following code executes when a syntax error first occurs. +*/ +static void yy_syntax_error( + yyParser *yypParser, /* The parser */ + int yymajor, /* The major type of the error token */ + YYMINORTYPE yyminor /* The minor type of the error token */ +){ + ParseARG_FETCH; +#define TOKEN (yyminor.yy0) +%% + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* +** The following is executed when the parser accepts +*/ +static void yy_accept( + yyParser *yypParser /* The parser */ +){ + ParseARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser accepts */ +%% + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* The main parser program. +** The first argument is a pointer to a structure obtained from +** "ParseAlloc" which describes the current state of the parser. +** The second argument is the major token number. The third is +** the minor token. The fourth optional argument is whatever the +** user wants (and specified in the grammar) and is available for +** use by the action routines. +** +** Inputs: +**
    +**
  • A pointer to the parser (an opaque structure.) +**
  • The major token number. +**
  • The minor token number. +**
  • An option argument of a grammar-specified type. +**
+** +** Outputs: +** None. +*/ +void Parse( + void *yyp, /* The parser */ + int yymajor, /* The major token code number */ + ParseTOKENTYPE yyminor /* The value for the token */ + ParseARG_PDECL /* Optional %extra_argument parameter */ +){ + YYMINORTYPE yyminorunion; + int yyact; /* The parser action. */ + int yyendofinput; /* True if we are at the end of input */ +#ifdef YYERRORSYMBOL + int yyerrorhit = 0; /* True if yymajor has invoked an error */ +#endif + yyParser *yypParser; /* The parser */ + + /* (re)initialize the parser, if necessary */ + yypParser = (yyParser*)yyp; + if( yypParser->yyidx<0 ){ +#if YYSTACKDEPTH<=0 + if( yypParser->yystksz <=0 ){ + memset(&yyminorunion, 0, sizeof(yyminorunion)); + yyStackOverflow(yypParser, &yyminorunion); + return; + } +#endif + yypParser->yyidx = 0; + yypParser->yyerrcnt = -1; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; + } + yyminorunion.yy0 = yyminor; + yyendofinput = (yymajor==0); + ParseARG_STORE; + +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); + } +#endif + + do{ + yyact = yy_find_shift_action(yypParser,yymajor); + if( yyactyyerrcnt--; + yymajor = YYNOCODE; + }else if( yyact < YYNSTATE + YYNRULE ){ + yy_reduce(yypParser,yyact-YYNSTATE); + }else{ +#ifdef YYERRORSYMBOL + int yymx; +#endif + assert( yyact == YY_ERROR_ACTION ); +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); + } +#endif +#ifdef YYERRORSYMBOL + /* A syntax error has occurred. + ** The response to an error depends upon whether or not the + ** grammar defines an error token "ERROR". + ** + ** This is what we do if the grammar does define ERROR: + ** + ** * Call the %syntax_error function. + ** + ** * Begin popping the stack until we enter a state where + ** it is legal to shift the error symbol, then shift + ** the error symbol. + ** + ** * Set the error count to three. + ** + ** * Begin accepting and shifting new tokens. No new error + ** processing will occur until three tokens have been + ** shifted successfully. + ** + */ + if( yypParser->yyerrcnt<0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yymx = yypParser->yystack[yypParser->yyidx].major; + if( yymx==YYERRORSYMBOL || yyerrorhit ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sDiscard input token %s\n", + yyTracePrompt,yyTokenName[yymajor]); + } +#endif + yy_destructor(yymajor,&yyminorunion); + yymajor = YYNOCODE; + }else{ + while( + yypParser->yyidx >= 0 && + yymx != YYERRORSYMBOL && + (yyact = yy_find_reduce_action( + yypParser->yystack[yypParser->yyidx].stateno, + YYERRORSYMBOL)) >= YYNSTATE + ){ + yy_pop_parser_stack(yypParser); + } + if( yypParser->yyidx < 0 || yymajor==0 ){ + yy_destructor(yymajor,&yyminorunion); + yy_parse_failed(yypParser); + yymajor = YYNOCODE; + }else if( yymx!=YYERRORSYMBOL ){ + YYMINORTYPE u2; + u2.YYERRSYMDT = 0; + yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); + } + } + yypParser->yyerrcnt = 3; + yyerrorhit = 1; +#else /* YYERRORSYMBOL is not defined */ + /* This is what we do if the grammar does not define ERROR: + ** + ** * Report an error message, and throw away the input token. + ** + ** * If the input token is $, then fail the parse. + ** + ** As before, subsequent error messages are suppressed until + ** three input tokens have been successfully shifted. + */ + if( yypParser->yyerrcnt<=0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yypParser->yyerrcnt = 3; + yy_destructor(yymajor,&yyminorunion); + if( yyendofinput ){ + yy_parse_failed(yypParser); + } + yymajor = YYNOCODE; +#endif + } + }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); + return; +} diff --git a/tools/re2c/CHANGELOG b/tools/re2c/CHANGELOG index c2b10eeb78..c371edbe14 100644 --- a/tools/re2c/CHANGELOG +++ b/tools/re2c/CHANGELOG @@ -1,3 +1,57 @@ +Version 0.12.3 (2007-08-24) +--------------------------- +- Fixed issue with some compilers. +- Fixed #1776177 Build on AIX. +- Fixed #1743180 fwrite with 0 length crashes on OS X. + +Version 0.12.2 (2007-06-26) +--------------------------- +- Fixed #1743180 fwrite with 0 length crashes on OS X. + +Version 0.12.1 (2007-05-23) +--------------------------- +- Fixed #1711240 problem with '"' and 7F on EBCDIC plattforms. + +Version 0.12.0 (2007-05-01) +--------------------------- +- Re-release of 0.11.3 as new stable branch. +- Fixed issue with short form of switches and parameter if not first switch. +- Fixed #1708378 segfault in actions.cc. + +Version 0.11.3 (2007-04-01) +--------------------------- +- Added support for underscores in named definitions. +- Added new option --no-generation-date. +- Fixed issue with long form of switches. + +Version 0.11.2 (2007-03-01) +--------------------------- +- Added inplace configuration 're2c:yyfill:parameter'. +- Added inplace configuration 're2c:yych:conversion'. +- Fixed -u switch code generation. +- Added ability to avoid defines and overwrite variable and label names. + +Version 0.11.1 (2007-02-20) +--------------------------- +- Applied #1647875 add const to yybm vector. + +Version 0.11.0 (2007-01-01) +--------------------------- +- Added -u switch to support unicode. + +Version 0.10.8 (2007-04-01) +--------------------------- +- Fixed issue with long form of switches. + +Version 0.10.7 (2007-02-20) +--------------------------- +- Applied #1647875 add const to yybm vector. + +Version 0.10.6 (2006-08-05) +--------------------------- +- Fixed #1529351 Segv bug on unterminated code blocks. +- Fixed #1528269 Invalid code generation. + Version 0.10.5 (2006-06-11) --------------------------- - Fixed long form of -1 switch to --single-pass as noted in man page and help. @@ -20,7 +74,7 @@ Version 0.10.2 (2006-05-01) - Fixed -i switch. - Added configuration 'yyfill:enable' to allow suppression of YYFILL() blocks. - Added tutorial like lessons to re2c. -- Added /*!ignore!re2c */ to support documenting of re2c source. +- Added /*!ignore:re2c */ to support documenting of re2c source. - Fixed issue with multiline re2c comments (/*!max:re2c ... */ and alike). - Fixed generation of YYDEBUG() when using -d switch. - Added /*!getstate:re2c */ which triggers generation of the YYGETSTATE() block. diff --git a/tools/re2c/Makefile b/tools/re2c/Makefile index e1d3fc3e44..f465951c50 100644 --- a/tools/re2c/Makefile +++ b/tools/re2c/Makefile @@ -1,11 +1,11 @@ -ifeq (Windows_NT,$(OS)) - WIN=1 - WINCMD=1 -endif -ifeq (msys,$(OSTYPE)) - WIN=1 - WINCMD=0 -endif +ifeq (Windows_NT,$(OS)) + WIN=1 + WINCMD=1 +endif +ifeq (msys,$(OSTYPE)) + WIN=1 + WINCMD=0 +endif ifeq (1,$(WIN)) EXE = re2c.exe diff --git a/tools/re2c/README b/tools/re2c/README index 0cb9ab6396..84c2f4fdb2 100644 --- a/tools/re2c/README +++ b/tools/re2c/README @@ -1,4 +1,4 @@ -re2c Version 0.10.5 +re2c Version 0.12.3 ------------------ Originally written by Peter Bumbulis (peter@csg.uwaterloo.ca) @@ -17,7 +17,7 @@ platforms in 32 bit and 64 bit mode: - GCC 3.3 ... 4.1 - Microsoft VC 7, 7.1, 8 - Intel 9.0 -- Sun C++ 5.8 (CXXFLAGS='-compat5 -library=stlport4') +- Sun C++ 5.8 (CXXFLAGS='-library=stlport4') - MIPSpro Compilers: Version 7.4.4m GCC 2.x and Microsoft VC 6 are not capable of compiling re2c. @@ -41,7 +41,7 @@ re2c) you need the following steps: Or you can create a rpm package and install it by the following commands: ./configure make rpm - rpm -Uhv /re2c-0.10.5-1.rpm + rpm -Uhv /re2c-0.12.3-1.rpm If you want to build from CVS then the first thing you should do is regenerating all build files using the following command: @@ -51,7 +51,7 @@ need to generate RPM packages for cvs builds use these commands: ./autogen.sh ./configure ./makerpm - rpm -Uhv /re2c-0.10.5-.rpm + rpm -Uhv /re2c-0.12.3-.rpm Here should be a number like 1. And must equal the directory where the makerpm step has written the generated rpm to. diff --git a/tools/re2c/actions.cc b/tools/re2c/actions.cc index edb5d53a12..b90584827e 100644 --- a/tools/re2c/actions.cc +++ b/tools/re2c/actions.cc @@ -1,1062 +1,1062 @@ -/* $Id: actions.cc,v 1.35 2006/02/25 12:57:50 helly Exp $ */ -#include -#include -#include -#include -#include - -#include "globals.h" -#include "parser.h" -#include "dfa.h" - -namespace re2c -{ - -void Symbol::ClearTable() -{ +/* $Id: actions.cc 608 2006-11-05 00:48:30Z helly $ */ +#include +#include +#include +#include +#include + +#include "globals.h" +#include "parser.h" +#include "dfa.h" + +namespace re2c +{ + +void Symbol::ClearTable() +{ for (SymbolTable::iterator it = symbol_table.begin(); it != symbol_table.end(); ++it) { delete it->second; } - symbol_table.clear(); -} - -Symbol::SymbolTable Symbol::symbol_table; - -Symbol *Symbol::find(const SubStr &str) -{ - const std::string ss(str.to_string()); - SymbolTable::const_iterator it = symbol_table.find(ss); - - if (it == symbol_table.end()) - { - return (*symbol_table.insert(SymbolTable::value_type(ss, new Symbol(str))).first).second; - } - - return (*it).second; -} - -void showIns(std::ostream &o, const Ins &i, const Ins &base) -{ - o.width(3); - o << &i - &base << ": "; - - switch (i.i.tag) - { - - case CHAR: - { - o << "match "; - - for (const Ins *j = &(&i)[1]; j < (Ins*) i.i.link; ++j) - prtCh(o, j->c.value); - - break; - } - - case GOTO: - o << "goto " << ((Ins*) i.i.link - &base); - break; - - case FORK: - o << "fork " << ((Ins*) i.i.link - &base); - break; - - case CTXT: - o << "ctxt"; - break; - - case TERM: - o << "term " << ((RuleOp*) i.i.link)->accept; - break; - } - - o << "\n"; -} - -uint RegExp::fixedLength() -{ - return ~0; -} - -const char *NullOp::type = "NullOp"; - -void NullOp::calcSize(Char*) -{ - size = 0; -} - -uint NullOp::fixedLength() -{ - return 0; -} - -void NullOp::compile(Char*, Ins*) -{ - ; -} - -void NullOp::split(CharSet&) -{ - ; -} - -std::ostream& operator<<(std::ostream &o, const Range &r) -{ - if ((r.ub - r.lb) == 1) - { - prtCh(o, r.lb); - } - else - { - prtCh(o, r.lb); - o << "-"; - prtCh(o, r.ub - 1); - } - - return o << r.next; -} - -Range *doUnion(Range *r1, Range *r2) -{ - Range *r, **rP = &r; - - for (;;) - { - Range *s; - - if (r1->lb <= r2->lb) - { - s = new Range(*r1); - } - else - { - s = new Range(*r2); - } - - *rP = s; - rP = &s->next; - - for (;;) - { - if (r1->lb <= r2->lb) - { - if (r1->lb > s->ub) - break; - - if (r1->ub > s->ub) - s->ub = r1->ub; - - if (!(r1 = r1->next)) - { - uint ub = 0; - - for (; r2 && r2->lb <= s->ub; r2 = r2->next) - ub = r2->ub; - - if (ub > s->ub) - s->ub = ub; - - *rP = r2; - - return r; - } - } - else - { - if (r2->lb > s->ub) - break; - - if (r2->ub > s->ub) - s->ub = r2->ub; - - if (!(r2 = r2->next)) - { - uint ub = 0; - - for (; r1 && r1->lb <= s->ub; r1 = r1->next) - ub = r1->ub; - - if (ub > s->ub) - s->ub = ub; - - *rP = r1; - - return r; - } - } - } - } - - *rP = NULL; - return r; -} - -Range *doDiff(Range *r1, Range *r2) -{ - Range *r, *s, **rP = &r; - - for (; r1; r1 = r1->next) - { - uint lb = r1->lb; - - for (; r2 && r2->ub <= r1->lb; r2 = r2->next) - - ; - for (; r2 && r2->lb < r1->ub; r2 = r2->next) - { - if (lb < r2->lb) - { - *rP = s = new Range(lb, r2->lb); - rP = &s->next; - } - - if ((lb = r2->ub) >= r1->ub) - goto noMore; - } - - *rP = s = new Range(lb, r1->ub); - rP = &s->next; - -noMore: - ; - } - - *rP = NULL; - return r; -} - -MatchOp *merge(MatchOp *m1, MatchOp *m2) -{ - if (!m1) - return m2; - - if (!m2) - return m1; - - return new MatchOp(doUnion(m1->match, m2->match)); -} - -const char *MatchOp::type = "MatchOp"; - -void MatchOp::display(std::ostream &o) const -{ - o << match; -} - -void MatchOp::calcSize(Char *rep) -{ - size = 1; - - for (Range *r = match; r; r = r->next) - for (uint c = r->lb; c < r->ub; ++c) - if (rep[c] == c) - ++size; -} - -uint MatchOp::fixedLength() -{ - return 1; -} - -void MatchOp::compile(Char *rep, Ins *i) -{ - i->i.tag = CHAR; - i->i.link = &i[size]; - Ins *j = &i[1]; - uint bump = size; - - for (Range *r = match; r; r = r->next) - { - for (uint c = r->lb; c < r->ub; ++c) - { - if (rep[c] == c) - { - j->c.value = c; - j->c.bump = --bump; - j++; - } - } - } -} - -void MatchOp::split(CharSet &s) -{ - for (Range *r = match; r; r = r->next) - { - for (uint c = r->lb; c < r->ub; ++c) - { - CharPtn *x = s.rep[c], *a = x->nxt; - - if (!a) - { - if (x->card == 1) - continue; - - x->nxt = a = s.freeHead; - - if (!(s.freeHead = s.freeHead->nxt)) - s.freeTail = &s.freeHead; - - a->nxt = NULL; - - x->fix = s.fix; - - s.fix = x; - } - - if (--(x->card) == 0) - { - *s.freeTail = x; - *(s.freeTail = &x->nxt) = NULL; - } - - s.rep[c] = a; - ++(a->card); - } - } - - for (; s.fix; s.fix = s.fix->fix) - if (s.fix->card) - s.fix->nxt = NULL; -} - -RegExp * mkDiff(RegExp *e1, RegExp *e2) -{ - MatchOp *m1, *m2; - - if (!(m1 = (MatchOp*) e1->isA(MatchOp::type))) - return NULL; - - if (!(m2 = (MatchOp*) e2->isA(MatchOp::type))) - return NULL; - - Range *r = doDiff(m1->match, m2->match); - - return r ? (RegExp*) new MatchOp(r) : (RegExp*) new NullOp; -} - -RegExp *doAlt(RegExp *e1, RegExp *e2) -{ - if (!e1) - return e2; - - if (!e2) - return e1; - - return new AltOp(e1, e2); -} - -RegExp *mkAlt(RegExp *e1, RegExp *e2) -{ - AltOp *a; - MatchOp *m1, *m2; - - if ((a = (AltOp*) e1->isA(AltOp::type))) - { - if ((m1 = (MatchOp*) a->exp1->isA(MatchOp::type))) - e1 = a->exp2; - } - else if ((m1 = (MatchOp*) e1->isA(MatchOp::type))) - { - e1 = NULL; - } - - if ((a = (AltOp*) e2->isA(AltOp::type))) - { - if ((m2 = (MatchOp*) a->exp1->isA(MatchOp::type))) - e2 = a->exp2; - } - else if ((m2 = (MatchOp*) e2->isA(MatchOp::type))) - { - e2 = NULL; - } - - return doAlt(merge(m1, m2), doAlt(e1, e2)); -} - -const char *AltOp::type = "AltOp"; - -void AltOp::calcSize(Char *rep) -{ - exp1->calcSize(rep); - exp2->calcSize(rep); - size = exp1->size + exp2->size + 2; -} - -uint AltOp::fixedLength() -{ - uint l1 = exp1->fixedLength(); - uint l2 = exp1->fixedLength(); - - if (l1 != l2 || l1 == ~0u) - return ~0; - - return l1; -} - -void AltOp::compile(Char *rep, Ins *i) -{ - i->i.tag = FORK; - Ins *j = &i[exp1->size + 1]; - i->i.link = &j[1]; - exp1->compile(rep, &i[1]); - j->i.tag = GOTO; - j->i.link = &j[exp2->size + 1]; - exp2->compile(rep, &j[1]); -} - -void AltOp::split(CharSet &s) -{ - exp1->split(s); - exp2->split(s); -} - -const char *CatOp::type = "CatOp"; - -void CatOp::calcSize(Char *rep) -{ - exp1->calcSize(rep); - exp2->calcSize(rep); - size = exp1->size + exp2->size; -} - -uint CatOp::fixedLength() -{ - uint l1, l2; - - if ((l1 = exp1->fixedLength()) != ~0u ) - if ((l2 = exp2->fixedLength()) != ~0u) - return l1 + l2; - - return ~0u; -} - -void CatOp::compile(Char *rep, Ins *i) -{ - exp1->compile(rep, &i[0]); - exp2->compile(rep, &i[exp1->size]); -} - -void CatOp::split(CharSet &s) -{ - exp1->split(s); - exp2->split(s); -} - -const char *CloseOp::type = "CloseOp"; - -void CloseOp::calcSize(Char *rep) -{ - exp->calcSize(rep); - size = exp->size + 1; -} - -void CloseOp::compile(Char *rep, Ins *i) -{ - exp->compile(rep, &i[0]); - i += exp->size; - i->i.tag = FORK; - i->i.link = i - exp->size; -} - -void CloseOp::split(CharSet &s) -{ - exp->split(s); -} - -const char *CloseVOp::type = "CloseVOp"; - -void CloseVOp::calcSize(Char *rep) -{ - exp->calcSize(rep); - - if (max >= 0) - { - size = (exp->size * min) + ((1 + exp->size) * (max - min)); - } - else - { - size = (exp->size * min) + 1; - } -} - -void CloseVOp::compile(Char *rep, Ins *i) -{ - Ins *jumppoint; - int st; - jumppoint = i + ((1 + exp->size) * (max - min)); - - for (st = min; st < max; st++) - { - i->i.tag = FORK; - i->i.link = jumppoint; - i++; - exp->compile(rep, &i[0]); - i += exp->size; - } - - for (st = 0; st < min; st++) - { - exp->compile(rep, &i[0]); - i += exp->size; - - if (max < 0 && st == 0) - { - i->i.tag = FORK; - i->i.link = i - exp->size; - i++; - } - } -} - -void CloseVOp::split(CharSet &s) -{ - exp->split(s); -} - -RegExp *expr(Scanner &); - -uint Scanner::unescape(SubStr &s) const -{ - static const char * hex = "0123456789abcdef"; - static const char * oct = "01234567"; - - s.len--; - uint c, ucb = 0; - - if ((c = *s.str++) != '\\' || s.len == 0) - { - return xlat(c); - } - - s.len--; - - switch (c = *s.str++) - { - case 'n': return xlat('\n'); - case 't': return xlat('\t'); - case 'v': return xlat('\v'); - case 'b': return xlat('\b'); - case 'r': return xlat('\r'); - case 'f': return xlat('\f'); - case 'a': return xlat('\a'); - - case 'x': - { - if (s.len < 2) - { - fatal(s.ofs()+s.len, "Illegal hexadecimal character code, two hexadecimal digits are required"); - return ~0; - } - - const char *p1 = strchr(hex, tolower(s.str[0])); - const char *p2 = strchr(hex, tolower(s.str[1])); - - if (!p1 || !p2) - { - fatal(s.ofs()+(p1?1:0), "Illegal hexadecimal character code"); - return ~0; - } - else - { - s.len -= 2; - s.str += 2; - - uint v = (uint)((p1 - hex) << 4) - + (uint)((p2 - hex)); - - return v; - } - } - - case 'U': - { - if (s.len < 8) - { - fatal(s.ofs()+s.len, "Illegal unicode character, eight hexadecimal digits are required"); - return ~0; - } - - uint l = 0; - - if (s.str[0] == '0') - { - l++; - if (s.str[1] == '0') - { - l++; - if (s.str[2] == '0' || (s.str[2] == '1' && uFlag)) - { - l++; - if (uFlag) { - const char *u3 = strchr(hex, tolower(s.str[2])); - const char *u4 = strchr(hex, tolower(s.str[3])); - if (u3 && u4) - { - ucb = (uint)((u3 - hex) << 20) - + (uint)((u4 - hex) << 16); - l++; - } - } - else if (s.str[3] == '0') - { - l++; - } - } - } - } - - if (l != 4) - { - fatal(s.ofs()+l, "Illegal unicode character, eight hexadecimal digits are required"); - } - - s.len -= 4; - s.str += 4; - - // no break; - } - case 'X': - case 'u': - { - if (s.len < 4) - { - fatal(s.ofs()+s.len, - c == 'X' - ? "Illegal hexadecimal character code, four hexadecimal digits are required" - : "Illegal unicode character, four hexadecimal digits are required"); - return ~0; - } - - const char *p1 = strchr(hex, tolower(s.str[0])); - const char *p2 = strchr(hex, tolower(s.str[1])); - const char *p3 = strchr(hex, tolower(s.str[2])); - const char *p4 = strchr(hex, tolower(s.str[3])); - - if (!p1 || !p2 || !p3 || !p4) - { - fatal(s.ofs()+(p1?1:0)+(p2?1:0)+(p3?1:0), - c == 'X' - ? "Illegal hexadecimal character code, non hexxdecimal digit found" - : "Illegal unicode character, non hexadecimal digit found"); - return ~0; - } - else - { - s.len -= 4; - s.str += 4; - - uint v = (uint)((p1 - hex) << 12) - + (uint)((p2 - hex) << 8) - + (uint)((p3 - hex) << 4) - + (uint)((p4 - hex)) - + ucb; - - if (v >= nRealChars) - { - fatal(s.ofs(), - c == 'X' - ? "Illegal hexadecimal character code, out of range" - : "Illegal unicode character, out of range"); - } - - return v; - } - } - - case '4': - case '5': - case '6': - case '7': - { - fatal(s.ofs()-1, "Illegal octal character code, first digit must be 0 thru 3"); - return ~0; - } - - case '0': - case '1': - case '2': - case '3': - { - if (s.len < 2) - { - fatal(s.ofs()+s.len, "Illegal octal character code, three octal digits are required"); - return ~0; - } - - const char *p0 = strchr(oct, c); - const char *p1 = strchr(oct, s.str[0]); - const char *p2 = strchr(oct, s.str[1]); - - if (!p0 || !p1 || !p2) - { - fatal(s.ofs()+(p1?1:0), "Illegal octal character code, non octal digit found"); - return ~0; - } - else - { - s.len -= 2; - s.str += 2; - - uint v = (uint)((p0 - oct) << 6) + (uint)((p1 - oct) << 3) + (uint)(p2 - oct); - - return v; - } - } - - default: - return xlat(c); - } -} - -std::string& Scanner::unescape(SubStr& str_in, std::string& str_out) const -{ - str_out.clear(); - - while(str_in.len) - { - uint c = unescape(str_in); - - if (c > 0xFF) - { - fatal(str_in.ofs(), "Illegal character"); - } - - str_out += static_cast(c); - } - - return str_out; -} - -Range * Scanner::getRange(SubStr &s) const -{ - uint lb = unescape(s), ub, xlb, xub, c; - - if (s.len < 2 || *s.str != '-') - { - ub = lb; - } - else - { - s.len--; - s.str++; - ub = unescape(s); - - if (ub < lb) - { - uint tmp = lb; - lb = ub; - ub = tmp; - } - - xlb = xlat(lb); - xub = xlat(ub); - - for(c = lb; c <= ub; c++) - { - if (!(xlb <= xlat(c) && xlat(c) <= ub)) - { - /* range doesn't work */ - Range * r = new Range(xlb, xlb + 1); - for (c = lb + 1; c <= ub; c++) - { - r = doUnion(r, new Range(xlat(c), xlat(c) + 1)); - } - return r; - } - } - - lb = xlb; - ub = xub; - } - - return new Range(lb, ub + 1); -} - -RegExp * Scanner::matchChar(uint c) const -{ - return new MatchOp(new Range(c, c + 1)); -} - -RegExp * Scanner::strToRE(SubStr s) const -{ - s.len -= 2; - s.str += 1; - - if (s.len == 0) - return new NullOp; - - RegExp *re = matchChar(unescape(s)); - - while (s.len > 0) - re = new CatOp(re, matchChar(unescape(s))); - - return re; -} - -RegExp * Scanner::strToCaseInsensitiveRE(SubStr s) const -{ - s.len -= 2; - s.str += 1; - - if (s.len == 0) - return new NullOp; - - uint c = unescape(s); - - RegExp *re, *reL, *reU; - - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) - { - reL = matchChar(xlat(tolower(c))); - reU = matchChar(xlat(toupper(c))); - re = mkAlt(reL, reU); - } - else - { - re = matchChar(c); - } - - while (s.len > 0) - { - uint c = unescape(s); - - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) - { - reL = matchChar(xlat(tolower(c))); - reU = matchChar(xlat(toupper(c))); - re = new CatOp(re, mkAlt(reL, reU)); - } - else - { - re = new CatOp(re, matchChar(c)); - } - } - - return re; -} - -RegExp * Scanner::ranToRE(SubStr s) const -{ - s.len -= 2; - s.str += 1; - - if (s.len == 0) - return new NullOp; - - Range *r = getRange(s); - - while (s.len > 0) - r = doUnion(r, getRange(s)); - - return new MatchOp(r); -} - -RegExp * Scanner::invToRE(SubStr s) const -{ - s.len--; - s.str++; - - RegExp * any = ranToRE(SubStr(wFlag ? "[\\X0000-\\XFFFF]" : "[\\000-\\377]")); - - if (s.len <= 2) - { - return any; - } - - RegExp * ran = ranToRE(s); - RegExp * inv = mkDiff(any, ran); - - delete ran; - delete any; - - return inv; -} - -RegExp * Scanner::mkDot() const -{ - RegExp * any = ranToRE(SubStr(wFlag ? "[\\X0000-\\XFFFF]" : "[\\000-\\377]")); - RegExp * ran = matchChar(xlat('\n')); - RegExp * inv = mkDiff(any, ran); - - delete ran; - delete any; - - return inv; -} - -const char *RuleOp::type = "RuleOp"; - -RuleOp::RuleOp(RegExp *e, RegExp *c, Token *t, uint a) - : exp(e) - , ctx(c) - , ins(NULL) - , accept(a) - , code(t) - , line(0) -{ - ; -} - -void RuleOp::calcSize(Char *rep) -{ - exp->calcSize(rep); - ctx->calcSize(rep); - size = exp->size + (ctx->size ? ctx->size + 2 : 1); -} - -void RuleOp::compile(Char *rep, Ins *i) -{ - ins = i; - exp->compile(rep, &i[0]); - i += exp->size; - if (ctx->size) - { - i->i.tag = CTXT; - i->i.link = &i[1]; - i++; - ctx->compile(rep, &i[0]); - i += ctx->size; - } - i->i.tag = TERM; - i->i.link = this; -} - -void RuleOp::split(CharSet &s) -{ - exp->split(s); - ctx->split(s); -} - -void optimize(Ins *i) -{ - while (!isMarked(i)) - { - mark(i); - - if (i->i.tag == CHAR) - { - i = (Ins*) i->i.link; - } - else if (i->i.tag == GOTO || i->i.tag == FORK) - { - Ins *target = (Ins*) i->i.link; - optimize(target); - - if (target->i.tag == GOTO) - i->i.link = target->i.link == target ? i : target; - - if (i->i.tag == FORK) - { - Ins *follow = (Ins*) & i[1]; - optimize(follow); - - if (follow->i.tag == GOTO && follow->i.link == follow) - { - i->i.tag = GOTO; - } - else if (i->i.link == i) - { - i->i.tag = GOTO; - i->i.link = follow; - } - } - - return ; - } - else - { - ++i; - } - } -} - -void genCode(std::ostream& o, RegExp *re) -{ - genCode(o, 0, re); -} - -CharSet::CharSet() - : fix(0) - , freeHead(0) - , freeTail(0) - , rep(new CharPtr[nRealChars]) - , ptn(new CharPtn[nRealChars]) -{ - for (uint j = 0; j < nRealChars; ++j) - { - rep[j] = &ptn[0]; - ptn[j].nxt = &ptn[j + 1]; /* wrong for j=nRealChars but will be corrected below */ - ptn[j].card = 0; - } - - freeHead = &ptn[1]; - *(freeTail = &ptn[nRealChars - 1].nxt) = NULL; - ptn[0].card = nRealChars; - ptn[0].nxt = NULL; -} - -CharSet::~CharSet() -{ - delete[] rep; - delete[] ptn; -} - -void genCode(std::ostream& o, uint ind, RegExp *re) -{ - CharSet cs; - uint j; - - re->split(cs); - /* - for(uint k = 0; k < nChars;){ - for(j = k; ++k < nRealChars && cs.rep[k] == cs.rep[j];); - printSpan(cerr, j, k); - cerr << "\t" << cs.rep[j] - &cs.ptn[0] << endl; - } - */ - Char *rep = new Char[nRealChars]; - - for (j = 0; j < nRealChars; ++j) - { - if (!cs.rep[j]->nxt) - cs.rep[j]->nxt = &cs.ptn[j]; - - rep[j] = (Char) (cs.rep[j]->nxt - &cs.ptn[0]); - } - - re->calcSize(rep); - Ins *ins = new Ins[re->size + 1]; - memset(ins, 0, (re->size + 1)*sizeof(Ins)); - re->compile(rep, ins); - Ins *eoi = &ins[re->size]; - eoi->i.tag = GOTO; - eoi->i.link = eoi; - - optimize(ins); - - for (j = 0; j < re->size;) - { - unmark(&ins[j]); - - if (ins[j].i.tag == CHAR) - { - j = (Ins*) ins[j].i.link - ins; - } - else - { - j++; - } - } - - DFA *dfa = new DFA(ins, re->size, 0, nRealChars, rep); - dfa->emit(o, ind); - delete dfa; - delete [] ins; - delete [] rep; -} - -} // end namespace re2c - + symbol_table.clear(); +} + +Symbol::SymbolTable Symbol::symbol_table; + +Symbol *Symbol::find(const SubStr &str) +{ + const std::string ss(str.to_string()); + SymbolTable::const_iterator it = symbol_table.find(ss); + + if (it == symbol_table.end()) + { + return (*symbol_table.insert(SymbolTable::value_type(ss, new Symbol(str))).first).second; + } + + return (*it).second; +} + +void showIns(std::ostream &o, const Ins &i, const Ins &base) +{ + o.width(3); + o << &i - &base << ": "; + + switch (i.i.tag) + { + + case CHAR: + { + o << "match "; + + for (const Ins *j = &(&i)[1]; j < (Ins*) i.i.link; ++j) + prtCh(o, j->c.value); + + break; + } + + case GOTO: + o << "goto " << ((Ins*) i.i.link - &base); + break; + + case FORK: + o << "fork " << ((Ins*) i.i.link - &base); + break; + + case CTXT: + o << "ctxt"; + break; + + case TERM: + o << "term " << ((RuleOp*) i.i.link)->accept; + break; + } + + o << "\n"; +} + +uint RegExp::fixedLength() +{ + return ~0; +} + +const char *NullOp::type = "NullOp"; + +void NullOp::calcSize(Char*) +{ + size = 0; +} + +uint NullOp::fixedLength() +{ + return 0; +} + +void NullOp::compile(Char*, Ins*) +{ + ; +} + +void NullOp::split(CharSet&) +{ + ; +} + +std::ostream& operator<<(std::ostream &o, const Range &r) +{ + if ((r.ub - r.lb) == 1) + { + prtCh(o, r.lb); + } + else + { + prtCh(o, r.lb); + o << "-"; + prtCh(o, r.ub - 1); + } + + return o << r.next; +} + +Range *doUnion(Range *r1, Range *r2) +{ + Range *r, **rP = &r; + + for (;;) + { + Range *s; + + if (r1->lb <= r2->lb) + { + s = new Range(*r1); + } + else + { + s = new Range(*r2); + } + + *rP = s; + rP = &s->next; + + for (;;) + { + if (r1->lb <= r2->lb) + { + if (r1->lb > s->ub) + break; + + if (r1->ub > s->ub) + s->ub = r1->ub; + + if (!(r1 = r1->next)) + { + uint ub = 0; + + for (; r2 && r2->lb <= s->ub; r2 = r2->next) + ub = r2->ub; + + if (ub > s->ub) + s->ub = ub; + + *rP = r2; + + return r; + } + } + else + { + if (r2->lb > s->ub) + break; + + if (r2->ub > s->ub) + s->ub = r2->ub; + + if (!(r2 = r2->next)) + { + uint ub = 0; + + for (; r1 && r1->lb <= s->ub; r1 = r1->next) + ub = r1->ub; + + if (ub > s->ub) + s->ub = ub; + + *rP = r1; + + return r; + } + } + } + } + + *rP = NULL; + return r; +} + +Range *doDiff(Range *r1, Range *r2) +{ + Range *r, *s, **rP = &r; + + for (; r1; r1 = r1->next) + { + uint lb = r1->lb; + + for (; r2 && r2->ub <= r1->lb; r2 = r2->next) + + ; + for (; r2 && r2->lb < r1->ub; r2 = r2->next) + { + if (lb < r2->lb) + { + *rP = s = new Range(lb, r2->lb); + rP = &s->next; + } + + if ((lb = r2->ub) >= r1->ub) + goto noMore; + } + + *rP = s = new Range(lb, r1->ub); + rP = &s->next; + +noMore: + ; + } + + *rP = NULL; + return r; +} + +MatchOp *merge(MatchOp *m1, MatchOp *m2) +{ + if (!m1) + return m2; + + if (!m2) + return m1; + + return new MatchOp(doUnion(m1->match, m2->match)); +} + +const char *MatchOp::type = "MatchOp"; + +void MatchOp::display(std::ostream &o) const +{ + o << match; +} + +void MatchOp::calcSize(Char *rep) +{ + size = 1; + + for (Range *r = match; r; r = r->next) + for (uint c = r->lb; c < r->ub; ++c) + if (rep[c] == c) + ++size; +} + +uint MatchOp::fixedLength() +{ + return 1; +} + +void MatchOp::compile(Char *rep, Ins *i) +{ + i->i.tag = CHAR; + i->i.link = &i[size]; + Ins *j = &i[1]; + uint bump = size; + + for (Range *r = match; r; r = r->next) + { + for (uint c = r->lb; c < r->ub; ++c) + { + if (rep[c] == c) + { + j->c.value = c; + j->c.bump = --bump; + j++; + } + } + } +} + +void MatchOp::split(CharSet &s) +{ + for (Range *r = match; r; r = r->next) + { + for (uint c = r->lb; c < r->ub; ++c) + { + CharPtn *x = s.rep[c], *a = x->nxt; + + if (!a) + { + if (x->card == 1) + continue; + + x->nxt = a = s.freeHead; + + if (!(s.freeHead = s.freeHead->nxt)) + s.freeTail = &s.freeHead; + + a->nxt = NULL; + + x->fix = s.fix; + + s.fix = x; + } + + if (--(x->card) == 0) + { + *s.freeTail = x; + *(s.freeTail = &x->nxt) = NULL; + } + + s.rep[c] = a; + ++(a->card); + } + } + + for (; s.fix; s.fix = s.fix->fix) + if (s.fix->card) + s.fix->nxt = NULL; +} + +RegExp * mkDiff(RegExp *e1, RegExp *e2) +{ + MatchOp *m1, *m2; + + if (!(m1 = (MatchOp*) e1->isA(MatchOp::type))) + return NULL; + + if (!(m2 = (MatchOp*) e2->isA(MatchOp::type))) + return NULL; + + Range *r = doDiff(m1->match, m2->match); + + return r ? (RegExp*) new MatchOp(r) : (RegExp*) new NullOp; +} + +RegExp *doAlt(RegExp *e1, RegExp *e2) +{ + if (!e1) + return e2; + + if (!e2) + return e1; + + return new AltOp(e1, e2); +} + +RegExp *mkAlt(RegExp *e1, RegExp *e2) +{ + AltOp *a; + MatchOp *m1, *m2; + + if ((a = (AltOp*) e1->isA(AltOp::type))) + { + if ((m1 = (MatchOp*) a->exp1->isA(MatchOp::type))) + e1 = a->exp2; + } + else if ((m1 = (MatchOp*) e1->isA(MatchOp::type))) + { + e1 = NULL; + } + + if ((a = (AltOp*) e2->isA(AltOp::type))) + { + if ((m2 = (MatchOp*) a->exp1->isA(MatchOp::type))) + e2 = a->exp2; + } + else if ((m2 = (MatchOp*) e2->isA(MatchOp::type))) + { + e2 = NULL; + } + + return doAlt(merge(m1, m2), doAlt(e1, e2)); +} + +const char *AltOp::type = "AltOp"; + +void AltOp::calcSize(Char *rep) +{ + exp1->calcSize(rep); + exp2->calcSize(rep); + size = exp1->size + exp2->size + 2; +} + +uint AltOp::fixedLength() +{ + uint l1 = exp1->fixedLength(); + uint l2 = exp1->fixedLength(); + + if (l1 != l2 || l1 == ~0u) + return ~0; + + return l1; +} + +void AltOp::compile(Char *rep, Ins *i) +{ + i->i.tag = FORK; + Ins *j = &i[exp1->size + 1]; + i->i.link = &j[1]; + exp1->compile(rep, &i[1]); + j->i.tag = GOTO; + j->i.link = &j[exp2->size + 1]; + exp2->compile(rep, &j[1]); +} + +void AltOp::split(CharSet &s) +{ + exp1->split(s); + exp2->split(s); +} + +const char *CatOp::type = "CatOp"; + +void CatOp::calcSize(Char *rep) +{ + exp1->calcSize(rep); + exp2->calcSize(rep); + size = exp1->size + exp2->size; +} + +uint CatOp::fixedLength() +{ + uint l1, l2; + + if ((l1 = exp1->fixedLength()) != ~0u ) + if ((l2 = exp2->fixedLength()) != ~0u) + return l1 + l2; + + return ~0u; +} + +void CatOp::compile(Char *rep, Ins *i) +{ + exp1->compile(rep, &i[0]); + exp2->compile(rep, &i[exp1->size]); +} + +void CatOp::split(CharSet &s) +{ + exp1->split(s); + exp2->split(s); +} + +const char *CloseOp::type = "CloseOp"; + +void CloseOp::calcSize(Char *rep) +{ + exp->calcSize(rep); + size = exp->size + 1; +} + +void CloseOp::compile(Char *rep, Ins *i) +{ + exp->compile(rep, &i[0]); + i += exp->size; + i->i.tag = FORK; + i->i.link = i - exp->size; +} + +void CloseOp::split(CharSet &s) +{ + exp->split(s); +} + +const char *CloseVOp::type = "CloseVOp"; + +void CloseVOp::calcSize(Char *rep) +{ + exp->calcSize(rep); + + if (max >= 0) + { + size = (exp->size * min) + ((1 + exp->size) * (max - min)); + } + else + { + size = (exp->size * min) + 1; + } +} + +void CloseVOp::compile(Char *rep, Ins *i) +{ + Ins *jumppoint; + int st; + jumppoint = i + ((1 + exp->size) * (max - min)); + + for (st = min; st < max; st++) + { + i->i.tag = FORK; + i->i.link = jumppoint; + i++; + exp->compile(rep, &i[0]); + i += exp->size; + } + + for (st = 0; st < min; st++) + { + exp->compile(rep, &i[0]); + i += exp->size; + + if (max < 0 && st == 0) + { + i->i.tag = FORK; + i->i.link = i - exp->size; + i++; + } + } +} + +void CloseVOp::split(CharSet &s) +{ + exp->split(s); +} + +RegExp *expr(Scanner &); + +uint Scanner::unescape(SubStr &s) const +{ + static const char * hex = "0123456789abcdef"; + static const char * oct = "01234567"; + + s.len--; + uint c, ucb = 0; + + if ((c = *s.str++) != '\\' || s.len == 0) + { + return xlat(c); + } + + s.len--; + + switch (c = *s.str++) + { + case 'n': return xlat('\n'); + case 't': return xlat('\t'); + case 'v': return xlat('\v'); + case 'b': return xlat('\b'); + case 'r': return xlat('\r'); + case 'f': return xlat('\f'); + case 'a': return xlat('\a'); + + case 'x': + { + if (s.len < 2) + { + fatal(s.ofs()+s.len, "Illegal hexadecimal character code, two hexadecimal digits are required"); + return ~0; + } + + const char *p1 = strchr(hex, tolower(s.str[0])); + const char *p2 = strchr(hex, tolower(s.str[1])); + + if (!p1 || !p2) + { + fatal(s.ofs()+(p1?1:0), "Illegal hexadecimal character code"); + return ~0; + } + else + { + s.len -= 2; + s.str += 2; + + uint v = (uint)((p1 - hex) << 4) + + (uint)((p2 - hex)); + + return v; + } + } + + case 'U': + { + if (s.len < 8) + { + fatal(s.ofs()+s.len, "Illegal unicode character, eight hexadecimal digits are required"); + return ~0; + } + + uint l = 0; + + if (s.str[0] == '0') + { + l++; + if (s.str[1] == '0') + { + l++; + if (s.str[2] == '0' || (s.str[2] == '1' && uFlag)) + { + l++; + if (uFlag) { + const char *u3 = strchr(hex, tolower(s.str[2])); + const char *u4 = strchr(hex, tolower(s.str[3])); + if (u3 && u4) + { + ucb = (uint)((u3 - hex) << 20) + + (uint)((u4 - hex) << 16); + l++; + } + } + else if (s.str[3] == '0') + { + l++; + } + } + } + } + + if (l != 4) + { + fatal(s.ofs()+l, "Illegal unicode character, eight hexadecimal digits are required"); + } + + s.len -= 4; + s.str += 4; + + // no break; + } + case 'X': + case 'u': + { + if (s.len < 4) + { + fatal(s.ofs()+s.len, + c == 'X' + ? "Illegal hexadecimal character code, four hexadecimal digits are required" + : "Illegal unicode character, four hexadecimal digits are required"); + return ~0; + } + + const char *p1 = strchr(hex, tolower(s.str[0])); + const char *p2 = strchr(hex, tolower(s.str[1])); + const char *p3 = strchr(hex, tolower(s.str[2])); + const char *p4 = strchr(hex, tolower(s.str[3])); + + if (!p1 || !p2 || !p3 || !p4) + { + fatal(s.ofs()+(p1?1:0)+(p2?1:0)+(p3?1:0), + c == 'X' + ? "Illegal hexadecimal character code, non hexxdecimal digit found" + : "Illegal unicode character, non hexadecimal digit found"); + return ~0; + } + else + { + s.len -= 4; + s.str += 4; + + uint v = (uint)((p1 - hex) << 12) + + (uint)((p2 - hex) << 8) + + (uint)((p3 - hex) << 4) + + (uint)((p4 - hex)) + + ucb; + + if (v >= nRealChars) + { + fatal(s.ofs(), + c == 'X' + ? "Illegal hexadecimal character code, out of range" + : "Illegal unicode character, out of range"); + } + + return v; + } + } + + case '4': + case '5': + case '6': + case '7': + { + fatal(s.ofs()-1, "Illegal octal character code, first digit must be 0 thru 3"); + return ~0; + } + + case '0': + case '1': + case '2': + case '3': + { + if (s.len < 2) + { + fatal(s.ofs()+s.len, "Illegal octal character code, three octal digits are required"); + return ~0; + } + + const char *p0 = strchr(oct, c); + const char *p1 = strchr(oct, s.str[0]); + const char *p2 = strchr(oct, s.str[1]); + + if (!p0 || !p1 || !p2) + { + fatal(s.ofs()+(p1?1:0), "Illegal octal character code, non octal digit found"); + return ~0; + } + else + { + s.len -= 2; + s.str += 2; + + uint v = (uint)((p0 - oct) << 6) + (uint)((p1 - oct) << 3) + (uint)(p2 - oct); + + return v; + } + } + + default: + return xlat(c); + } +} + +std::string& Scanner::unescape(SubStr& str_in, std::string& str_out) const +{ + str_out.clear(); + + while(str_in.len) + { + uint c = unescape(str_in); + + if (c > 0xFF) + { + fatal(str_in.ofs(), "Illegal character"); + } + + str_out += static_cast(c); + } + + return str_out; +} + +Range * Scanner::getRange(SubStr &s) const +{ + uint lb = unescape(s), ub, xlb, xub, c; + + if (s.len < 2 || *s.str != '-') + { + ub = lb; + } + else + { + s.len--; + s.str++; + ub = unescape(s); + + if (ub < lb) + { + uint tmp = lb; + lb = ub; + ub = tmp; + } + + xlb = xlat(lb); + xub = xlat(ub); + + for(c = lb; c <= ub; c++) + { + if (!(xlb <= xlat(c) && xlat(c) <= ub)) + { + /* range doesn't work */ + Range * r = new Range(xlb, xlb + 1); + for (c = lb + 1; c <= ub; c++) + { + r = doUnion(r, new Range(xlat(c), xlat(c) + 1)); + } + return r; + } + } + + lb = xlb; + ub = xub; + } + + return new Range(lb, ub + 1); +} + +RegExp * Scanner::matchChar(uint c) const +{ + return new MatchOp(new Range(c, c + 1)); +} + +RegExp * Scanner::strToRE(SubStr s) const +{ + s.len -= 2; + s.str += 1; + + if (s.len == 0) + return new NullOp; + + RegExp *re = matchChar(unescape(s)); + + while (s.len > 0) + re = new CatOp(re, matchChar(unescape(s))); + + return re; +} + +RegExp * Scanner::strToCaseInsensitiveRE(SubStr s) const +{ + s.len -= 2; + s.str += 1; + + if (s.len == 0) + return new NullOp; + + uint c = unescape(s); + + RegExp *re, *reL, *reU; + + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + { + reL = matchChar(xlat(tolower(c))); + reU = matchChar(xlat(toupper(c))); + re = mkAlt(reL, reU); + } + else + { + re = matchChar(c); + } + + while (s.len > 0) + { + uint c = unescape(s); + + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + { + reL = matchChar(xlat(tolower(c))); + reU = matchChar(xlat(toupper(c))); + re = new CatOp(re, mkAlt(reL, reU)); + } + else + { + re = new CatOp(re, matchChar(c)); + } + } + + return re; +} + +RegExp * Scanner::ranToRE(SubStr s) const +{ + s.len -= 2; + s.str += 1; + + if (s.len == 0) + return new NullOp; + + Range *r = getRange(s); + + while (s.len > 0) + r = doUnion(r, getRange(s)); + + return new MatchOp(r); +} + +RegExp * Scanner::invToRE(SubStr s) const +{ + s.len--; + s.str++; + + RegExp * any = ranToRE(SubStr(wFlag ? "[\\X0000-\\XFFFF]" : "[\\000-\\377]")); + + if (s.len <= 2) + { + return any; + } + + RegExp * ran = ranToRE(s); + RegExp * inv = mkDiff(any, ran); + + delete ran; + delete any; + + return inv; +} + +RegExp * Scanner::mkDot() const +{ + RegExp * any = ranToRE(SubStr(wFlag ? "[\\X0000-\\XFFFF]" : "[\\000-\\377]")); + RegExp * ran = matchChar(xlat('\n')); + RegExp * inv = mkDiff(any, ran); + + delete ran; + delete any; + + return inv; +} + +const char *RuleOp::type = "RuleOp"; + +RuleOp::RuleOp(RegExp *e, RegExp *c, Token *t, uint a) + : exp(e) + , ctx(c) + , ins(NULL) + , accept(a) + , code(t) + , line(0) +{ + ; +} + +void RuleOp::calcSize(Char *rep) +{ + exp->calcSize(rep); + ctx->calcSize(rep); + size = exp->size + (ctx->size ? ctx->size + 2 : 1); +} + +void RuleOp::compile(Char *rep, Ins *i) +{ + ins = i; + exp->compile(rep, &i[0]); + i += exp->size; + if (ctx->size) + { + i->i.tag = CTXT; + i->i.link = &i[1]; + i++; + ctx->compile(rep, &i[0]); + i += ctx->size; + } + i->i.tag = TERM; + i->i.link = this; +} + +void RuleOp::split(CharSet &s) +{ + exp->split(s); + ctx->split(s); +} + +void optimize(Ins *i) +{ + while (!isMarked(i)) + { + mark(i); + + if (i->i.tag == CHAR) + { + i = (Ins*) i->i.link; + } + else if (i->i.tag == GOTO || i->i.tag == FORK) + { + Ins *target = (Ins*) i->i.link; + optimize(target); + + if (target->i.tag == GOTO) + i->i.link = target->i.link == target ? i : target; + + if (i->i.tag == FORK) + { + Ins *follow = (Ins*) & i[1]; + optimize(follow); + + if (follow->i.tag == GOTO && follow->i.link == follow) + { + i->i.tag = GOTO; + } + else if (i->i.link == i) + { + i->i.tag = GOTO; + i->i.link = follow; + } + } + + return ; + } + else + { + ++i; + } + } +} + +void genCode(std::ostream& o, RegExp *re) +{ + genCode(o, 0, re); +} + +CharSet::CharSet() + : fix(0) + , freeHead(0) + , freeTail(0) + , rep(new CharPtr[nRealChars]) + , ptn(new CharPtn[nRealChars]) +{ + for (uint j = 0; j < nRealChars; ++j) + { + rep[j] = &ptn[0]; + ptn[j].nxt = &ptn[j + 1]; /* wrong for j=nRealChars but will be corrected below */ + ptn[j].card = 0; + } + + freeHead = &ptn[1]; + *(freeTail = &ptn[nRealChars - 1].nxt) = NULL; + ptn[0].card = nRealChars; + ptn[0].nxt = NULL; +} + +CharSet::~CharSet() +{ + delete[] rep; + delete[] ptn; +} + +void genCode(std::ostream& o, uint ind, RegExp *re) +{ + CharSet cs; + uint j; + + re->split(cs); + /* + for(uint k = 0; k < nChars;){ + for(j = k; ++k < nRealChars && cs.rep[k] == cs.rep[j];); + printSpan(cerr, j, k); + cerr << "\t" << cs.rep[j] - &cs.ptn[0] << endl; + } + */ + Char *rep = new Char[nRealChars]; + + for (j = 0; j < nRealChars; ++j) + { + if (!cs.rep[j]->nxt) + cs.rep[j]->nxt = &cs.ptn[j]; + + rep[j] = (Char) (cs.rep[j]->nxt - &cs.ptn[0]); + } + + re->calcSize(rep); + Ins *ins = new Ins[re->size + 1]; + memset(ins, 0, (re->size + 1)*sizeof(Ins)); + re->compile(rep, ins); + Ins *eoi = &ins[re->size]; + eoi->i.tag = GOTO; + eoi->i.link = eoi; + + optimize(ins); + + for (j = 0; j < re->size;) + { + unmark(&ins[j]); + + if (ins[j].i.tag == CHAR) + { + j = (Ins*) ins[j].i.link - ins; + } + else + { + j++; + } + } + + DFA *dfa = new DFA(ins, re->size, 0, nRealChars, rep); + dfa->emit(o, ind); + delete dfa; + delete [] ins; + delete [] rep; +} + +} // end namespace re2c + diff --git a/tools/re2c/basics.h b/tools/re2c/basics.h index 009adda185..c9ddb62764 100644 --- a/tools/re2c/basics.h +++ b/tools/re2c/basics.h @@ -1,4 +1,4 @@ -/* $Id: basics.h,v 1.6 2005/12/29 14:32:09 helly Exp $ */ +/* $Id: basics.h 520 2006-05-25 13:31:06Z helly $ */ #ifndef _basics_h #define _basics_h diff --git a/tools/re2c/code.cc b/tools/re2c/code.cc index 38477a24b8..f6eea4d0ba 100644 --- a/tools/re2c/code.cc +++ b/tools/re2c/code.cc @@ -1,900 +1,900 @@ -/* $Id: code.cc,v 1.74 2006/05/14 13:38:26 helly Exp $ */ -#include -#include -#include -#include -#include -#include "substr.h" -#include "globals.h" -#include "dfa.h" -#include "parser.h" -#include "code.h" - -namespace re2c -{ - -// there must be at least one span in list; all spans must cover -// same range - -std::string indent(uint ind) -{ - std::string str; - - while (ind-- > 0) - { - str += indString; - } - return str; -} - -static std::string space(uint this_label) -{ - int nl = next_label > 999999 ? 6 : next_label > 99999 ? 5 : next_label > 9999 ? 4 : next_label > 999 ? 3 : next_label > 99 ? 2 : next_label > 9 ? 1 : 0; - int tl = this_label > 999999 ? 6 : this_label > 99999 ? 5 : this_label > 9999 ? 4 : this_label > 999 ? 3 : this_label > 99 ? 2 : this_label > 9 ? 1 : 0; - - return std::string(std::max(1, nl - tl + 1), ' '); -} - -void Go::compact() -{ - // arrange so that adjacent spans have different targets - uint i = 0; - - for (uint j = 1; j < nSpans; ++j) - { - if (span[j].to != span[i].to) - { - ++i; - span[i].to = span[j].to; - } - - span[i].ub = span[j].ub; - } - - nSpans = i + 1; -} - -void Go::unmap(Go *base, const State *x) -{ - Span *s = span, *b = base->span, *e = &b[base->nSpans]; - uint lb = 0; - s->ub = 0; - s->to = NULL; - - for (; b != e; ++b) - { - if (b->to == x) - { - if ((s->ub - lb) > 1) - { - s->ub = b->ub; - } - } - else - { - if (b->to != s->to) - { - if (s->ub) - { - lb = s->ub; - ++s; - } - - s->to = b->to; - } - - s->ub = b->ub; - } - } - - s->ub = e[ -1].ub; - ++s; - nSpans = s - span; -} - -void doGen(const Go *g, const State *s, uint *bm, uint f, uint m) -{ - Span *b = g->span, *e = &b[g->nSpans]; - uint lb = 0; - - for (; b < e; ++b) - { - if (b->to == s) - { - for (; lb < b->ub && lb < 256; ++lb) - { - bm[lb-f] |= m; - } - } - - lb = b->ub; - } -} - -void prt(std::ostream& o, const Go *g, const State *s) -{ - Span *b = g->span, *e = &b[g->nSpans]; - uint lb = 0; - - for (; b < e; ++b) - { - if (b->to == s) - { - printSpan(o, lb, b->ub); - } - - lb = b->ub; - } -} - -bool matches(const Go *g1, const State *s1, const Go *g2, const State *s2) -{ - Span *b1 = g1->span, *e1 = &b1[g1->nSpans]; - uint lb1 = 0; - Span *b2 = g2->span, *e2 = &b2[g2->nSpans]; - uint lb2 = 0; - - for (;;) - { - for (; b1 < e1 && b1->to != s1; ++b1) - { - lb1 = b1->ub; - } - - for (; b2 < e2 && b2->to != s2; ++b2) - { - lb2 = b2->ub; - } - - if (b1 == e1) - { - return b2 == e2; - } - - if (b2 == e2) - { - return false; - } - - if (lb1 != lb2 || b1->ub != b2->ub) - { - return false; - } - - ++b1; - ++b2; - } -} - -BitMap *BitMap::first = NULL; - -BitMap::BitMap(const Go *g, const State *x) - : go(g) - , on(x) - , next(first) - , i(0) - , m(0) -{ - first = this; -} - -BitMap::~BitMap() -{ - delete next; -} - -const BitMap *BitMap::find(const Go *g, const State *x) -{ - for (const BitMap *b = first; b; b = b->next) - { - if (matches(b->go, b->on, g, x)) - { - return b; - } - } - - return new BitMap(g, x); -} - -const BitMap *BitMap::find(const State *x) -{ - for (const BitMap *b = first; b; b = b->next) - { - if (b->on == x) - { - return b; - } - } - - return NULL; -} - -void BitMap::gen(std::ostream &o, uint ind, uint lb, uint ub) -{ - if (first && bLastPass) - { - o << indent(ind) << "static const unsigned char " << mapCodeName["yybm"] << "[] = {"; - - uint c = 1, n = ub - lb; - const BitMap *cb = first; - - while((cb = cb->next) != NULL) { - ++c; - } - BitMap *b = first; - - uint *bm = new uint[n]; - - for (uint i = 0, t = 1; b; i += n, t += 8) - { - memset(bm, 0, n * sizeof(uint)); - - for (uint m = 0x80; b && m; m >>= 1) - { - b->i = i; - b->m = m; - doGen(b->go, b->on, bm, lb, m); - b = const_cast(b->next); - } - - if (c > 8) - { - o << "\n" << indent(ind+1) << "/* table " << t << " .. " << std::min(c, t+7) << ": " << i << " */"; - } - - for (uint j = 0; j < n; ++j) - { - if (j % 8 == 0) - { - o << "\n" << indent(ind+1); - } - - if (yybmHexTable) - { - prtHex(o, bm[j], false); - } - else - { - o << std::setw(3) << (uint)bm[j]; - } - o << ", "; - } - } - - o << "\n" << indent(ind) << "};\n"; - /* stats(); */ - - delete[] bm; - } -} - -void BitMap::stats() -{ - uint n = 0; - - for (const BitMap *b = first; b; b = b->next) - { - prt(std::cerr, b->go, b->on); - std::cerr << std::endl; - ++n; - } - - std::cerr << n << " bitmaps\n"; - first = NULL; -} - -void genGoTo(std::ostream &o, uint ind, const State *from, const State *to, bool & readCh) -{ - if (readCh && from->label + 1 != to->label) - { - o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n"; - readCh = false; - } - - o << indent(ind) << "goto " << labelPrefix << to->label << ";\n"; - vUsedLabels.insert(to->label); -} - -void genIf(std::ostream &o, uint ind, const char *cmp, uint v, bool &readCh) -{ - o << indent(ind) << "if("; - if (readCh) - { +/* $Id: code.cc 717 2007-04-29 22:29:59Z helly $ */ +#include +#include +#include +#include +#include +#include "substr.h" +#include "globals.h" +#include "dfa.h" +#include "parser.h" +#include "code.h" + +namespace re2c +{ + +// there must be at least one span in list; all spans must cover +// same range + +std::string indent(uint ind) +{ + std::string str; + + while (ind-- > 0) + { + str += indString; + } + return str; +} + +static std::string space(uint this_label) +{ + int nl = next_label > 999999 ? 6 : next_label > 99999 ? 5 : next_label > 9999 ? 4 : next_label > 999 ? 3 : next_label > 99 ? 2 : next_label > 9 ? 1 : 0; + int tl = this_label > 999999 ? 6 : this_label > 99999 ? 5 : this_label > 9999 ? 4 : this_label > 999 ? 3 : this_label > 99 ? 2 : this_label > 9 ? 1 : 0; + + return std::string(std::max(1, nl - tl + 1), ' '); +} + +void Go::compact() +{ + // arrange so that adjacent spans have different targets + uint i = 0; + + for (uint j = 1; j < nSpans; ++j) + { + if (span[j].to != span[i].to) + { + ++i; + span[i].to = span[j].to; + } + + span[i].ub = span[j].ub; + } + + nSpans = i + 1; +} + +void Go::unmap(Go *base, const State *x) +{ + Span *s = span, *b = base->span, *e = &b[base->nSpans]; + uint lb = 0; + s->ub = 0; + s->to = NULL; + + for (; b != e; ++b) + { + if (b->to == x) + { + if ((s->ub - lb) > 1) + { + s->ub = b->ub; + } + } + else + { + if (b->to != s->to) + { + if (s->ub) + { + lb = s->ub; + ++s; + } + + s->to = b->to; + } + + s->ub = b->ub; + } + } + + s->ub = e[ -1].ub; + ++s; + nSpans = s - span; +} + +void doGen(const Go *g, const State *s, uint *bm, uint f, uint m) +{ + Span *b = g->span, *e = &b[g->nSpans]; + uint lb = 0; + + for (; b < e; ++b) + { + if (b->to == s) + { + for (; lb < b->ub && lb < 256; ++lb) + { + bm[lb-f] |= m; + } + } + + lb = b->ub; + } +} + +void prt(std::ostream& o, const Go *g, const State *s) +{ + Span *b = g->span, *e = &b[g->nSpans]; + uint lb = 0; + + for (; b < e; ++b) + { + if (b->to == s) + { + printSpan(o, lb, b->ub); + } + + lb = b->ub; + } +} + +bool matches(const Go *g1, const State *s1, const Go *g2, const State *s2) +{ + Span *b1 = g1->span, *e1 = &b1[g1->nSpans]; + uint lb1 = 0; + Span *b2 = g2->span, *e2 = &b2[g2->nSpans]; + uint lb2 = 0; + + for (;;) + { + for (; b1 < e1 && b1->to != s1; ++b1) + { + lb1 = b1->ub; + } + + for (; b2 < e2 && b2->to != s2; ++b2) + { + lb2 = b2->ub; + } + + if (b1 == e1) + { + return b2 == e2; + } + + if (b2 == e2) + { + return false; + } + + if (lb1 != lb2 || b1->ub != b2->ub) + { + return false; + } + + ++b1; + ++b2; + } +} + +BitMap *BitMap::first = NULL; + +BitMap::BitMap(const Go *g, const State *x) + : go(g) + , on(x) + , next(first) + , i(0) + , m(0) +{ + first = this; +} + +BitMap::~BitMap() +{ + delete next; +} + +const BitMap *BitMap::find(const Go *g, const State *x) +{ + for (const BitMap *b = first; b; b = b->next) + { + if (matches(b->go, b->on, g, x)) + { + return b; + } + } + + return new BitMap(g, x); +} + +const BitMap *BitMap::find(const State *x) +{ + for (const BitMap *b = first; b; b = b->next) + { + if (b->on == x) + { + return b; + } + } + + return NULL; +} + +void BitMap::gen(std::ostream &o, uint ind, uint lb, uint ub) +{ + if (first && bLastPass) + { + o << indent(ind) << "static const unsigned char " << mapCodeName["yybm"] << "[] = {"; + + uint c = 1, n = ub - lb; + const BitMap *cb = first; + + while((cb = cb->next) != NULL) { + ++c; + } + BitMap *b = first; + + uint *bm = new uint[n]; + + for (uint i = 0, t = 1; b; i += n, t += 8) + { + memset(bm, 0, n * sizeof(uint)); + + for (uint m = 0x80; b && m; m >>= 1) + { + b->i = i; + b->m = m; + doGen(b->go, b->on, bm, lb, m); + b = const_cast(b->next); + } + + if (c > 8) + { + o << "\n" << indent(ind+1) << "/* table " << t << " .. " << std::min(c, t+7) << ": " << i << " */"; + } + + for (uint j = 0; j < n; ++j) + { + if (j % 8 == 0) + { + o << "\n" << indent(ind+1); + } + + if (yybmHexTable) + { + prtHex(o, bm[j], false); + } + else + { + o << std::setw(3) << (uint)bm[j]; + } + o << ", "; + } + } + + o << "\n" << indent(ind) << "};\n"; + /* stats(); */ + + delete[] bm; + } +} + +void BitMap::stats() +{ + uint n = 0; + + for (const BitMap *b = first; b; b = b->next) + { + prt(std::cerr, b->go, b->on); + std::cerr << std::endl; + ++n; + } + + std::cerr << n << " bitmaps\n"; + first = NULL; +} + +void genGoTo(std::ostream &o, uint ind, const State *from, const State *to, bool & readCh) +{ + if (readCh && from->label + 1 != to->label) + { + o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n"; + readCh = false; + } + + o << indent(ind) << "goto " << labelPrefix << to->label << ";\n"; + vUsedLabels.insert(to->label); +} + +void genIf(std::ostream &o, uint ind, const char *cmp, uint v, bool &readCh) +{ + o << indent(ind) << "if("; + if (readCh) + { o << "(" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")"; - readCh = false; - } - else - { - o << mapCodeName["yych"]; - } - - o << " " << cmp << " "; - prtChOrHex(o, v); - o << ") "; -} - -static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMarker) -{ - uint fillIndex = next_fill_index; - - if (fFlag) - { - next_fill_index++; + readCh = false; + } + else + { + o << mapCodeName["yych"]; + } + + o << " " << cmp << " "; + prtChOrHex(o, v); + o << ") "; +} + +static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMarker) +{ + uint fillIndex = next_fill_index; + + if (fFlag) + { + next_fill_index++; o << indent(ind) << mapCodeName["YYSETSTATE"] << "(" << fillIndex << ");\n"; - } - - if (bUseYYFill) - { - if (n == 1) - { + } + + if (bUseYYFill) + { + if (n == 1) + { o << indent(ind) << "if(" << mapCodeName["YYLIMIT"] << " == " << mapCodeName["YYCURSOR"] << ") " << mapCodeName["YYFILL"]; - } - else - { - o << indent(ind) << "if((YYLIMIT - YYCURSOR) < " << n << ") YYFILL(" << n << ");\n"; - } + } + else + { + o << indent(ind) << "if((" << mapCodeName["YYLIMIT"] << " - " << mapCodeName["YYCURSOR"] << ") < " << n << ") " << mapCodeName["YYFILL"]; + } if (bUseYYFillParam) { o << "(" << n << ")"; } o << ";\n"; - } - - if (fFlag) - { + } + + if (fFlag) + { o << mapCodeName["yyFillLabel"] << fillIndex << ":\n"; - } - - if (bSetMarker) - { + } + + if (bSetMarker) + { o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*(" << mapCodeName["YYMARKER"] << " = " << mapCodeName["YYCURSOR"] << ");\n"; - } - else - { + } + else + { o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n"; - } - readCh = false; -} - -void Match::emit(std::ostream &o, uint ind, bool &readCh) const -{ - if (state->link) - { + } + readCh = false; +} + +void Match::emit(std::ostream &o, uint ind, bool &readCh) const +{ + if (state->link) + { o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n"; - } - else if (!readAhead()) - { - /* do not read next char if match */ + } + else if (!readAhead()) + { + /* do not read next char if match */ o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n"; - readCh = true; - } - else - { + readCh = true; + } + else + { o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n"; - readCh = false; - } - - if (state->link) - { - need(o, ind, state->depth, readCh, false); - } -} - -void Enter::emit(std::ostream &o, uint ind, bool &readCh) const -{ - if (state->link) - { + readCh = false; + } + + if (state->link) + { + need(o, ind, state->depth, readCh, false); + } +} + +void Enter::emit(std::ostream &o, uint ind, bool &readCh) const +{ + if (state->link) + { o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n"; - if (vUsedLabels.count(label)) - { + if (vUsedLabels.count(label)) + { o << labelPrefix << label << ":\n"; - } - need(o, ind, state->depth, readCh, false); - } - else - { - /* we shouldn't need 'rule-following' protection here */ + } + need(o, ind, state->depth, readCh, false); + } + else + { + /* we shouldn't need 'rule-following' protection here */ o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n"; - if (vUsedLabels.count(label)) - { + if (vUsedLabels.count(label)) + { o << labelPrefix << label << ":\n"; - } - readCh = false; - } -} - -void Initial::emit(std::ostream &o, uint ind, bool &readCh) const -{ - if (!startLabelName.empty()) - { - o << startLabelName << ":\n"; - } - - if (vUsedLabels.count(1)) - { - if (state->link) - { + } + readCh = false; + } +} + +void Initial::emit(std::ostream &o, uint ind, bool &readCh) const +{ + if (!startLabelName.empty()) + { + o << startLabelName << ":\n"; + } + + if (vUsedLabels.count(1)) + { + if (state->link) + { o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n"; - } - else - { + } + else + { o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n"; - } - } - - if (vUsedLabels.count(label)) - { + } + } + + if (vUsedLabels.count(label)) + { o << labelPrefix << label << ":\n"; - } - else if (!label) - { - o << "\n"; - } - - if (dFlag) - { + } + else if (!label) + { + o << "\n"; + } + + if (dFlag) + { o << indent(ind) << mapCodeName["YYDEBUG"] << "(" << label << ", *" << mapCodeName["YYCURSOR"] << ");\n"; - } - - if (state->link) - { - need(o, ind, state->depth, readCh, setMarker && bUsedYYMarker); - } - else - { - if (setMarker && bUsedYYMarker) - { + } + + if (state->link) + { + need(o, ind, state->depth, readCh, setMarker && bUsedYYMarker); + } + else + { + if (setMarker && bUsedYYMarker) + { o << indent(ind) << mapCodeName["YYMARKER"] << " = " << mapCodeName["YYCURSOR"] << ";\n"; - } - readCh = false; - } -} - -void Save::emit(std::ostream &o, uint ind, bool &readCh) const -{ - if (bUsedYYAccept) - { + } + readCh = false; + } +} + +void Save::emit(std::ostream &o, uint ind, bool &readCh) const +{ + if (bUsedYYAccept) + { o << indent(ind) << mapCodeName["yyaccept"] << " = " << selector << ";\n"; - } - - if (state->link) - { - if (bUsedYYMarker) - { + } + + if (state->link) + { + if (bUsedYYMarker) + { o << indent(ind) << mapCodeName["YYMARKER"] << " = ++" << mapCodeName["YYCURSOR"] << ";\n"; - } - need(o, ind, state->depth, readCh, false); - } - else - { - if (bUsedYYMarker) - { + } + need(o, ind, state->depth, readCh, false); + } + else + { + if (bUsedYYMarker) + { o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*(" << mapCodeName["YYMARKER"] << " = ++" << mapCodeName["YYCURSOR"] << ");\n"; - } - else - { + } + else + { o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n"; - } - readCh = false; - } -} - -Move::Move(State *s) : Action(s) -{ - ; -} - -void Move::emit(std::ostream &, uint, bool &) const -{ - ; -} - -Accept::Accept(State *x, uint n, uint *s, State **r) - : Action(x), nRules(n), saves(s), rules(r) -{ - ; -} - -void Accept::genRuleMap() -{ - for (uint i = 0; i < nRules; ++i) - { - if (saves[i] != ~0u) - { - mapRules[saves[i]] = rules[i]; - } - } -} - -void Accept::emitBinary(std::ostream &o, uint ind, uint l, uint r, bool &readCh) const -{ - if (l < r) - { - uint m = (l + r) >> 1; - + } + readCh = false; + } +} + +Move::Move(State *s) : Action(s) +{ + ; +} + +void Move::emit(std::ostream &, uint, bool &) const +{ + ; +} + +Accept::Accept(State *x, uint n, uint *s, State **r) + : Action(x), nRules(n), saves(s), rules(r) +{ + ; +} + +void Accept::genRuleMap() +{ + for (uint i = 0; i < nRules; ++i) + { + if (saves[i] != ~0u) + { + mapRules[saves[i]] = rules[i]; + } + } +} + +void Accept::emitBinary(std::ostream &o, uint ind, uint l, uint r, bool &readCh) const +{ + if (l < r) + { + uint m = (l + r) >> 1; + o << indent(ind) << "if(" << mapCodeName["yyaccept"] << " <= " << m << ") {\n"; - emitBinary(o, ++ind, l, m, readCh); - o << indent(--ind) << "} else {\n"; - emitBinary(o, ++ind, m + 1, r, readCh); - o << indent(--ind) << "}\n"; - } - else - { - genGoTo(o, ind, state, mapRules.find(l)->second, readCh); - } -} - -void Accept::emit(std::ostream &o, uint ind, bool &readCh) const -{ - if (mapRules.size() > 0) - { - bUsedYYMarker = true; + emitBinary(o, ++ind, l, m, readCh); + o << indent(--ind) << "} else {\n"; + emitBinary(o, ++ind, m + 1, r, readCh); + o << indent(--ind) << "}\n"; + } + else + { + genGoTo(o, ind, state, mapRules.find(l)->second, readCh); + } +} + +void Accept::emit(std::ostream &o, uint ind, bool &readCh) const +{ + if (mapRules.size() > 0) + { + bUsedYYMarker = true; o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYMARKER"] << ";\n"; - - if (readCh) // shouldn't be necessary, but might become at some point - { + + if (readCh) // shouldn't be necessary, but might become at some point + { o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n"; - readCh = false; - } - - if (mapRules.size() > 1) - { - bUsedYYAccept = true; - - if (gFlag && mapRules.size() >= cGotoThreshold) - { - o << indent(ind++) << "{\n"; + readCh = false; + } + + if (mapRules.size() > 1) + { + bUsedYYAccept = true; + + if (gFlag && mapRules.size() >= cGotoThreshold) + { + o << indent(ind++) << "{\n"; o << indent(ind++) << "static void *" << mapCodeName["yytarget"] << "[" << mapRules.size() << "] = {\n"; - for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it) - { + for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it) + { o << indent(ind) << "&&" << labelPrefix << it->second->label << ",\n"; - vUsedLabels.insert(it->second->label); - } - o << indent(--ind) << "};\n"; + vUsedLabels.insert(it->second->label); + } + o << indent(--ind) << "};\n"; o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << mapCodeName["yyaccept"] << "];\n"; - o << indent(--ind) << "}\n"; - } - else if (sFlag) - { - emitBinary(o, ind, 0, mapRules.size() - 1, readCh); - } - else - { + o << indent(--ind) << "}\n"; + } + else if (sFlag) + { + emitBinary(o, ind, 0, mapRules.size() - 1, readCh); + } + else + { o << indent(ind) << "switch(" << mapCodeName["yyaccept"] << ") {\n"; - - for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it) - { - o << indent(ind) << "case " << it->first << ": \t"; - genGoTo(o, 0, state, it->second, readCh); - } - - o << indent(ind) << "}\n"; - } - } - else - { - // no need to write if statement here since there is only case 0. - genGoTo(o, ind, state, mapRules.find(0)->second, readCh); - } - } -} - -Rule::Rule(State *s, RuleOp *r) : Action(s), rule(r) -{ - ; -} - -void Rule::emit(std::ostream &o, uint ind, bool &) const -{ - uint back = rule->ctx->fixedLength(); - - if (back != 0u) - { + + for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it) + { + o << indent(ind) << "case " << it->first << ": \t"; + genGoTo(o, 0, state, it->second, readCh); + } + + o << indent(ind) << "}\n"; + } + } + else + { + // no need to write if statement here since there is only case 0. + genGoTo(o, ind, state, mapRules.find(0)->second, readCh); + } + } +} + +Rule::Rule(State *s, RuleOp *r) : Action(s), rule(r) +{ + ; +} + +void Rule::emit(std::ostream &o, uint ind, bool &) const +{ + uint back = rule->ctx->fixedLength(); + + if (back != 0u) + { o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYCTXMARKER"] << ";\n"; - } - - RuleLine rl(*rule); - - o << file_info(sourceFileInfo, &rl); - o << indent(ind); - o << rule->code->text; - o << "\n"; - o << outputFileInfo; -} - -void doLinear(std::ostream &o, uint ind, Span *s, uint n, const State *from, const State *next, bool &readCh, uint mask) -{ - for (;;) - { - State *bg = s[0].to; - - while (n >= 3 && s[2].to == bg && (s[1].ub - s[0].ub) == 1) - { - if (s[1].to == next && n == 3) - { - if (!mask || (s[0].ub > 0x00FF)) - { - genIf(o, ind, "!=", s[0].ub, readCh); - genGoTo(o, 0, from, bg, readCh); - } - if (next->label != from->label + 1) - { - genGoTo(o, ind, from, next, readCh); - } - return ; - } - else - { - if (!mask || (s[0].ub > 0x00FF)) - { - genIf(o, ind, "==", s[0].ub, readCh); - genGoTo(o, 0, from, s[1].to, readCh); - } - } - - n -= 2; - s += 2; - } - - if (n == 1) - { - // if(bg != next){ - if (s[0].to->label != from->label + 1) - { - genGoTo(o, ind, from, s[0].to, readCh); - } - // } - return ; - } - else if (n == 2 && bg == next) - { - if (!mask || (s[0].ub > 0x00FF)) - { - genIf(o, ind, ">=", s[0].ub, readCh); - genGoTo(o, 0, from, s[1].to, readCh); - } - if (next->label != from->label + 1) - { - genGoTo(o, ind, from, next, readCh); - } - return ; - } - else - { - if (!mask || ((s[0].ub - 1) > 0x00FF)) - { - genIf(o, ind, "<=", s[0].ub - 1, readCh); - genGoTo(o, 0, from, bg, readCh); - } - n -= 1; - s += 1; - } - } - - if (next->label != from->label + 1) - { - genGoTo(o, ind, from, next, readCh); - } -} - -void Go::genLinear(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const -{ - doLinear(o, ind, span, nSpans, from, next, readCh, mask); -} - -bool genCases(std::ostream &o, uint ind, uint lb, Span *s, bool &newLine, uint mask) -{ - bool used = false; - - if (!newLine) - { - o << "\n"; - } - newLine = true; - if (lb < s->ub) - { - for (;;) - { - if (!mask || lb > 0x00FF) - { - o << indent(ind) << "case "; - prtChOrHex(o, lb); - o << ":"; - newLine = false; - used = true; - } - - if (++lb == s->ub) - { - break; - } - - o << "\n"; - newLine = true; - } - } - return used; -} - -void Go::genSwitch(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const -{ - bool newLine = true; - - if ((mask ? wSpans : nSpans) <= 2) - { - genLinear(o, ind, from, next, readCh, mask); - } - else - { - State *def = span[nSpans - 1].to; - Span **sP = new Span * [nSpans - 1], **r, **s, **t; - - t = &sP[0]; - - for (uint i = 0; i < nSpans; ++i) - { - if (span[i].to != def) - { - *(t++) = &span[i]; - } - } - - if (dFlag) - { + } + + RuleLine rl(*rule); + + o << file_info(sourceFileInfo, &rl); + o << indent(ind); + o << rule->code->text; + o << "\n"; + o << outputFileInfo; +} + +void doLinear(std::ostream &o, uint ind, Span *s, uint n, const State *from, const State *next, bool &readCh, uint mask) +{ + for (;;) + { + State *bg = s[0].to; + + while (n >= 3 && s[2].to == bg && (s[1].ub - s[0].ub) == 1) + { + if (s[1].to == next && n == 3) + { + if (!mask || (s[0].ub > 0x00FF)) + { + genIf(o, ind, "!=", s[0].ub, readCh); + genGoTo(o, 0, from, bg, readCh); + } + if (next->label != from->label + 1) + { + genGoTo(o, ind, from, next, readCh); + } + return ; + } + else + { + if (!mask || (s[0].ub > 0x00FF)) + { + genIf(o, ind, "==", s[0].ub, readCh); + genGoTo(o, 0, from, s[1].to, readCh); + } + } + + n -= 2; + s += 2; + } + + if (n == 1) + { + // if(bg != next){ + if (s[0].to->label != from->label + 1) + { + genGoTo(o, ind, from, s[0].to, readCh); + } + // } + return ; + } + else if (n == 2 && bg == next) + { + if (!mask || (s[0].ub > 0x00FF)) + { + genIf(o, ind, ">=", s[0].ub, readCh); + genGoTo(o, 0, from, s[1].to, readCh); + } + if (next->label != from->label + 1) + { + genGoTo(o, ind, from, next, readCh); + } + return ; + } + else + { + if (!mask || ((s[0].ub - 1) > 0x00FF)) + { + genIf(o, ind, "<=", s[0].ub - 1, readCh); + genGoTo(o, 0, from, bg, readCh); + } + n -= 1; + s += 1; + } + } + + if (next->label != from->label + 1) + { + genGoTo(o, ind, from, next, readCh); + } +} + +void Go::genLinear(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const +{ + doLinear(o, ind, span, nSpans, from, next, readCh, mask); +} + +bool genCases(std::ostream &o, uint ind, uint lb, Span *s, bool &newLine, uint mask) +{ + bool used = false; + + if (!newLine) + { + o << "\n"; + } + newLine = true; + if (lb < s->ub) + { + for (;;) + { + if (!mask || lb > 0x00FF) + { + o << indent(ind) << "case "; + prtChOrHex(o, lb); + o << ":"; + newLine = false; + used = true; + } + + if (++lb == s->ub) + { + break; + } + + o << "\n"; + newLine = true; + } + } + return used; +} + +void Go::genSwitch(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const +{ + bool newLine = true; + + if ((mask ? wSpans : nSpans) <= 2) + { + genLinear(o, ind, from, next, readCh, mask); + } + else + { + State *def = span[nSpans - 1].to; + Span **sP = new Span * [nSpans - 1], **r, **s, **t; + + t = &sP[0]; + + for (uint i = 0; i < nSpans; ++i) + { + if (span[i].to != def) + { + *(t++) = &span[i]; + } + } + + if (dFlag) + { o << indent(ind) << mapCodeName["YYDEBUG"] << "(-1, " << mapCodeName["yych"] << ");\n"; - } - - if (readCh) - { + } + + if (readCh) + { o << indent(ind) << "switch((" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")) {\n"; - readCh = false; - } - else - { + readCh = false; + } + else + { o << indent(ind) << "switch(" << mapCodeName["yych"] << ") {\n"; - } - - while (t != &sP[0]) - { - bool used = false; - - r = s = &sP[0]; - - if (*s == &span[0]) - { - used |= genCases(o, ind, 0, *s, newLine, mask); - } - else - { - used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask); - } - - State *to = (*s)->to; - - while (++s < t) - { - if ((*s)->to == to) - { - used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask); - } - else - { - *(r++) = *s; - } - } - - if (used) - { - genGoTo(o, newLine ? ind+1 : 1, from, to, readCh); - newLine = true; - } - t = r; - } - - o << indent(ind) << "default:"; - genGoTo(o, 1, from, def, readCh); - o << indent(ind) << "}\n"; - - delete [] sP; - } -} - -void doBinary(std::ostream &o, uint ind, Span *s, uint n, const State *from, const State *next, bool &readCh, uint mask) -{ - if (n <= 4) - { - doLinear(o, ind, s, n, from, next, readCh, mask); - } - else - { - uint h = n / 2; - - genIf(o, ind, "<=", s[h - 1].ub - 1, readCh); - o << "{\n"; - doBinary(o, ind+1, &s[0], h, from, next, readCh, mask); - o << indent(ind) << "} else {\n"; - doBinary(o, ind+1, &s[h], n - h, from, next, readCh, mask); - o << indent(ind) << "}\n"; - } -} - -void Go::genBinary(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const -{ - if (mask) - { - Span * sc = new Span[wSpans]; - - for (uint i = 0, j = 0; i < nSpans; i++) - { - if (span[i].ub > 0xFF) - { - sc[j++] = span[i]; - } - } - - doBinary(o, ind, sc, wSpans, from, next, readCh, mask); - - delete[] sc; - } - else - { - doBinary(o, ind, span, nSpans, from, next, readCh, mask); - } -} - -void Go::genBase(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const -{ - if ((mask ? wSpans : nSpans) == 0) - { - return ; - } - - if (!sFlag) - { - genSwitch(o, ind, from, next, readCh, mask); - return ; - } - - if ((mask ? wSpans : nSpans) > 8) - { - Span *bot = &span[0], *top = &span[nSpans - 1]; - uint util; - - if (bot[0].to == top[0].to) - { - util = (top[ -1].ub - bot[0].ub) / (nSpans - 2); - } - else - { - if (bot[0].ub > (top[0].ub - top[ -1].ub)) - { - util = (top[0].ub - bot[0].ub) / (nSpans - 1); - } - else - { - util = top[ -1].ub / (nSpans - 1); - } - } - - if (util <= 2) - { - genSwitch(o, ind, from, next, readCh, mask); - return ; - } - } - - if ((mask ? wSpans : nSpans) > 5) - { - genBinary(o, ind, from, next, readCh, mask); - } - else - { - genLinear(o, ind, from, next, readCh, mask); - } -} - -void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) const -{ + } + + while (t != &sP[0]) + { + bool used = false; + + r = s = &sP[0]; + + if (*s == &span[0]) + { + used |= genCases(o, ind, 0, *s, newLine, mask); + } + else + { + used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask); + } + + State *to = (*s)->to; + + while (++s < t) + { + if ((*s)->to == to) + { + used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask); + } + else + { + *(r++) = *s; + } + } + + if (used) + { + genGoTo(o, newLine ? ind+1 : 1, from, to, readCh); + newLine = true; + } + t = r; + } + + o << indent(ind) << "default:"; + genGoTo(o, 1, from, def, readCh); + o << indent(ind) << "}\n"; + + delete [] sP; + } +} + +void doBinary(std::ostream &o, uint ind, Span *s, uint n, const State *from, const State *next, bool &readCh, uint mask) +{ + if (n <= 4) + { + doLinear(o, ind, s, n, from, next, readCh, mask); + } + else + { + uint h = n / 2; + + genIf(o, ind, "<=", s[h - 1].ub - 1, readCh); + o << "{\n"; + doBinary(o, ind+1, &s[0], h, from, next, readCh, mask); + o << indent(ind) << "} else {\n"; + doBinary(o, ind+1, &s[h], n - h, from, next, readCh, mask); + o << indent(ind) << "}\n"; + } +} + +void Go::genBinary(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const +{ + if (mask) + { + Span * sc = new Span[wSpans]; + + for (uint i = 0, j = 0; i < nSpans; i++) + { + if (span[i].ub > 0xFF) + { + sc[j++] = span[i]; + } + } + + doBinary(o, ind, sc, wSpans, from, next, readCh, mask); + + delete[] sc; + } + else + { + doBinary(o, ind, span, nSpans, from, next, readCh, mask); + } +} + +void Go::genBase(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const +{ + if ((mask ? wSpans : nSpans) == 0) + { + return ; + } + + if (!sFlag) + { + genSwitch(o, ind, from, next, readCh, mask); + return ; + } + + if ((mask ? wSpans : nSpans) > 8) + { + Span *bot = &span[0], *top = &span[nSpans - 1]; + uint util; + + if (bot[0].to == top[0].to) + { + util = (top[ -1].ub - bot[0].ub) / (nSpans - 2); + } + else + { + if (bot[0].ub > (top[0].ub - top[ -1].ub)) + { + util = (top[0].ub - bot[0].ub) / (nSpans - 1); + } + else + { + util = top[ -1].ub / (nSpans - 1); + } + } + + if (util <= 2) + { + genSwitch(o, ind, from, next, readCh, mask); + return ; + } + } + + if ((mask ? wSpans : nSpans) > 5) + { + genBinary(o, ind, from, next, readCh, mask); + } + else + { + genLinear(o, ind, from, next, readCh, mask); + } +} + +void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) const +{ std::string sYych; if (readCh) @@ -905,116 +905,116 @@ void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *ne { sYych = mapCodeName["yych"]; } - - readCh = false; - if (wFlag) - { - o << indent(ind) << "if(" << sYych <<" & ~0xFF) {\n"; - genBase(o, ind+1, from, next, readCh, 1); - o << indent(ind++) << "} else {\n"; - sYych = mapCodeName["yych"]; - } - else - { - o << indent(ind++) << "{\n"; - } + + readCh = false; + if (wFlag) + { + o << indent(ind) << "if(" << sYych <<" & ~0xFF) {\n"; + genBase(o, ind+1, from, next, readCh, 1); + o << indent(ind++) << "} else {\n"; + sYych = mapCodeName["yych"]; + } + else + { + o << indent(ind++) << "{\n"; + } o << indent(ind++) << "static void *" << mapCodeName["yytarget"] << "[256] = {\n"; - o << indent(ind); - - uint ch = 0; - for (uint i = 0; i < lSpans; ++i) - { - vUsedLabels.insert(span[i].to->label); - for(; ch < span[i].ub; ++ch) - { + o << indent(ind); + + uint ch = 0; + for (uint i = 0; i < lSpans; ++i) + { + vUsedLabels.insert(span[i].to->label); + for(; ch < span[i].ub; ++ch) + { o << "&&" << labelPrefix << span[i].to->label; - if (ch == 255) - { - o << "\n"; - i = lSpans; - break; - } - else if (ch % 8 == 7) - { - o << ",\n" << indent(ind); - } - else - { - o << "," << space(span[i].to->label); - } - } - } - o << indent(--ind) << "};\n"; + if (ch == 255) + { + o << "\n"; + i = lSpans; + break; + } + else if (ch % 8 == 7) + { + o << ",\n" << indent(ind); + } + else + { + o << "," << space(span[i].to->label); + } + } + } + o << indent(--ind) << "};\n"; o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << sYych << "];\n"; - o << indent(--ind) << "}\n"; -} - -void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) -{ - if ((gFlag || wFlag) && wSpans == ~0u) - { - uint nBitmaps = 0; - std::set vTargets; - wSpans = 0; - lSpans = 1; - dSpans = 0; - for (uint i = 0; i < nSpans; ++i) - { - if (span[i].ub > 0xFF) - { - wSpans++; - } - if (span[i].ub < 0x100 || !wFlag) - { - lSpans++; - - State *to = span[i].to; - - if (to && to->isBase) - { - const BitMap *b = BitMap::find(to); - - if (b && matches(b->go, b->on, this, to)) - { - nBitmaps++; - } - else - { - dSpans++; - vTargets.insert(to->label); - } - } - else - { - dSpans++; - vTargets.insert(to->label); - } - } - } - lTargets = vTargets.size() >> nBitmaps; - } - - if (gFlag && (lTargets >= cGotoThreshold || dSpans >= cGotoThreshold)) - { - genCpGoto(o, ind, from, next, readCh); - return; - } - else if (bFlag) - { - for (uint i = 0; i < nSpans; ++i) - { - State *to = span[i].to; - - if (to && to->isBase) - { - const BitMap *b = BitMap::find(to); - std::string sYych; - - if (b && matches(b->go, b->on, this, to)) - { - Go go; - go.span = new Span[nSpans]; - go.unmap(this, to); + o << indent(--ind) << "}\n"; +} + +void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) +{ + if ((gFlag || wFlag) && wSpans == ~0u) + { + uint nBitmaps = 0; + std::set vTargets; + wSpans = 0; + lSpans = 1; + dSpans = 0; + for (uint i = 0; i < nSpans; ++i) + { + if (span[i].ub > 0xFF) + { + wSpans++; + } + if (span[i].ub < 0x100 || !wFlag) + { + lSpans++; + + State *to = span[i].to; + + if (to && to->isBase) + { + const BitMap *b = BitMap::find(to); + + if (b && matches(b->go, b->on, this, to)) + { + nBitmaps++; + } + else + { + dSpans++; + vTargets.insert(to->label); + } + } + else + { + dSpans++; + vTargets.insert(to->label); + } + } + } + lTargets = vTargets.size() >> nBitmaps; + } + + if (gFlag && (lTargets >= cGotoThreshold || dSpans >= cGotoThreshold)) + { + genCpGoto(o, ind, from, next, readCh); + return; + } + else if (bFlag) + { + for (uint i = 0; i < nSpans; ++i) + { + State *to = span[i].to; + + if (to && to->isBase) + { + const BitMap *b = BitMap::find(to); + std::string sYych; + + if (b && matches(b->go, b->on, this, to)) + { + Go go; + go.span = new Span[nSpans]; + go.unmap(this, to); if (readCh) { sYych = "(" + mapCodeName["yych"] + " = " + yychConversion + "*" + mapCodeName["YYCURSOR"] + ")"; @@ -1023,683 +1023,683 @@ void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next { sYych = mapCodeName["yych"]; } - readCh = false; - if (wFlag) - { + readCh = false; + if (wFlag) + { o << indent(ind) << "if(" << sYych << " & ~0xFF) {\n"; sYych = mapCodeName["yych"]; - genBase(o, ind+1, from, next, readCh, 1); - o << indent(ind) << "} else "; - } - else - { - o << indent(ind); - } + genBase(o, ind+1, from, next, readCh, 1); + o << indent(ind) << "} else "; + } + else + { + o << indent(ind); + } o << "if(" << mapCodeName["yybm"] << "[" << b->i << "+" << sYych << "] & "; - if (yybmHexTable) - { - prtHex(o, b->m, false); - } - else - { - o << (uint) b->m; - } - o << ") {\n"; - genGoTo(o, ind+1, from, to, readCh); - o << indent(ind) << "}\n"; - go.genBase(o, ind, from, next, readCh, 0); - delete [] go.span; - return ; - } - } - } - } - - genBase(o, ind, from, next, readCh, 0); -} - -void State::emit(std::ostream &o, uint ind, bool &readCh) const -{ - if (vUsedLabels.count(label)) - { + if (yybmHexTable) + { + prtHex(o, b->m, false); + } + else + { + o << (uint) b->m; + } + o << ") {\n"; + genGoTo(o, ind+1, from, to, readCh); + o << indent(ind) << "}\n"; + go.genBase(o, ind, from, next, readCh, 0); + delete [] go.span; + return ; + } + } + } + } + + genBase(o, ind, from, next, readCh, 0); +} + +void State::emit(std::ostream &o, uint ind, bool &readCh) const +{ + if (vUsedLabels.count(label)) + { o << labelPrefix << label << ":\n"; - } - if (dFlag && !action->isInitial()) - { + } + if (dFlag && !action->isInitial()) + { o << indent(ind) << mapCodeName["YYDEBUG"] << "(" << label << ", *" << mapCodeName["YYCURSOR"] << ");\n"; - } - if (isPreCtxt) - { + } + if (isPreCtxt) + { o << indent(ind) << mapCodeName["YYCTXMARKER"] << " = " << mapCodeName["YYCURSOR"] << " + 1;\n"; - } - action->emit(o, ind, readCh); -} - -uint merge(Span *x0, State *fg, State *bg) -{ - Span *x = x0, *f = fg->go.span, *b = bg->go.span; - uint nf = fg->go.nSpans, nb = bg->go.nSpans; - State *prev = NULL, *to; - // NB: we assume both spans are for same range - - for (;;) - { - if (f->ub == b->ub) - { - to = f->to == b->to ? bg : f->to; - - if (to == prev) - { - --x; - } - else - { - x->to = prev = to; - } - - x->ub = f->ub; - ++x; - ++f; - --nf; - ++b; - --nb; - - if (nf == 0 && nb == 0) - { - return x - x0; - } - } - - while (f->ub < b->ub) - { - to = f->to == b->to ? bg : f->to; - - if (to == prev) - { - --x; - } - else - { - x->to = prev = to; - } - - x->ub = f->ub; - ++x; - ++f; - --nf; - } - - while (b->ub < f->ub) - { - to = b->to == f->to ? bg : f->to; - - if (to == prev) - { - --x; - } - else - { - x->to = prev = to; - } - - x->ub = b->ub; - ++x; - ++b; - --nb; - } - } -} - -const uint cInfinity = ~0; - -class SCC -{ - -public: - State **top, **stk; - -public: - SCC(uint); - ~SCC(); - void traverse(State*); - -#ifdef PEDANTIC -private: - SCC(const SCC& oth) - : top(oth.top) - , stk(oth.stk) - { - } - SCC& operator = (const SCC& oth) - { - new(this) SCC(oth); - return *this; - } -#endif -}; - -SCC::SCC(uint size) - : top(new State * [size]) - , stk(top) -{ -} - -SCC::~SCC() -{ - delete [] stk; -} - -void SCC::traverse(State *x) -{ - *top = x; - uint k = ++top - stk; - x->depth = k; - - for (uint i = 0; i < x->go.nSpans; ++i) - { - State *y = x->go.span[i].to; - - if (y) - { - if (y->depth == 0) - { - traverse(y); - } - - if (y->depth < x->depth) - { - x->depth = y->depth; - } - } - } - - if (x->depth == k) - { - do - { - (*--top)->depth = cInfinity; - (*top)->link = x; - } - while (*top != x); - } -} - -static bool state_is_in_non_trivial_SCC(const State* s) -{ - - // does not link to self - if (s->link != s) - { - return true; - } - - // or exists i: (s->go.spans[i].to->link == s) - // - // Note: (s->go.spans[i].to == s) is allowed, corresponds to s - // looping back to itself. - // - for (uint i = 0; i < s->go.nSpans; ++i) - { - const State* t = s->go.span[i].to; - - if (t && t->link == s) - { - return true; - } - } - // otherwise no - return false; -} - -uint maxDist(State *s) -{ - if (s->depth != cInfinity) - { - // Already calculated, just return result. - return s->depth; - } - uint mm = 0; - - for (uint i = 0; i < s->go.nSpans; ++i) - { - State *t = s->go.span[i].to; - - if (t) - { - uint m = 1; - - if (!t->link) // marked as non-key state - { - if (t->depth == cInfinity) - { - t->depth = maxDist(t); - } - m += t->depth; - } - - if (m > mm) - { - mm = m; - } - } - } - - s->depth = mm; - return mm; -} - -void calcDepth(State *head) -{ - State* s; - - // mark non-key states by s->link = NULL ; - for (s = head; s; s = s->next) - { - if (s != head && !state_is_in_non_trivial_SCC(s)) - { - s->link = NULL; - } - //else: key state, leave alone - } - - for (s = head; s; s = s->next) - { - s->depth = cInfinity; - } - - // calculate max number of transitions before guarantied to reach - // a key state. - for (s = head; s; s = s->next) - { - maxDist(s); - } -} - -void DFA::findSCCs() -{ - SCC scc(nStates); - State *s; - - for (s = head; s; s = s->next) - { - s->depth = 0; - s->link = NULL; - } - - for (s = head; s; s = s->next) - { - if (!s->depth) - { - scc.traverse(s); - } - } - - calcDepth(head); -} - -void DFA::split(State *s) -{ - State *move = new State; - (void) new Move(move); - addState(&s->next, move); - move->link = s->link; - move->rule = s->rule; - move->go = s->go; - s->rule = NULL; - s->go.nSpans = 1; - s->go.span = new Span[1]; - s->go.span[0].ub = ubChar; - s->go.span[0].to = move; -} - -void DFA::findBaseState() -{ - Span *span = new Span[ubChar - lbChar]; - - for (State *s = head; s; s = s->next) - { - if (!s->link) - { - for (uint i = 0; i < s->go.nSpans; ++i) - { - State *to = s->go.span[i].to; - - if (to && to->isBase) - { - to = to->go.span[0].to; - uint nSpans = merge(span, s, to); - - if (nSpans < s->go.nSpans) - { - delete [] s->go.span; - s->go.nSpans = nSpans; - s->go.span = new Span[nSpans]; - memcpy(s->go.span, span, nSpans*sizeof(Span)); - } - - break; - } - } - } - } - - delete [] span; -} - -void DFA::emit(std::ostream &o, uint ind) -{ - State *s; - uint i, bitmap_brace = 0; - - findSCCs(); - head->link = head; - - uint nRules = 0; - - for (s = head; s; s = s->next) - { - s->depth = maxDist(s); - if (maxFill < s->depth) - { - maxFill = s->depth; - } - if (s->rule && s->rule->accept >= nRules) - { - nRules = s->rule->accept + 1; - } - } - - uint nSaves = 0; - uint *saves = new uint[nRules]; - memset(saves, ~0, (nRules)*sizeof(*saves)); - - // mark backtracking points - bool bSaveOnHead = false; - - for (s = head; s; s = s->next) - { - if (s->rule) - { - for (i = 0; i < s->go.nSpans; ++i) - { - if (s->go.span[i].to && !s->go.span[i].to->rule) - { - delete s->action; - s->action = NULL; - - if (saves[s->rule->accept] == ~0u) - { - saves[s->rule->accept] = nSaves++; - } - - bSaveOnHead |= s == head; - (void) new Save(s, saves[s->rule->accept]); // sets s->action - } - } - } - } - - // insert actions - State **rules = new State * [nRules]; - - memset(rules, 0, (nRules)*sizeof(*rules)); - - State *accept = NULL; - Accept *accfixup = NULL; - - for (s = head; s; s = s->next) - { - State * ow; - - if (!s->rule) - { - ow = accept; - } - else - { - if (!rules[s->rule->accept]) - { - State *n = new State; - (void) new Rule(n, s->rule); - rules[s->rule->accept] = n; - addState(&s->next, n); - } - - ow = rules[s->rule->accept]; - } - - for (i = 0; i < s->go.nSpans; ++i) - { - if (!s->go.span[i].to) - { - if (!ow) - { - ow = accept = new State; - accfixup = new Accept(accept, nRules, saves, rules); - addState(&s->next, accept); - } - - s->go.span[i].to = ow; - } - } - } - - if (accfixup) - { - accfixup->genRuleMap(); - } - - // split ``base'' states into two parts - for (s = head; s; s = s->next) - { - s->isBase = false; - - if (s->link) - { - for (i = 0; i < s->go.nSpans; ++i) - { - if (s->go.span[i].to == s) - { - s->isBase = true; - split(s); - - if (bFlag) - { - BitMap::find(&s->next->go, s); - } - - s = s->next; - break; - } - } - } - } - - // find ``base'' state, if possible - findBaseState(); - - delete head->action; - head->action = NULL; - - if (bFlag) - { - o << indent(ind++) << "{\n"; - bitmap_brace = 1; - BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256); - } - - bUsedYYAccept = false; - - uint start_label = next_label; - - (void) new Initial(head, next_label++, bSaveOnHead); - - if (bUseStartLabel) - { - if (startLabelName.empty()) - { - vUsedLabels.insert(start_label); - } - } - - for (s = head; s; s = s->next) - { - s->label = next_label++; - } - - // Save 'next_fill_index' and compute information about code generation - // while writing to null device. - uint save_fill_index = next_fill_index; - null_stream null_dev; - - for (s = head; s; s = s->next) - { - bool readCh = false; - s->emit(null_dev, ind, readCh); - s->go.genGoto(null_dev, ind, s, s->next, readCh); - } - if (last_fill_index < next_fill_index) - { - last_fill_index = next_fill_index; - } - next_fill_index = save_fill_index; - - // Generate prolog - o << "\n" << outputFileInfo; - o << indent(ind++) << "{\n"; - - if (!fFlag) - { + } + action->emit(o, ind, readCh); +} + +uint merge(Span *x0, State *fg, State *bg) +{ + Span *x = x0, *f = fg->go.span, *b = bg->go.span; + uint nf = fg->go.nSpans, nb = bg->go.nSpans; + State *prev = NULL, *to; + // NB: we assume both spans are for same range + + for (;;) + { + if (f->ub == b->ub) + { + to = f->to == b->to ? bg : f->to; + + if (to == prev) + { + --x; + } + else + { + x->to = prev = to; + } + + x->ub = f->ub; + ++x; + ++f; + --nf; + ++b; + --nb; + + if (nf == 0 && nb == 0) + { + return x - x0; + } + } + + while (f->ub < b->ub) + { + to = f->to == b->to ? bg : f->to; + + if (to == prev) + { + --x; + } + else + { + x->to = prev = to; + } + + x->ub = f->ub; + ++x; + ++f; + --nf; + } + + while (b->ub < f->ub) + { + to = b->to == f->to ? bg : f->to; + + if (to == prev) + { + --x; + } + else + { + x->to = prev = to; + } + + x->ub = b->ub; + ++x; + ++b; + --nb; + } + } +} + +const uint cInfinity = ~0; + +class SCC +{ + +public: + State **top, **stk; + +public: + SCC(uint); + ~SCC(); + void traverse(State*); + +#ifdef PEDANTIC +private: + SCC(const SCC& oth) + : top(oth.top) + , stk(oth.stk) + { + } + SCC& operator = (const SCC& oth) + { + new(this) SCC(oth); + return *this; + } +#endif +}; + +SCC::SCC(uint size) + : top(new State * [size]) + , stk(top) +{ +} + +SCC::~SCC() +{ + delete [] stk; +} + +void SCC::traverse(State *x) +{ + *top = x; + uint k = ++top - stk; + x->depth = k; + + for (uint i = 0; i < x->go.nSpans; ++i) + { + State *y = x->go.span[i].to; + + if (y) + { + if (y->depth == 0) + { + traverse(y); + } + + if (y->depth < x->depth) + { + x->depth = y->depth; + } + } + } + + if (x->depth == k) + { + do + { + (*--top)->depth = cInfinity; + (*top)->link = x; + } + while (*top != x); + } +} + +static bool state_is_in_non_trivial_SCC(const State* s) +{ + + // does not link to self + if (s->link != s) + { + return true; + } + + // or exists i: (s->go.spans[i].to->link == s) + // + // Note: (s->go.spans[i].to == s) is allowed, corresponds to s + // looping back to itself. + // + for (uint i = 0; i < s->go.nSpans; ++i) + { + const State* t = s->go.span[i].to; + + if (t && t->link == s) + { + return true; + } + } + // otherwise no + return false; +} + +uint maxDist(State *s) +{ + if (s->depth != cInfinity) + { + // Already calculated, just return result. + return s->depth; + } + uint mm = 0; + + for (uint i = 0; i < s->go.nSpans; ++i) + { + State *t = s->go.span[i].to; + + if (t) + { + uint m = 1; + + if (!t->link) // marked as non-key state + { + if (t->depth == cInfinity) + { + t->depth = maxDist(t); + } + m += t->depth; + } + + if (m > mm) + { + mm = m; + } + } + } + + s->depth = mm; + return mm; +} + +void calcDepth(State *head) +{ + State* s; + + // mark non-key states by s->link = NULL ; + for (s = head; s; s = s->next) + { + if (s != head && !state_is_in_non_trivial_SCC(s)) + { + s->link = NULL; + } + //else: key state, leave alone + } + + for (s = head; s; s = s->next) + { + s->depth = cInfinity; + } + + // calculate max number of transitions before guarantied to reach + // a key state. + for (s = head; s; s = s->next) + { + maxDist(s); + } +} + +void DFA::findSCCs() +{ + SCC scc(nStates); + State *s; + + for (s = head; s; s = s->next) + { + s->depth = 0; + s->link = NULL; + } + + for (s = head; s; s = s->next) + { + if (!s->depth) + { + scc.traverse(s); + } + } + + calcDepth(head); +} + +void DFA::split(State *s) +{ + State *move = new State; + (void) new Move(move); + addState(&s->next, move); + move->link = s->link; + move->rule = s->rule; + move->go = s->go; + s->rule = NULL; + s->go.nSpans = 1; + s->go.span = new Span[1]; + s->go.span[0].ub = ubChar; + s->go.span[0].to = move; +} + +void DFA::findBaseState() +{ + Span *span = new Span[ubChar - lbChar]; + + for (State *s = head; s; s = s->next) + { + if (!s->link) + { + for (uint i = 0; i < s->go.nSpans; ++i) + { + State *to = s->go.span[i].to; + + if (to && to->isBase) + { + to = to->go.span[0].to; + uint nSpans = merge(span, s, to); + + if (nSpans < s->go.nSpans) + { + delete [] s->go.span; + s->go.nSpans = nSpans; + s->go.span = new Span[nSpans]; + memcpy(s->go.span, span, nSpans*sizeof(Span)); + } + + break; + } + } + } + } + + delete [] span; +} + +void DFA::emit(std::ostream &o, uint ind) +{ + State *s; + uint i, bitmap_brace = 0; + + findSCCs(); + head->link = head; + + uint nRules = 0; + + for (s = head; s; s = s->next) + { + s->depth = maxDist(s); + if (maxFill < s->depth) + { + maxFill = s->depth; + } + if (s->rule && s->rule->accept >= nRules) + { + nRules = s->rule->accept + 1; + } + } + + uint nSaves = 0; + uint *saves = new uint[nRules]; + memset(saves, ~0, (nRules)*sizeof(*saves)); + + // mark backtracking points + bool bSaveOnHead = false; + + for (s = head; s; s = s->next) + { + if (s->rule) + { + for (i = 0; i < s->go.nSpans; ++i) + { + if (s->go.span[i].to && !s->go.span[i].to->rule) + { + delete s->action; + s->action = NULL; + + if (saves[s->rule->accept] == ~0u) + { + saves[s->rule->accept] = nSaves++; + } + + bSaveOnHead |= s == head; + (void) new Save(s, saves[s->rule->accept]); // sets s->action + } + } + } + } + + // insert actions + State **rules = new State * [nRules]; + + memset(rules, 0, (nRules)*sizeof(*rules)); + + State *accept = NULL; + Accept *accfixup = NULL; + + for (s = head; s; s = s->next) + { + State * ow; + + if (!s->rule) + { + ow = accept; + } + else + { + if (!rules[s->rule->accept]) + { + State *n = new State; + (void) new Rule(n, s->rule); + rules[s->rule->accept] = n; + addState(&s->next, n); + } + + ow = rules[s->rule->accept]; + } + + for (i = 0; i < s->go.nSpans; ++i) + { + if (!s->go.span[i].to) + { + if (!ow) + { + ow = accept = new State; + accfixup = new Accept(accept, nRules, saves, rules); + addState(&s->next, accept); + } + + s->go.span[i].to = ow; + } + } + } + + if (accfixup) + { + accfixup->genRuleMap(); + } + + // split ``base'' states into two parts + for (s = head; s; s = s->next) + { + s->isBase = false; + + if (s->link) + { + for (i = 0; i < s->go.nSpans; ++i) + { + if (s->go.span[i].to == s) + { + s->isBase = true; + split(s); + + if (bFlag) + { + BitMap::find(&s->next->go, s); + } + + s = s->next; + break; + } + } + } + } + + // find ``base'' state, if possible + findBaseState(); + + delete head->action; + head->action = NULL; + + if (bFlag) + { + o << indent(ind++) << "{\n"; + bitmap_brace = 1; + BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256); + } + + bUsedYYAccept = false; + + uint start_label = next_label; + + (void) new Initial(head, next_label++, bSaveOnHead); + + if (bUseStartLabel) + { + if (startLabelName.empty()) + { + vUsedLabels.insert(start_label); + } + } + + for (s = head; s; s = s->next) + { + s->label = next_label++; + } + + // Save 'next_fill_index' and compute information about code generation + // while writing to null device. + uint save_fill_index = next_fill_index; + null_stream null_dev; + + for (s = head; s; s = s->next) + { + bool readCh = false; + s->emit(null_dev, ind, readCh); + s->go.genGoto(null_dev, ind, s, s->next, readCh); + } + if (last_fill_index < next_fill_index) + { + last_fill_index = next_fill_index; + } + next_fill_index = save_fill_index; + + // Generate prolog + o << "\n" << outputFileInfo; + o << indent(ind++) << "{\n"; + + if (!fFlag) + { o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n"; - if (bUsedYYAccept) - { + if (bUsedYYAccept) + { o << indent(ind) << "unsigned int "<< mapCodeName["yyaccept"] << " = 0;\n"; - } - } - else - { - o << "\n"; - } - - genGetState(o, ind, start_label); - - if (vUsedLabels.count(1)) - { - vUsedLabels.insert(0); + } + } + else + { + o << "\n"; + } + + genGetState(o, ind, start_label); + + if (vUsedLabels.count(1)) + { + vUsedLabels.insert(0); o << indent(ind) << "goto " << labelPrefix << "0;\n"; - } - - // Generate code - for (s = head; s; s = s->next) - { - bool readCh = false; - s->emit(o, ind, readCh); - s->go.genGoto(o, ind, s, s->next, readCh); - } - - // Generate epilog - o << indent(--ind) << "}\n"; - if (bitmap_brace) - { - o << indent(--ind) << "}\n"; - } - - // Cleanup - if (BitMap::first) - { - delete BitMap::first; - BitMap::first = NULL; - } - - delete [] saves; - delete [] rules; - - bUseStartLabel = false; -} - -void genGetState(std::ostream &o, uint& ind, uint start_label) -{ - if (fFlag && !bWroteGetState) - { - vUsedLabels.insert(start_label); + } + + // Generate code + for (s = head; s; s = s->next) + { + bool readCh = false; + s->emit(o, ind, readCh); + s->go.genGoto(o, ind, s, s->next, readCh); + } + + // Generate epilog + o << indent(--ind) << "}\n"; + if (bitmap_brace) + { + o << indent(--ind) << "}\n"; + } + + // Cleanup + if (BitMap::first) + { + delete BitMap::first; + BitMap::first = NULL; + } + + delete [] saves; + delete [] rules; + + bUseStartLabel = false; +} + +void genGetState(std::ostream &o, uint& ind, uint start_label) +{ + if (fFlag && !bWroteGetState) + { + vUsedLabels.insert(start_label); o << indent(ind) << "switch(" << mapCodeName["YYGETSTATE"] << "()) {\n"; - if (bUseStateAbort) - { - o << indent(ind) << "default: abort();\n"; + if (bUseStateAbort) + { + o << indent(ind) << "default: abort();\n"; o << indent(ind) << "case -1: goto " << labelPrefix << start_label << ";\n"; - } - else - { + } + else + { o << indent(ind) << "default: goto " << labelPrefix << start_label << ";\n"; - } - - for (size_t i=0; iget_line() << " \"" << li.fname << "\"\n"; - } - return o; -} - -uint Scanner::get_line() const -{ - return cline; -} - -void Scanner::config(const Str& cfg, int num) -{ - if (cfg.to_string() == "indent:top") - { - if (num < 0) - { - fatal("configuration 'indent:top' must be a positive integer"); - } - topIndent = num; - } - else if (cfg.to_string() == "yybm:hex") - { - yybmHexTable = num != 0; - } - else if (cfg.to_string() == "startlabel") - { - bUseStartLabel = num != 0; - startLabelName = ""; - } - else if (cfg.to_string() == "state:abort") - { - bUseStateAbort = num != 0; - } - else if (cfg.to_string() == "state:nextlabel") - { - bUseStateNext = num != 0; - } - else if (cfg.to_string() == "yyfill:enable") - { - bUseYYFill = num != 0; - } + } + bWroteGetState = true; + } +} + +std::ostream& operator << (std::ostream& o, const file_info& li) +{ + if (li.ln && !iFlag) + { + o << "#line " << li.ln->get_line() << " \"" << li.fname << "\"\n"; + } + return o; +} + +uint Scanner::get_line() const +{ + return cline; +} + +void Scanner::config(const Str& cfg, int num) +{ + if (cfg.to_string() == "indent:top") + { + if (num < 0) + { + fatal("configuration 'indent:top' must be a positive integer"); + } + topIndent = num; + } + else if (cfg.to_string() == "yybm:hex") + { + yybmHexTable = num != 0; + } + else if (cfg.to_string() == "startlabel") + { + bUseStartLabel = num != 0; + startLabelName = ""; + } + else if (cfg.to_string() == "state:abort") + { + bUseStateAbort = num != 0; + } + else if (cfg.to_string() == "state:nextlabel") + { + bUseStateNext = num != 0; + } + else if (cfg.to_string() == "yyfill:enable") + { + bUseYYFill = num != 0; + } else if (cfg.to_string() == "yyfill:parameter") { bUseYYFillParam = num != 0; } - else if (cfg.to_string() == "cgoto:threshold") - { - cGotoThreshold = num; - } + else if (cfg.to_string() == "cgoto:threshold") + { + cGotoThreshold = num; + } else if (cfg.to_string() == "yych:conversion") { if (num) @@ -1713,18 +1713,18 @@ void Scanner::config(const Str& cfg, int num) yychConversion = ""; } } - else - { - fatal("unrecognized configuration name or illegal integer value"); - } -} - + else + { + fatal("unrecognized configuration name or illegal integer value"); + } +} + static std::set mapVariableKeys; static std::set mapDefineKeys; static std::set mapLabelKeys; -void Scanner::config(const Str& cfg, const Str& val) -{ +void Scanner::config(const Str& cfg, const Str& val) +{ if (mapDefineKeys.empty()) { mapVariableKeys.insert("variable:yyaccept"); @@ -1757,15 +1757,15 @@ void Scanner::config(const Str& cfg, const Str& val) strVal = val.to_string(); } - if (cfg.to_string() == "indent:string") - { - indString = strVal; - } - else if (cfg.to_string() == "startlabel") - { - startLabelName = val.to_string(); - bUseStartLabel = !startLabelName.empty(); - } + if (cfg.to_string() == "indent:string") + { + indString = strVal; + } + else if (cfg.to_string() == "startlabel") + { + startLabelName = strVal; + bUseStartLabel = !startLabelName.empty(); + } else if (cfg.to_string() == "labelprefix") { labelPrefix = strVal; @@ -1797,10 +1797,10 @@ void Scanner::config(const Str& cfg, const Str& val) fatal("label already being used and cannot be changed"); } } - else - { - fatal("unrecognized configuration name or illegal string value"); - } -} - -} // end namespace re2c + else + { + fatal("unrecognized configuration name or illegal string value"); + } +} + +} // end namespace re2c diff --git a/tools/re2c/code.h b/tools/re2c/code.h index 5f2e551231..ed9df0dde7 100644 --- a/tools/re2c/code.h +++ b/tools/re2c/code.h @@ -1,4 +1,4 @@ -/* $Id: code.h,v 1.7 2006/01/21 15:51:02 helly Exp $ */ +/* $Id: code.h 525 2006-05-25 13:32:49Z helly $ */ #ifndef _code_h #define _code_h diff --git a/tools/re2c/dfa.h b/tools/re2c/dfa.h index e5ac5f4e99..fac2fe21cf 100644 --- a/tools/re2c/dfa.h +++ b/tools/re2c/dfa.h @@ -1,4 +1,4 @@ -/* $Id: dfa.h,v 1.23 2006/05/14 13:38:26 helly Exp $ */ +/* $Id: dfa.h 569 2006-06-05 22:14:00Z helly $ */ #ifndef _dfa_h #define _dfa_h diff --git a/tools/re2c/globals.h b/tools/re2c/globals.h index b9cc10e163..341d0aac30 100644 --- a/tools/re2c/globals.h +++ b/tools/re2c/globals.h @@ -1,4 +1,4 @@ -/* $Id: globals.h,v 1.31 2006/05/14 13:38:26 helly Exp $ */ +/* $Id: globals.h 713 2007-04-29 15:33:47Z helly $ */ #ifndef _globals_h #define _globals_h diff --git a/tools/re2c/ins.h b/tools/re2c/ins.h index 0132738591..a2e379585f 100644 --- a/tools/re2c/ins.h +++ b/tools/re2c/ins.h @@ -1,4 +1,4 @@ -/* $Id: ins.h,v 1.7 2006/01/03 11:40:38 helly Exp $ */ +/* $Id: ins.h 535 2006-05-25 13:36:14Z helly $ */ #ifndef _ins_h #define _ins_h diff --git a/tools/re2c/main.cc b/tools/re2c/main.cc index 966d7e5ad4..1116b9772c 100644 --- a/tools/re2c/main.cc +++ b/tools/re2c/main.cc @@ -1,4 +1,4 @@ -/* $Id: main.cc,v 1.53 2006/05/14 13:38:26 helly Exp $ */ +/* $Id: main.cc 691 2007-04-22 15:07:39Z helly $ */ #ifdef HAVE_CONFIG_H #include "config.h" #elif defined(_WIN32) @@ -139,7 +139,7 @@ static void usage() " with -f and disables YYMAXFILL generation prior to last\n" " re2c block.\n" "\n" - "--no-generation-date Suppress the date output in the generated output so that it\n" + "--no-generation-date Suppress date output in the generated output so that it\n" " only shows the re2c version.\n" ; } diff --git a/tools/re2c/mbo_getopt.cc b/tools/re2c/mbo_getopt.cc index 8c33332f39..6376279267 100644 --- a/tools/re2c/mbo_getopt.cc +++ b/tools/re2c/mbo_getopt.cc @@ -2,7 +2,7 @@ Author: Marcus Boerger */ -/* $Id: mbo_getopt.cc,v 1.5 2006/04/17 19:28:47 helly Exp $ */ +/* $Id: mbo_getopt.cc 698 2007-04-23 21:06:56Z helly $ */ #include #include diff --git a/tools/re2c/mbo_getopt.h b/tools/re2c/mbo_getopt.h index f38b7ab5ea..ca72f0db72 100644 --- a/tools/re2c/mbo_getopt.h +++ b/tools/re2c/mbo_getopt.h @@ -2,7 +2,7 @@ Author: Marcus Boerger */ -/* $Id: mbo_getopt.h,v 1.5 2006/04/17 19:28:47 helly Exp $ */ +/* $Id: mbo_getopt.h 539 2006-05-25 13:37:38Z helly $ */ /* Define structure for one recognized option (both single char and long name). * If short_open is '-' this is the last option. diff --git a/tools/re2c/parser.cc b/tools/re2c/parser.cc index 7cbf7a8032..ad1bf74ece 100644 --- a/tools/re2c/parser.cc +++ b/tools/re2c/parser.cc @@ -95,7 +95,7 @@ #line 1 "./parser.y" -/* $Id: parser.y,v 1.20 2006/04/16 15:15:46 helly Exp $ */ +/* $Id: parser.y 674 2007-04-16 21:39:11Z helly $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/tools/re2c/parser.h b/tools/re2c/parser.h index 1f367c58da..642d6db4ec 100644 --- a/tools/re2c/parser.h +++ b/tools/re2c/parser.h @@ -1,4 +1,4 @@ -/* $Id: parser.h,v 1.10 2006/01/21 15:51:02 helly Exp $ */ +/* $Id: parser.h 565 2006-06-05 22:07:13Z helly $ */ #ifndef _parser_h #define _parser_h diff --git a/tools/re2c/parser.y b/tools/re2c/parser.y index fa6e267a71..0164c45fea 100644 --- a/tools/re2c/parser.y +++ b/tools/re2c/parser.y @@ -1,6 +1,6 @@ %{ -/* $Id: parser.y,v 1.20 2006/04/16 15:15:46 helly Exp $ */ +/* $Id: parser.y 674 2007-04-16 21:39:11Z helly $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/tools/re2c/re.h b/tools/re2c/re.h index 2dd652bfc5..f17bdff7c6 100644 --- a/tools/re2c/re.h +++ b/tools/re2c/re.h @@ -1,16 +1,16 @@ -/* $Id: re.h,v 1.17 2006/04/09 00:06:33 helly Exp $ */ -#ifndef _re_h -#define _re_h - -#include -#include -#include "token.h" -#include "ins.h" -#include "globals.h" - -namespace re2c -{ - +/* $Id: re.h 775 2007-07-10 19:33:17Z helly $ */ +#ifndef _re_h +#define _re_h + +#include +#include +#include "token.h" +#include "ins.h" +#include "globals.h" + +namespace re2c +{ + template class free_list: protected std::set<_Ty> { @@ -55,436 +55,442 @@ public: protected: bool in_clear; }; - -typedef struct extop -{ - char op; - int minsize; - int maxsize; -} - -ExtOp; - -struct CharPtn -{ - uint card; - CharPtn *fix; - CharPtn *nxt; -}; - -typedef CharPtn *CharPtr; - -struct CharSet -{ - CharSet(); - ~CharSet(); - - CharPtn *fix; - CharPtn *freeHead, **freeTail; - CharPtr *rep; - CharPtn *ptn; -}; - -class Range -{ - -public: - Range *next; - uint lb, ub; // [lb,ub) - - static free_list vFreeList; - -public: - Range(uint l, uint u) : next(NULL), lb(l), ub(u) - { - vFreeList.insert(this); - } - - Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub) - { - vFreeList.insert(this); - } - - friend std::ostream& operator<<(std::ostream&, const Range&); - friend std::ostream& operator<<(std::ostream&, const Range*); -}; - -inline std::ostream& operator<<(std::ostream &o, const Range *r) -{ - return r ? o << *r : o; -} - -class RegExp -{ - -public: - uint size; - - static free_list vFreeList; - -public: - RegExp() : size(0) - { - } - - virtual ~RegExp() - { - vFreeList.erase(this); - } - - virtual const char *typeOf() = 0; - RegExp *isA(const char *t) - { - return typeOf() == t ? this : NULL; - } - - virtual void split(CharSet&) = 0; - virtual void calcSize(Char*) = 0; - virtual uint fixedLength(); - virtual void compile(Char*, Ins*) = 0; - virtual void display(std::ostream&) const = 0; - friend std::ostream& operator<<(std::ostream&, const RegExp&); - friend std::ostream& operator<<(std::ostream&, const RegExp*); -}; - -inline std::ostream& operator<<(std::ostream &o, const RegExp &re) -{ - re.display(o); - return o; -} - -inline std::ostream& operator<<(std::ostream &o, const RegExp *re) -{ - return o << *re; -} - -class NullOp: public RegExp -{ - -public: - static const char *type; - -public: - const char *typeOf() - { - return type; - } - - void split(CharSet&); - void calcSize(Char*); - uint fixedLength(); - void compile(Char*, Ins*); - void display(std::ostream &o) const - { - o << "_"; - } -}; - -class MatchOp: public RegExp -{ - -public: - static const char *type; - Range *match; - -public: - MatchOp(Range *m) : match(m) - { - } - - const char *typeOf() - { - return type; - } - - void split(CharSet&); - void calcSize(Char*); - uint fixedLength(); - void compile(Char*, Ins*); - void display(std::ostream&) const; - -#ifdef PEDANTIC -private: - MatchOp(const MatchOp& oth) - : RegExp(oth) - , match(oth.match) - { - } - - MatchOp& operator = (const MatchOp& oth) - { - new(this) MatchOp(oth); - return *this; - } -#endif -}; - -class RuleOp: public RegExp -{ -public: - static const char *type; - -private: - RegExp *exp; - -public: - RegExp *ctx; - Ins *ins; - uint accept; - Token *code; - uint line; - -public: - RuleOp(RegExp*, RegExp*, Token*, uint); - - ~RuleOp() - { - delete code; - } - - const char *typeOf() - { - return type; - } - - void split(CharSet&); - void calcSize(Char*); - void compile(Char*, Ins*); - void display(std::ostream &o) const - { - o << exp << "/" << ctx << ";"; - } - -#ifdef PEDANTIC -private: - RuleOp(const RuleOp& oth) - : RegExp(oth) - , exp(oth.exp) - , ctx(oth.ctx) - , ins(oth.ins) - , accept(oth.accept) - , code(oth.code) - , line(oth.line) - { - } - RuleOp& operator = (const RuleOp& oth) - { - new(this) RuleOp(oth); - return *this; - } -#endif -}; - -class RuleLine: public line_number -{ -public: - - RuleLine(const RuleOp& _op) - : op(_op) - { - } - - uint get_line() const - { - return op.code->line; - } - - const RuleOp& op; -}; - -RegExp *mkAlt(RegExp*, RegExp*); - -class AltOp: public RegExp -{ - -private: - RegExp *exp1, *exp2; - -public: - static const char *type; - -public: - AltOp(RegExp *e1, RegExp *e2) - : exp1(e1) - , exp2(e2) - { - } - - const char *typeOf() - { - return type; - } - - void split(CharSet&); - void calcSize(Char*); - uint fixedLength(); - void compile(Char*, Ins*); - void display(std::ostream &o) const - { - o << exp1 << "|" << exp2; - } - - friend RegExp *mkAlt(RegExp*, RegExp*); - -#ifdef PEDANTIC -private: - AltOp(const AltOp& oth) - : RegExp(oth) - , exp1(oth.exp1) - , exp2(oth.exp2) - { - } - AltOp& operator = (const AltOp& oth) - { - new(this) AltOp(oth); - return *this; - } -#endif -}; - -class CatOp: public RegExp -{ - -private: - RegExp *exp1, *exp2; - -public: - static const char *type; - -public: - CatOp(RegExp *e1, RegExp *e2) - : exp1(e1) - , exp2(e2) - { - } - - const char *typeOf() - { - return type; - } - - void split(CharSet&); - void calcSize(Char*); - uint fixedLength(); - void compile(Char*, Ins*); - void display(std::ostream &o) const - { - o << exp1 << exp2; - } - -#ifdef PEDANTIC -private: - CatOp(const CatOp& oth) - : RegExp(oth) - , exp1(oth.exp1) - , exp2(oth.exp2) - { - } - CatOp& operator = (const CatOp& oth) - { - new(this) CatOp(oth); - return *this; - } -#endif -}; - -class CloseOp: public RegExp -{ - -private: - RegExp *exp; - -public: - static const char *type; - -public: - CloseOp(RegExp *e) - : exp(e) - { - } - - const char *typeOf() - { - return type; - } - - void split(CharSet&); - void calcSize(Char*); - void compile(Char*, Ins*); - void display(std::ostream &o) const - { - o << exp << "+"; - } - -#ifdef PEDANTIC -private: - CloseOp(const CloseOp& oth) - : RegExp(oth) - , exp(oth.exp) - { - } - CloseOp& operator = (const CloseOp& oth) - { - new(this) CloseOp(oth); - return *this; - } -#endif -}; - -class CloseVOp: public RegExp -{ - -private: - RegExp *exp; - int min; - int max; - -public: - static const char *type; - -public: - CloseVOp(RegExp *e, int lb, int ub) - : exp(e) - , min(lb) - , max(ub) - { - } - - const char *typeOf() - { - return type; - } - - void split(CharSet&); - void calcSize(Char*); - void compile(Char*, Ins*); - void display(std::ostream &o) const - { - o << exp << "+"; - } -#ifdef PEDANTIC -private: - CloseVOp(const CloseVOp& oth) - : RegExp(oth) - , exp(oth.exp) - , min(oth.min) - , max(oth.max) - { - } - CloseVOp& operator = (const CloseVOp& oth) - { - new(this) CloseVOp(oth); - return *this; - } -#endif -}; - -extern void genCode(std::ostream&, RegExp*); -extern void genCode(std::ostream&, uint, RegExp*); -extern void genGetState(std::ostream&, uint&, uint); -extern RegExp *mkDiff(RegExp*, RegExp*); -extern RegExp *mkAlt(RegExp*, RegExp*); - -} // end namespace re2c - -#endif + +typedef struct extop +{ + char op; + int minsize; + int maxsize; +} + +ExtOp; + +struct CharPtn +{ + uint card; + CharPtn *fix; + CharPtn *nxt; +}; + +typedef CharPtn *CharPtr; + +struct CharSet +{ + CharSet(); + ~CharSet(); + + CharPtn *fix; + CharPtn *freeHead, **freeTail; + CharPtr *rep; + CharPtn *ptn; +}; + +class Range +{ + +public: + Range *next; + uint lb, ub; // [lb,ub) + + static free_list vFreeList; + +public: + Range(uint l, uint u) : next(NULL), lb(l), ub(u) + { + vFreeList.insert(this); + } + + Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub) + { + vFreeList.insert(this); + } + + ~Range() + { + vFreeList.erase(this); + } + + friend std::ostream& operator<<(std::ostream&, const Range&); + friend std::ostream& operator<<(std::ostream&, const Range*); +}; + +inline std::ostream& operator<<(std::ostream &o, const Range *r) +{ + return r ? o << *r : o; +} + +class RegExp +{ + +public: + uint size; + + static free_list vFreeList; + +public: + RegExp() : size(0) + { + vFreeList.insert(this); + } + + virtual ~RegExp() + { + vFreeList.erase(this); + } + + virtual const char *typeOf() = 0; + RegExp *isA(const char *t) + { + return typeOf() == t ? this : NULL; + } + + virtual void split(CharSet&) = 0; + virtual void calcSize(Char*) = 0; + virtual uint fixedLength(); + virtual void compile(Char*, Ins*) = 0; + virtual void display(std::ostream&) const = 0; + friend std::ostream& operator<<(std::ostream&, const RegExp&); + friend std::ostream& operator<<(std::ostream&, const RegExp*); +}; + +inline std::ostream& operator<<(std::ostream &o, const RegExp &re) +{ + re.display(o); + return o; +} + +inline std::ostream& operator<<(std::ostream &o, const RegExp *re) +{ + return o << *re; +} + +class NullOp: public RegExp +{ + +public: + static const char *type; + +public: + const char *typeOf() + { + return type; + } + + void split(CharSet&); + void calcSize(Char*); + uint fixedLength(); + void compile(Char*, Ins*); + void display(std::ostream &o) const + { + o << "_"; + } +}; + +class MatchOp: public RegExp +{ + +public: + static const char *type; + Range *match; + +public: + MatchOp(Range *m) : match(m) + { + } + + const char *typeOf() + { + return type; + } + + void split(CharSet&); + void calcSize(Char*); + uint fixedLength(); + void compile(Char*, Ins*); + void display(std::ostream&) const; + +#ifdef PEDANTIC +private: + MatchOp(const MatchOp& oth) + : RegExp(oth) + , match(oth.match) + { + } + + MatchOp& operator = (const MatchOp& oth) + { + new(this) MatchOp(oth); + return *this; + } +#endif +}; + +class RuleOp: public RegExp +{ +public: + static const char *type; + +private: + RegExp *exp; + +public: + RegExp *ctx; + Ins *ins; + uint accept; + Token *code; + uint line; + +public: + RuleOp(RegExp*, RegExp*, Token*, uint); + + ~RuleOp() + { + delete code; + } + + const char *typeOf() + { + return type; + } + + void split(CharSet&); + void calcSize(Char*); + void compile(Char*, Ins*); + void display(std::ostream &o) const + { + o << exp << "/" << ctx << ";"; + } + +#ifdef PEDANTIC +private: + RuleOp(const RuleOp& oth) + : RegExp(oth) + , exp(oth.exp) + , ctx(oth.ctx) + , ins(oth.ins) + , accept(oth.accept) + , code(oth.code) + , line(oth.line) + { + } + RuleOp& operator = (const RuleOp& oth) + { + new(this) RuleOp(oth); + return *this; + } +#endif +}; + +class RuleLine: public line_number +{ +public: + + RuleLine(const RuleOp& _op) + : op(_op) + { + } + + uint get_line() const + { + return op.code->line; + } + + const RuleOp& op; +}; + +RegExp *mkAlt(RegExp*, RegExp*); + +class AltOp: public RegExp +{ + +private: + RegExp *exp1, *exp2; + +public: + static const char *type; + +public: + AltOp(RegExp *e1, RegExp *e2) + : exp1(e1) + , exp2(e2) + { + } + + const char *typeOf() + { + return type; + } + + void split(CharSet&); + void calcSize(Char*); + uint fixedLength(); + void compile(Char*, Ins*); + void display(std::ostream &o) const + { + o << exp1 << "|" << exp2; + } + + friend RegExp *mkAlt(RegExp*, RegExp*); + +#ifdef PEDANTIC +private: + AltOp(const AltOp& oth) + : RegExp(oth) + , exp1(oth.exp1) + , exp2(oth.exp2) + { + } + AltOp& operator = (const AltOp& oth) + { + new(this) AltOp(oth); + return *this; + } +#endif +}; + +class CatOp: public RegExp +{ + +private: + RegExp *exp1, *exp2; + +public: + static const char *type; + +public: + CatOp(RegExp *e1, RegExp *e2) + : exp1(e1) + , exp2(e2) + { + } + + const char *typeOf() + { + return type; + } + + void split(CharSet&); + void calcSize(Char*); + uint fixedLength(); + void compile(Char*, Ins*); + void display(std::ostream &o) const + { + o << exp1 << exp2; + } + +#ifdef PEDANTIC +private: + CatOp(const CatOp& oth) + : RegExp(oth) + , exp1(oth.exp1) + , exp2(oth.exp2) + { + } + CatOp& operator = (const CatOp& oth) + { + new(this) CatOp(oth); + return *this; + } +#endif +}; + +class CloseOp: public RegExp +{ + +private: + RegExp *exp; + +public: + static const char *type; + +public: + CloseOp(RegExp *e) + : exp(e) + { + } + + const char *typeOf() + { + return type; + } + + void split(CharSet&); + void calcSize(Char*); + void compile(Char*, Ins*); + void display(std::ostream &o) const + { + o << exp << "+"; + } + +#ifdef PEDANTIC +private: + CloseOp(const CloseOp& oth) + : RegExp(oth) + , exp(oth.exp) + { + } + CloseOp& operator = (const CloseOp& oth) + { + new(this) CloseOp(oth); + return *this; + } +#endif +}; + +class CloseVOp: public RegExp +{ + +private: + RegExp *exp; + int min; + int max; + +public: + static const char *type; + +public: + CloseVOp(RegExp *e, int lb, int ub) + : exp(e) + , min(lb) + , max(ub) + { + } + + const char *typeOf() + { + return type; + } + + void split(CharSet&); + void calcSize(Char*); + void compile(Char*, Ins*); + void display(std::ostream &o) const + { + o << exp << "+"; + } +#ifdef PEDANTIC +private: + CloseVOp(const CloseVOp& oth) + : RegExp(oth) + , exp(oth.exp) + , min(oth.min) + , max(oth.max) + { + } + CloseVOp& operator = (const CloseVOp& oth) + { + new(this) CloseVOp(oth); + return *this; + } +#endif +}; + +extern void genCode(std::ostream&, RegExp*); +extern void genCode(std::ostream&, uint, RegExp*); +extern void genGetState(std::ostream&, uint&, uint); +extern RegExp *mkDiff(RegExp*, RegExp*); +extern RegExp *mkAlt(RegExp*, RegExp*); + +} // end namespace re2c + +#endif diff --git a/tools/re2c/re2c.1 b/tools/re2c/re2c.1 index 05f49b2f0e..fe12c01797 100644 --- a/tools/re2c/re2c.1 +++ b/tools/re2c/re2c.1 @@ -1,7 +1,7 @@ ./" -./" $Id: re2c.1.in 523 2006-05-25 13:32:09Z helly $ +./" $Id: re2c.1.in 663 2007-04-01 11:22:15Z helly $ ./" -.TH RE2C 1 "22 April 2005" "Version 0.10.5" +.TH RE2C 1 "22 April 2005" "Version 0.12.3" .ds re \fBre2c\fP .ds le \fBlex\fP .ds rx regular expression @@ -10,7 +10,7 @@ re2c \- convert regular expressions to C/C++ .SH SYNOPSIS -\*(re [\fB-bdefghisvVw1\fP] [\fB-o output\fP] file\fP +\*(re [\fB-bdefghisuvVw1\fP] [\fB-o output\fP] file\fP .SH DESCRIPTION \*(re is a preprocessor that generates C-based recognizers from regular @@ -26,61 +26,51 @@ For example, given the following code .in +3 .nf -#define NULL ((char*) 0) char *scan(char *p) { -#define YYCTYPE char -#define YYCURSOR p -#define YYLIMIT p -#define YYFILL(n) /*!re2c - [0-9]+ {return YYCURSOR;} - [\\000-\\377] {return NULL;} + re2c:define:YYCTYPE = "unsigned char"; + re2c:define:YYCURSOR = p; + re2c:yyfill:enable = 0; + re2c:yych:conversion = 1; + re2c:indent:top = 1; + [0-9]+ {return p;} + [\000-\377] {return (char*)0;} */ } .fi .in -3 -\*(re will generate +\*(re -is will generate .in +3 .nf /* Generated by re2c on Sat Apr 16 11:40:58 1994 */ -#line 1 "simple.re" -#define NULL ((char*) 0) char *scan(char *p) { -#define YYCTYPE char -#define YYCURSOR p -#define YYLIMIT p -#define YYFILL(n) -{ - YYCTYPE yych; - unsigned int yyaccept; - goto yy0; -yy1: ++YYCURSOR; -yy0: - if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); - yych = *YYCURSOR; - if(yych <= '/') goto yy4; - if(yych >= ':') goto yy4; -yy2: yych = *++YYCURSOR; + { + unsigned char yych; + + yych = (unsigned char)*p; + if(yych <= '/') goto yy4; + if(yych >= ':') goto yy4; + ++p; + yych = (unsigned char)*p; goto yy7; yy3: -#line 9 - {return YYCURSOR;} -yy4: yych = *++YYCURSOR; -yy5: -#line 10 - {return NULL;} -yy6: ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; -yy7: if(yych <= '/') goto yy3; - if(yych <= '9') goto yy6; + {return p;} +yy4: + ++p; + yych = (unsigned char)*p; + {return char*)0;} +yy6: + ++p; + yych = (unsigned char)*p; +yy7: + if(yych <= '/') goto yy3; + if(yych <= '9') goto yy6; goto yy3; -} -#line 11 + } } .fi @@ -123,7 +113,7 @@ Generate a scanner with support for storable state. For details see below at \fBSCANNER WITH STORABLE STATES\fP. .TP \fB-g\fP -Generate a scanner that utilizes GCC's computed goto feature. That is re2c +Generate a scanner that utilizes GCC's computed goto feature. That is \*(re generates jump tables whenever a decision is of a certain complexity (e.g. a lot of if conditions are otherwise necessary). This is only useable with GCC and produces output that cannot be compiled with any other compiler. Note that @@ -132,8 +122,8 @@ inplace configuration "cgoto:threshold". .TP \fB-i\fP Do not output #line information. This is usefull when you want use a CMS tool -with the re2c output which you might want if you do not require your users to -have re2c themselves when building from your source. +with the \*(re output which you might want if you do not require your users to +have \*(re themselves when building from your source. \fB-o output\fP Specify the output file. .TP @@ -141,6 +131,12 @@ Specify the output file. Generate nested \fCif\fPs for some \fCswitch\fPes. Many compilers need this assist to generate better code. .TP +\fB-u\fP +Generate a parser that supports Unicode chars (UTF-32). This means the +generated code can deal with any valid Unicode character up to 0x10FFFF. When +UTF-8 or UTF-16 needs to be supported you need to convert the incoming stream +to UTF-32 upon input yourself. +.TP \fB-v\fP Show version information. .TP @@ -153,11 +149,16 @@ cannot be used together with \fB-e\fP switch. .TP \fB-1\fP Force single pass generation, this cannot be combined with -f and disables -YYMAXFILL generation prior to last re2c block. +YYMAXFILL generation prior to last \*(re block. +.TP +\fb--no-generation-date\fP +Suppress date output in the generated output so that it only shows the re2c +version. .SH "INTERFACE CODE" Unlike other scanner generators, \*(re does not generate complete scanners: the user must supply some interface code. -In particular, the user must define the following macros: +In particular, the user must define the following macros or use the +corresponding inplace configurations: .TP \fCYYCTYPE\fP Type used to hold an input symbol. @@ -187,26 +188,27 @@ The generated code saves trailing context backtracking information in \fCYYCTXMA The user only needs to define this macro if a scanner specification uses trailing context in one or more of its regular expressions. .TP -\fCYYFILL(\fP\fIn\fP\fC)\fP +\fCYYFILL\fP(\fIn\fP\fC\fP) The generated code "calls" \fCYYFILL\fP(n) when the buffer needs (re)filling: at least \fIn\fP additional characters should be provided. \fCYYFILL\fP(n) should adjust \fCYYCURSOR\fP, \fCYYLIMIT\fP, \fCYYMARKER\fP and \fCYYCTXMARKER\fP as needed. Note that for typical programming languages \fIn\fP will be the length of the longest keyword plus one. The user can place a comment of the form \fC/*!max:re2c */\fP once to insert -a \fCYYMAXFILL\fP definition that is set to the maximum length value. If -1 -switch is used then YYMAXFILL can be triggered once after the last \fC/*!re2c */\fP +a \fCYYMAXFILL\fP(n) definition that is set to the maximum length value. If -1 +switch is used then \fCYYMAXFILL\fP can be triggered only once after the +last \fC/*!re2c */\fP block. .TP -\fCYYGETSTATE()\fP +\fCYYGETSTATE\fP() The user only needs to define this macro if the \fB-f\fP flag was specified. -In that case, the generated code "calls" \fCYYGETSTATE\fP at the very beginning -of the scanner in order to obtain the saved state. YYGETSTATE must return a signed +In that case, the generated code "calls" \fCYYGETSTATE\fP() at the very beginning +of the scanner in order to obtain the saved state. \fCYYGETSTATE\fP() must return a signed integer. The value must be either -1, indicating that the scanner is entered for the -first time, or a value previously saved by \fCYYSETSTATE\fP. In the second case, the +first time, or a value previously saved by \fCYYSETSTATE\fP(s). In the second case, the scanner will resume operations right after where the last \fCYYFILL\fP(n) was called. .TP -\fCYYSETSTATE(\fP\fIn\fP\fC)\fP +\fCYYSETSTATE(\fP\fIs\fP\fC)\fP The user only needs to define this macro if the \fB-f\fP flag was specified. In that case, the generated code "calls" \fCYYSETSTATE\fP just before calling \fCYYFILL\fP(n). The parameter to \fCYYSETSTATE\fP is a signed integer that uniquely @@ -214,7 +216,9 @@ identifies the specific instance of \fCYYFILL\fP(n) that is about to be called. Should the user wish to save the state of the scanner and have \fCYYFILL\fP(n) return to the caller, all he has to do is store that unique identifer in a variable. Later, when the scannered is called again, it will call \fCYYGETSTATE()\fP and -resume execution right where it left off. +resume execution right where it left off. The generated code will contain +both \fCYYSETSTATE\fP(s) and \fCYYGETSTATE\fP even if \fCYYFILL\fP(n) is being +disabled. .TP \fCYYDEBUG(\fP\fIstate\fP,\fIcurrent\fC)\fP This is only needed if the \fB-d\fP flag was specified. It allows to easily debug @@ -227,11 +231,11 @@ input at the current cursor. This will be automatically defined by \fC/*!max:re2c */\fP blocks as explained above. .SH "SCANNER WITH STORABLE STATES" -When the \fB-f\fP flag is specified, re2c generates a scanner that +When the \fB-f\fP flag is specified, \*(re generates a scanner that can store its current state, return to the caller, and later resume operations exactly where it left off. -The default operation of re2c is a "pull" model, where the scanner asks +The default operation of \*(re is a "pull" model, where the scanner asks for extra input whenever it needs it. However, this mode of operation assumes that the scanner is the "owner" the parsing loop, and that may not always be convenient. @@ -246,9 +250,9 @@ chunk by chunk. When the scanner runs out of data to consume, it just stores its state, and return to the caller. When more input data is fed to the scanner, it resumes operations exactly where it left off. -When using the -f option re2c does not accept stdin because it has to do the +When using the -f option \*(re does not accept stdin because it has to do the full generation process twice which means it has to read the input twice. That -means re2c would fail in case it cannot open the input twice or reading the +means \*(re would fail in case it cannot open the input twice or reading the input for the first time influences the second read attempt. Changes needed compared to the "pull" model. @@ -286,7 +290,7 @@ Please see examples/push.re for push-model scanner. The generated code can be tweaked using inplace configurations "\fBstate:abort\fP" and "\fBstate:nextlabel\fP". .SH "SCANNER SPECIFICATIONS" -Each scanner specification consists of a set of \fIrules\fP, \fIname +Each scanner specification consists of a set of \fIrules\fP, \fInamed definitions\fP and \fIconfigurations\fP. .LP \fIRules\fP consist of a regular expression along with a block of C/C++ code that @@ -302,12 +306,15 @@ Named definitions are of the form: \fIname\fP \fC=\fP \fIregular expression\fP\fC;\fP .RE .LP -Configurations look like name definitions whose names start +Configurations look like named definitions whose names start with "\fBre2c:\fP": .P .RS \fCre2c:\fP\fIname\fP \fC=\fP \fIvalue\fP\fC;\fP .RE +.RS +\fCre2c:\fP\fIname\fP \fC=\fP \fB"\fP\fIvalue\fP\fB"\fP\fC;\fP +.RE .SH "SUMMARY OF RE2C REGULAR EXPRESSIONS" .TP @@ -345,7 +352,7 @@ one or more \fIr\fP's zero or one \fIr\fP's (that is, "an optional \fIr\fP") .TP name -the expansion of the "name" definition (see above) +the expansion of the "named definition" (see above) .TP \fC(\fP\fIr\fP\fC)\fP an \fIr\fP; parentheses are used to override precedence @@ -385,12 +392,10 @@ and a hexadecimal character is defined by backslash, a lower cased '\fBx\fP' and its two hexadecimal digits or a backslash, an upper cased \fBX\fP and its four hexadecimal digits. .LP -re2c -further more supports the c/c++ unicode notation. That is a backslash followed +\*(re further more supports the c/c++ unicode notation. That is a backslash followed by either a lowercased \fBu\fP and its four hexadecimal digits or an uppercased -\fBU\fP and its eight hexadecimal digits. However using the U notation it is -not possible to support characters greater \fB\\U0000FFFF\fP due to an internal -limitation of re2c. +\fBU\fP and its eight hexadecimal digits. However only in \fB-u\fP mode the +generated code can deal with any valid Unicode character up to 0x10FFFF. .LP Since characters greater \fB\\X00FF\fP are not allowed in non unicode mode, the only portable "\fBany\fP" rules are \fB(.|"\\n")\fP and \fB[^]\fP. @@ -401,7 +406,7 @@ Those grouped together have equal precedence. .SH "INPLACE CONFIGURATION" .LP -It is possible to configure code generation inside re2c blocks. The following +It is possible to configure code generation inside \*(re blocks. The following lists the available configurations: .TP \fIre2c:indent:top\fP \fB=\fP 0 \fB;\fP @@ -423,6 +428,12 @@ Set this to zero to suppress generation of YYFILL(n). When using this be sure to verify that the generated scanner does not read behind input. Allowing this behavior might introduce sever security issues to you programs. .TP +\fIre2c:yyfill:parameter\fP \fB=\fP 1 \fB;\fP +Allows to suppress parameter passing to \fBYYFILL\fP calls. If set to zero +then no parameter is passed to \fBYYFILL\fP. If set to a non zero value then +\fBYYFILL\fP usage will be followed by the number of requested characters in +braces. +.TP \fIre2c:startlabel\fP \fB=\fP 0 \fB;\fP If set to a non zero integer then the start label of the next scanner blocks will be generated even if not used by the scanner itself. Otherwise the normal @@ -431,6 +442,10 @@ value then a label with that text will be generated regardless of whether the normal start label is being used or not. This setting is being reset to \fB0\fP after a start label has been generated. .TP +\fIre2c:labelprefix\fP \fB=\fP yy \fB;\fP +Allows to change the prefix of numbered labels. The default is \fByy\fP and +can be set any string that is a valid label. +.TP \fIre2c:state:abort\fP \fB=\fP 0 \fB;\fP When not zero and switch -f is active then the \fCYYGETSTATE\fP block will contain a default case that aborts and a -1 case is used for initialization. @@ -448,11 +463,77 @@ When -g is active this value specifies the complexity threshold that triggers generation of jump tables rather than using nested if's and decision bitfields. The threshold is compared against a calculated estimation of if-s needed where every used bitmap divides the threshold by 2. +.TP +\fIre2c:yych:conversion\fP \fB=\fP 0 \fB;\fP +When the input uses signed characters and \fB-s\fP or \fB-b\fP switches are +in effect re2c allows to automatically convert to the unsigned character type +that is then necessary for its internal single character. When this setting +is zero or an empty string the conversion is disabled. Using a non zero number +the conversion is taken from \fBYYCTYPE\fP. If that is given by an inplace +configuration that value is being used. Otherwise it will be \fB(YYCTYPE)\fP +and changes to that configuration are no longer possible. When this setting is +a string the braces must be specified. Now assuming your input is a \fBchar*\fP +buffer and you are using above mentioned switches you can set \fBYYCTYPE\fP to +\fBunsigned char\fP and this setting to either \fB1\fP or \fB"(unsigned char)"\fP. +.TP +\fIre2c:define:YYCTXMARKER\fP \fB=\fP YYCTXMARKER \fB;\fP +Allows to overwrite the define YYCTXMARKER and thus avoiding it by setting the +value to the actual code needed. +.TP +\fIre2c:define:YYCTYPE\fP \fB=\fP YYCTYPE \fB;\fP +Allows to overwrite the define YYCTYPE and thus avoiding it by setting the +value to the actual code needed. +.TP +\fIre2c:define:YYCURSOR\fP \fB=\fP YYCURSOR \fB;\fP +Allows to overwrite the define YYCURSOR and thus avoiding it by setting the +value to the actual code needed. +.TP +\fIre2c:define:YYDEBUG\fP \fB=\fP YYDEBUG \fB;\fP +Allows to overwrite the define YYDEBUG and thus avoiding it by setting the +value to the actual code needed. +.TP +\fIre2c:define:YYFILL\fP \fB=\fP YYFILL \fB;\fP +Allows to overwrite the define YYFILL and thus avoiding it by setting the +value to the actual code needed. +.TP +\fIre2c:define:YYGETSTATE\fP \fB=\fP YYGETSTATE \fB;\fP +Allows to overwrite the define YYGETSTATE and thus avoiding it by setting the +value to the actual code needed. +.TP +\fIre2c:define:YYLIMIT\fP \fB=\fP YYLIMIT \fB;\fP +Allows to overwrite the define YYLIMIT and thus avoiding it by setting the +value to the actual code needed. +.TP +\fIre2c:define:YYMARKER\fP \fB=\fP YYMARKER \fB;\fP +Allows to overwrite the define YYMARKER and thus avoiding it by setting the +value to the actual code needed. +.TP +\fIre2c:define:YYSETSTATE\fP \fB=\fP YYSETSTATE \fB;\fP +Allows to overwrite the define YYSETSTATE and thus avoiding it by setting the +value to the actual code needed. +.TP +\fIre2c:label:yyFillLabel\fP \fB=\fP yyFillLabel \fB;\fP +Allows to overwrite the name of the label yyFillLabel. +.TP +\fIre2c:label:yyNext\fP \fB=\fP yyNext \fB;\fP +Allows to overwrite the name of the label yyNext. +.TP +\fIre2c:variable:yyaccept\fP \fB=\fP yyaccept \fB;\fP +Allows to overwrite the name of the variable yyaccept. +.TP +\fIre2c:variable:yybm\fP \fB=\fP yybm \fB;\fP +Allows to overwrite the name of the variable yybm. +.TP +\fIre2c:variable:yych\fP \fB=\fP yych \fB;\fP +Allows to overwrite the name of the variable yych. +.TP +\fIre2c:variable:yytarget\fP \fB=\fP yytarget \fB;\fP +Allows to overwrite the name of the variable yytarget. .SH "UNDERSTANDING RE2C" .LP -The subdirectory lessons of the re2c distribution contains a few step by step -lessons to get you started with re2c. All examples in the lessons subdirectory +The subdirectory lessons of the \*(re distribution contains a few step by step +lessons to get you started with \*(re. All examples in the lessons subdirectory can be compiled and actually work. .SH FEATURES @@ -487,10 +568,10 @@ The \*(re internal algorithms need documentation. .LP flex(1), lex(1). .P -More information on \fBre2c\fP can be found here: +More information on \*(re can be found here: .PD 0 .P -.B http://sourceforge.net/projects/re2c/ +.B http://re2c.org/ .PD 1 .SH AUTHORS @@ -511,6 +592,6 @@ Emmanuel Mogenet added storable state .PD 1 .SH VERSION INFORMATION -This manpage describes \fBre2c\fP, version 0.10.5. +This manpage describes \*(re, version 0.12.3. .fi diff --git a/tools/re2c/scanner.cc b/tools/re2c/scanner.cc index ee26a8c786..1a6cbbe7cd 100644 --- a/tools/re2c/scanner.cc +++ b/tools/re2c/scanner.cc @@ -1,6 +1,5 @@ -/* Generated by re2c 0.12.3 on Tue Jan 22 23:04:51 2008 */ -#line 1 "scanner.re" -/* $Id:$ */ +/* Generated by re2c 0.12.3 on Fri Jan 25 21:09:48 2008 */ +/* $Id: scanner.re 663 2007-04-01 11:22:15Z helly $ */ #include #include #include @@ -76,7 +75,6 @@ char *Scanner::fill(char *cursor) return cursor; } -#line 95 "scanner.re" int Scanner::echo() @@ -92,45 +90,36 @@ int Scanner::echo() tok = cursor; echo: - -#line 97 "scanner.cc" { - YYCTYPE yych; - unsigned int yyaccept = 0; - if((YYLIMIT - YYCURSOR) < 16) YYFILL(16); -(16); - yych = *YYCURSOR; - switch(yych) { - case 0x00: goto yy7; - case 0x0A: goto yy5; - case '*': goto yy4; - case '/': goto yy2; - default: goto yy9; - } -yy2: - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case '*': goto yy16; - default: goto yy3; - } -yy3: -#line 184 "scanner.re" { + YYCTYPE yych; + unsigned int yyaccept = 0; + + if((YYLIMIT - YYCURSOR) < 16) YYFILL(16); + yych = *YYCURSOR; + if(yych <= ')') { + if(yych <= 0x00) goto yy7; + if(yych == 0x0A) goto yy5; + goto yy9; + } else { + if(yych <= '*') goto yy4; + if(yych != '/') goto yy9; + } + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if(yych == '*') goto yy16; +yy3: + { goto echo; } -#line 124 "scanner.cc" yy4: - yych = *++YYCURSOR; - switch(yych) { - case '/': goto yy10; - default: goto yy3; - } + yych = *++YYCURSOR; + if(yych == '/') goto yy10; + goto yy3; yy5: - ++YYCURSOR; -#line 167 "scanner.re" - { + ++YYCURSOR; + { if (ignore_eoc) { ignore_cnt++; } else { @@ -139,11 +128,9 @@ yy5: tok = pos = cursor; cline++; goto echo; } -#line 143 "scanner.cc" yy7: - ++YYCURSOR; -#line 176 "scanner.re" - { + ++YYCURSOR; + { if (!ignore_eoc) { out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok) - 1); // -1 so we don't write out the \0 } @@ -151,21 +138,16 @@ yy7: RETURN(0); } } -#line 155 "scanner.cc" yy9: - yych = *++YYCURSOR; - goto yy3; + yych = *++YYCURSOR; + goto yy3; yy10: - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case 0x0A: goto yy14; - case 0x0D: goto yy12; - default: goto yy11; - } + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if(yych == 0x0A) goto yy14; + if(yych == 0x0D) goto yy12; yy11: -#line 154 "scanner.re" - { + { if (ignore_eoc) { if (ignore_cnt) { out << "\n" << sourceFileInfo; @@ -178,23 +160,19 @@ yy11: tok = pos = cursor; goto echo; } -#line 182 "scanner.cc" yy12: - yych = *++YYCURSOR; - switch(yych) { - case 0x0A: goto yy14; - default: goto yy13; - } + yych = *++YYCURSOR; + if(yych == 0x0A) goto yy14; yy13: - YYCURSOR = YYMARKER; - switch(yyaccept) { - case 0: goto yy3; - case 1: goto yy11; - } + YYCURSOR = YYMARKER; + if(yyaccept <= 0) { + goto yy3; + } else { + goto yy11; + } yy14: - ++YYCURSOR; -#line 140 "scanner.re" - { + ++YYCURSOR; + { cline++; if (ignore_eoc) { if (ignore_cnt) { @@ -208,62 +186,38 @@ yy14: tok = pos = cursor; goto echo; } -#line 212 "scanner.cc" yy16: - yych = *++YYCURSOR; - switch(yych) { - case '!': goto yy17; - default: goto yy13; - } -yy17: - yych = *++YYCURSOR; - switch(yych) { - case 'g': goto yy19; - case 'i': goto yy18; - case 'm': goto yy20; - case 'r': goto yy21; - default: goto yy13; - } + yych = *++YYCURSOR; + if(yych != '!') goto yy13; + yych = *++YYCURSOR; + switch(yych) { + case 'g': goto yy19; + case 'i': goto yy18; + case 'm': goto yy20; + case 'r': goto yy21; + default: goto yy13; + } yy18: - yych = *++YYCURSOR; - switch(yych) { - case 'g': goto yy47; - default: goto yy13; - } + yych = *++YYCURSOR; + if(yych == 'g') goto yy47; + goto yy13; yy19: - yych = *++YYCURSOR; - switch(yych) { - case 'e': goto yy34; - default: goto yy13; - } + yych = *++YYCURSOR; + if(yych == 'e') goto yy34; + goto yy13; yy20: - yych = *++YYCURSOR; - switch(yych) { - case 'a': goto yy26; - default: goto yy13; - } + yych = *++YYCURSOR; + if(yych == 'a') goto yy26; + goto yy13; yy21: - yych = *++YYCURSOR; - switch(yych) { - case 'e': goto yy22; - default: goto yy13; - } -yy22: - yych = *++YYCURSOR; - switch(yych) { - case '2': goto yy23; - default: goto yy13; - } -yy23: - yych = *++YYCURSOR; - switch(yych) { - case 'c': goto yy24; - default: goto yy13; - } -yy24: - ++YYCURSOR; -#line 111 "scanner.re" - { + yych = *++YYCURSOR; + if(yych != 'e') goto yy13; + yych = *++YYCURSOR; + if(yych != '2') goto yy13; + yych = *++YYCURSOR; + if(yych != 'c') goto yy13; + ++YYCURSOR; + { if (bUsedYYMaxFill && bSinglePass) { fatal("found scanner block after YYMAXFILL declaration"); } @@ -271,47 +225,21 @@ yy24: tok = cursor; RETURN(1); } -#line 275 "scanner.cc" yy26: - yych = *++YYCURSOR; - switch(yych) { - case 'x': goto yy27; - default: goto yy13; - } -yy27: - yych = *++YYCURSOR; - switch(yych) { - case ':': goto yy28; - default: goto yy13; - } -yy28: - yych = *++YYCURSOR; - switch(yych) { - case 'r': goto yy29; - default: goto yy13; - } -yy29: - yych = *++YYCURSOR; - switch(yych) { - case 'e': goto yy30; - default: goto yy13; - } -yy30: - yych = *++YYCURSOR; - switch(yych) { - case '2': goto yy31; - default: goto yy13; - } -yy31: - yych = *++YYCURSOR; - switch(yych) { - case 'c': goto yy32; - default: goto yy13; - } -yy32: - ++YYCURSOR; -#line 119 "scanner.re" - { + yych = *++YYCURSOR; + if(yych != 'x') goto yy13; + yych = *++YYCURSOR; + if(yych != ':') goto yy13; + yych = *++YYCURSOR; + if(yych != 'r') goto yy13; + yych = *++YYCURSOR; + if(yych != 'e') goto yy13; + yych = *++YYCURSOR; + if(yych != '2') goto yy13; + yych = *++YYCURSOR; + if(yych != 'c') goto yy13; + ++YYCURSOR; + { if (bUsedYYMaxFill) { fatal("cannot generate YYMAXFILL twice"); } @@ -321,148 +249,63 @@ yy32: bUsedYYMaxFill = true; goto echo; } -#line 325 "scanner.cc" yy34: - yych = *++YYCURSOR; - switch(yych) { - case 't': goto yy35; - default: goto yy13; - } -yy35: - yych = *++YYCURSOR; - switch(yych) { - case 's': goto yy36; - default: goto yy13; - } -yy36: - yych = *++YYCURSOR; - switch(yych) { - case 't': goto yy37; - default: goto yy13; - } -yy37: - yych = *++YYCURSOR; - switch(yych) { - case 'a': goto yy38; - default: goto yy13; - } -yy38: - yych = *++YYCURSOR; - switch(yych) { - case 't': goto yy39; - default: goto yy13; - } -yy39: - yych = *++YYCURSOR; - switch(yych) { - case 'e': goto yy40; - default: goto yy13; - } -yy40: - yych = *++YYCURSOR; - switch(yych) { - case ':': goto yy41; - default: goto yy13; - } -yy41: - yych = *++YYCURSOR; - switch(yych) { - case 'r': goto yy42; - default: goto yy13; - } -yy42: - yych = *++YYCURSOR; - switch(yych) { - case 'e': goto yy43; - default: goto yy13; - } -yy43: - yych = *++YYCURSOR; - switch(yych) { - case '2': goto yy44; - default: goto yy13; - } -yy44: - yych = *++YYCURSOR; - switch(yych) { - case 'c': goto yy45; - default: goto yy13; - } -yy45: - ++YYCURSOR; -#line 129 "scanner.re" - { + yych = *++YYCURSOR; + if(yych != 't') goto yy13; + yych = *++YYCURSOR; + if(yych != 's') goto yy13; + yych = *++YYCURSOR; + if(yych != 't') goto yy13; + yych = *++YYCURSOR; + if(yych != 'a') goto yy13; + yych = *++YYCURSOR; + if(yych != 't') goto yy13; + yych = *++YYCURSOR; + if(yych != 'e') goto yy13; + yych = *++YYCURSOR; + if(yych != ':') goto yy13; + yych = *++YYCURSOR; + if(yych != 'r') goto yy13; + yych = *++YYCURSOR; + if(yych != 'e') goto yy13; + yych = *++YYCURSOR; + if(yych != '2') goto yy13; + yych = *++YYCURSOR; + if(yych != 'c') goto yy13; + ++YYCURSOR; + { tok = pos = cursor; genGetState(out, topIndent, 0); ignore_eoc = true; goto echo; } -#line 401 "scanner.cc" yy47: - yych = *++YYCURSOR; - switch(yych) { - case 'n': goto yy48; - default: goto yy13; - } -yy48: - yych = *++YYCURSOR; - switch(yych) { - case 'o': goto yy49; - default: goto yy13; - } -yy49: - yych = *++YYCURSOR; - switch(yych) { - case 'r': goto yy50; - default: goto yy13; - } -yy50: - yych = *++YYCURSOR; - switch(yych) { - case 'e': goto yy51; - default: goto yy13; - } -yy51: - yych = *++YYCURSOR; - switch(yych) { - case ':': goto yy52; - default: goto yy13; - } -yy52: - yych = *++YYCURSOR; - switch(yych) { - case 'r': goto yy53; - default: goto yy13; - } -yy53: - yych = *++YYCURSOR; - switch(yych) { - case 'e': goto yy54; - default: goto yy13; - } -yy54: - yych = *++YYCURSOR; - switch(yych) { - case '2': goto yy55; - default: goto yy13; - } -yy55: - yych = *++YYCURSOR; - switch(yych) { - case 'c': goto yy56; - default: goto yy13; - } -yy56: - ++YYCURSOR; -#line 135 "scanner.re" - { + yych = *++YYCURSOR; + if(yych != 'n') goto yy13; + yych = *++YYCURSOR; + if(yych != 'o') goto yy13; + yych = *++YYCURSOR; + if(yych != 'r') goto yy13; + yych = *++YYCURSOR; + if(yych != 'e') goto yy13; + yych = *++YYCURSOR; + if(yych != ':') goto yy13; + yych = *++YYCURSOR; + if(yych != 'r') goto yy13; + yych = *++YYCURSOR; + if(yych != 'e') goto yy13; + yych = *++YYCURSOR; + if(yych != '2') goto yy13; + yych = *++YYCURSOR; + if(yych != 'c') goto yy13; + ++YYCURSOR; + { tok = pos = cursor; ignore_eoc = true; goto echo; } -#line 464 "scanner.cc" + } } -#line 187 "scanner.re" } @@ -484,1154 +327,951 @@ scan: { goto value; } - -#line 489 "scanner.cc" { - YYCTYPE yych; - unsigned int yyaccept = 0; - if((YYLIMIT - YYCURSOR) < 5) YYFILL(5); -(5); - yych = *YYCURSOR; - switch(yych) { - case 0x09: - case ' ': goto yy79; - case 0x0A: goto yy81; - case 0x0D: goto yy83; - case '"': goto yy66; - case '\'': goto yy68; - case '(': - case ')': - case ';': - case '=': - case '\\': - case '|': goto yy72; - case '*': goto yy64; - case '+': - case '?': goto yy73; - case '.': goto yy77; - case '/': goto yy62; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - case '_': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - case 'o': - case 'p': - case 'q': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': goto yy76; - case '[': goto yy70; - case 'r': goto yy74; - case '{': goto yy60; - default: goto yy85; - } + static const unsigned char yybm[] = { + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 116, 0, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 116, 112, 48, 112, 112, 112, 112, 80, + 112, 112, 112, 112, 112, 112, 112, 112, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 112, 112, 112, 112, 112, 112, + 112, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 112, 0, 96, 112, 120, + 112, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, + }; + + { + YYCTYPE yych; + unsigned int yyaccept = 0; + if((YYLIMIT - YYCURSOR) < 5) YYFILL(5); + yych = *YYCURSOR; + if(yych <= ':') { + if(yych <= '"') { + if(yych <= 0x0C) { + if(yych <= 0x08) goto yy85; + if(yych <= 0x09) goto yy79; + if(yych <= 0x0A) goto yy81; + goto yy85; + } else { + if(yych <= 0x1F) { + if(yych <= 0x0D) goto yy83; + goto yy85; + } else { + if(yych <= ' ') goto yy79; + if(yych <= '!') goto yy85; + goto yy66; + } + } + } else { + if(yych <= '*') { + if(yych <= '&') goto yy85; + if(yych <= '\'') goto yy68; + if(yych <= ')') goto yy72; + goto yy64; + } else { + if(yych <= '-') { + if(yych <= '+') goto yy73; + goto yy85; + } else { + if(yych <= '.') goto yy77; + if(yych <= '/') goto yy62; + goto yy85; + } + } + } + } else { + if(yych <= '\\') { + if(yych <= '>') { + if(yych == '<') goto yy85; + if(yych <= '=') goto yy72; + goto yy85; + } else { + if(yych <= '@') { + if(yych <= '?') goto yy73; + goto yy85; + } else { + if(yych <= 'Z') goto yy76; + if(yych <= '[') goto yy70; + goto yy72; + } + } + } else { + if(yych <= 'q') { + if(yych == '_') goto yy76; + if(yych <= '`') goto yy85; + goto yy76; + } else { + if(yych <= 'z') { + if(yych <= 'r') goto yy74; + goto yy76; + } else { + if(yych <= '{') goto yy60; + if(yych <= '|') goto yy72; + goto yy85; + } + } + } + } yy60: - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case ',': goto yy126; - case '0': goto yy123; - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy124; - default: goto yy61; - } + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if(yych <= '/') { + if(yych == ',') goto yy126; + } else { + if(yych <= '0') goto yy123; + if(yych <= '9') goto yy124; + } yy61: -#line 209 "scanner.re" - { depth = 1; + { depth = 1; goto code; } -#line 593 "scanner.cc" yy62: - ++YYCURSOR; - switch((yych = *YYCURSOR)) { - case '*': goto yy121; - default: goto yy63; - } + ++YYCURSOR; + if((yych = *YYCURSOR) == '*') goto yy121; yy63: -#line 239 "scanner.re" - { RETURN(*tok); } -#line 603 "scanner.cc" + { RETURN(*tok); } yy64: - ++YYCURSOR; - switch((yych = *YYCURSOR)) { - case '/': goto yy119; - default: goto yy65; - } + ++YYCURSOR; + if((yych = *YYCURSOR) == '/') goto yy119; yy65: -#line 241 "scanner.re" - { yylval.op = *tok; + { yylval.op = *tok; RETURN(CLOSE); } -#line 614 "scanner.cc" yy66: - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case 0x0A: goto yy67; - default: goto yy115; - } + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if(yych != 0x0A) goto yy115; yy67: -#line 226 "scanner.re" - { fatal("unterminated string constant (missing \")"); } -#line 625 "scanner.cc" + { fatal("unterminated string constant (missing \")"); } yy68: - yyaccept = 2; - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case 0x0A: goto yy69; - default: goto yy110; - } + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if(yych != 0x0A) goto yy110; yy69: -#line 227 "scanner.re" - { fatal("unterminated string constant (missing ')"); } -#line 636 "scanner.cc" + { fatal("unterminated string constant (missing ')"); } yy70: - yyaccept = 3; - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case 0x0A: goto yy71; - case '^': goto yy101; - default: goto yy100; - } + yyaccept = 3; + yych = *(YYMARKER = ++YYCURSOR); + if(yych == 0x0A) goto yy71; + if(yych == '^') goto yy101; + goto yy100; yy71: -#line 237 "scanner.re" - { fatal("unterminated range (missing ])"); } -#line 648 "scanner.cc" + { fatal("unterminated range (missing ])"); } yy72: - yych = *++YYCURSOR; - goto yy63; + yych = *++YYCURSOR; + goto yy63; yy73: - yych = *++YYCURSOR; - goto yy65; + yych = *++YYCURSOR; + goto yy65; yy74: - ++YYCURSOR; - switch((yych = *YYCURSOR)) { - case 'e': goto yy91; - default: goto yy90; - } + ++YYCURSOR; + if((yych = *YYCURSOR) == 'e') goto yy91; + goto yy90; yy75: -#line 268 "scanner.re" - { cur = cursor; + { cur = cursor; yylval.symbol = Symbol::find(token()); return ID; } -#line 666 "scanner.cc" yy76: - yych = *++YYCURSOR; - goto yy90; + yych = *++YYCURSOR; + goto yy90; yy77: - ++YYCURSOR; -#line 272 "scanner.re" - { cur = cursor; + ++YYCURSOR; + { cur = cursor; yylval.regexp = mkDot(); return RANGE; } -#line 677 "scanner.cc" yy79: - ++YYCURSOR; - yych = *YYCURSOR; - goto yy88; + ++YYCURSOR; + yych = *YYCURSOR; + goto yy88; yy80: -#line 277 "scanner.re" - { goto scan; } -#line 685 "scanner.cc" + { goto scan; } yy81: - ++YYCURSOR; + ++YYCURSOR; yy82: -#line 279 "scanner.re" - { if(cursor == eof) RETURN(0); + { if(cursor == eof) RETURN(0); pos = cursor; cline++; goto scan; } -#line 694 "scanner.cc" yy83: - ++YYCURSOR; - switch((yych = *YYCURSOR)) { - case 0x0A: goto yy86; - default: goto yy84; - } + ++YYCURSOR; + if((yych = *YYCURSOR) == 0x0A) goto yy86; yy84: -#line 284 "scanner.re" - { std::ostringstream msg; + { std::ostringstream msg; msg << "unexpected character: "; prtChOrHex(msg, *tok); fatal(msg.str().c_str()); goto scan; } -#line 709 "scanner.cc" yy85: - yych = *++YYCURSOR; - goto yy84; + yych = *++YYCURSOR; + goto yy84; yy86: - yych = *++YYCURSOR; - goto yy82; + yych = *++YYCURSOR; + goto yy82; yy87: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; yy88: - switch(yych) { - case 0x09: - case ' ': goto yy87; - default: goto yy80; - } + if(yybm[0+yych] & 4) { + goto yy87; + } + goto yy80; yy89: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; yy90: - switch(yych) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - case '_': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': goto yy89; - default: goto yy75; - } + if(yybm[0+yych] & 8) { + goto yy89; + } + goto yy75; yy91: - yych = *++YYCURSOR; - switch(yych) { - case '2': goto yy92; - default: goto yy90; - } -yy92: - yych = *++YYCURSOR; - switch(yych) { - case 'c': goto yy93; - default: goto yy90; - } -yy93: - yyaccept = 4; - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case ':': goto yy94; - default: goto yy90; - } + yych = *++YYCURSOR; + if(yych != '2') goto yy90; + yych = *++YYCURSOR; + if(yych != 'c') goto yy90; + yyaccept = 4; + yych = *(YYMARKER = ++YYCURSOR); + if(yych != ':') goto yy90; yy94: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - case '_': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': goto yy96; - default: goto yy95; - } + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= '^') { + if(yych <= '@') goto yy95; + if(yych <= 'Z') goto yy96; + } else { + if(yych == '`') goto yy95; + if(yych <= 'z') goto yy96; + } yy95: - YYCURSOR = YYMARKER; - switch(yyaccept) { - case 0: goto yy61; - case 1: goto yy67; - case 2: goto yy69; - case 3: goto yy71; - case 4: goto yy75; - case 5: goto yy98; - case 6: goto yy127; - } + YYCURSOR = YYMARKER; + if(yyaccept <= 3) { + if(yyaccept <= 1) { + if(yyaccept <= 0) { + goto yy61; + } else { + goto yy67; + } + } else { + if(yyaccept <= 2) { + goto yy69; + } else { + goto yy71; + } + } + } else { + if(yyaccept <= 5) { + if(yyaccept <= 4) { + goto yy75; + } else { + goto yy98; + } + } else { + goto yy127; + } + } yy96: - yyaccept = 5; - YYMARKER = ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - case '_': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': goto yy96; - case ':': goto yy94; - default: goto yy98; - } + yyaccept = 5; + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= 'Z') { + if(yych <= '9') { + if(yych >= '0') goto yy96; + } else { + if(yych <= ':') goto yy94; + if(yych >= 'A') goto yy96; + } + } else { + if(yych <= '_') { + if(yych >= '_') goto yy96; + } else { + if(yych <= '`') goto yy98; + if(yych <= 'z') goto yy96; + } + } yy98: -#line 261 "scanner.re" - { cur = cursor; + { cur = cursor; tok+= 5; /* skip "re2c:" */ iscfg = 1; yylval.str = new Str(token()); return CONFIG; } -#line 967 "scanner.cc" yy99: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; yy100: - switch(yych) { - case 0x0A: goto yy95; - case '\\': goto yy103; - case ']': goto yy104; - default: goto yy99; - } + if(yybm[0+yych] & 16) { + goto yy99; + } + if(yych <= '[') goto yy95; + if(yych <= '\\') goto yy103; + goto yy104; yy101: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy95; - case '\\': goto yy106; - case ']': goto yy107; - default: goto yy101; - } + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= '[') { + if(yych == 0x0A) goto yy95; + goto yy101; + } else { + if(yych <= '\\') goto yy106; + if(yych <= ']') goto yy107; + goto yy101; + } yy103: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy95; - default: goto yy99; - } + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy95; + goto yy99; yy104: - ++YYCURSOR; -#line 233 "scanner.re" - { cur = cursor; + ++YYCURSOR; + { cur = cursor; yylval.regexp = ranToRE(token()); return RANGE; } -#line 1003 "scanner.cc" yy106: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy95; - default: goto yy101; - } + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy95; + goto yy101; yy107: - ++YYCURSOR; -#line 229 "scanner.re" - { cur = cursor; + ++YYCURSOR; + { cur = cursor; yylval.regexp = invToRE(token()); return RANGE; } -#line 1018 "scanner.cc" yy109: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; yy110: - switch(yych) { - case 0x0A: goto yy95; - case '\'': goto yy112; - case '\\': goto yy111; - default: goto yy109; - } -yy111: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy95; - default: goto yy109; - } + if(yybm[0+yych] & 32) { + goto yy109; + } + if(yych <= '&') goto yy95; + if(yych <= '\'') goto yy112; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy95; + goto yy109; yy112: - ++YYCURSOR; -#line 222 "scanner.re" - { cur = cursor; + ++YYCURSOR; + { cur = cursor; yylval.regexp = strToCaseInsensitiveRE(token()); return STRING; } -#line 1044 "scanner.cc" yy114: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; yy115: - switch(yych) { - case 0x0A: goto yy95; - case '"': goto yy117; - case '\\': goto yy116; - default: goto yy114; - } -yy116: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy95; - default: goto yy114; - } + if(yybm[0+yych] & 64) { + goto yy114; + } + if(yych <= '!') goto yy95; + if(yych <= '"') goto yy117; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy95; + goto yy114; yy117: - ++YYCURSOR; -#line 218 "scanner.re" - { cur = cursor; + ++YYCURSOR; + { cur = cursor; yylval.regexp = strToRE(token()); return STRING; } -#line 1070 "scanner.cc" yy119: - ++YYCURSOR; -#line 215 "scanner.re" - { tok = cursor; + ++YYCURSOR; + { tok = cursor; RETURN(0); } -#line 1076 "scanner.cc" yy121: - ++YYCURSOR; -#line 212 "scanner.re" - { depth = 1; + ++YYCURSOR; + { depth = 1; goto comment; } -#line 1082 "scanner.cc" yy123: - yych = *++YYCURSOR; - switch(yych) { - case ',': goto yy137; - default: goto yy125; - } + yych = *++YYCURSOR; + if(yych == ',') goto yy137; + goto yy125; yy124: - ++YYCURSOR; - if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); -(2); - yych = *YYCURSOR; + ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; yy125: - switch(yych) { - case ',': goto yy130; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy124; - case '}': goto yy128; - default: goto yy95; - } + if(yybm[0+yych] & 128) { + goto yy124; + } + if(yych == ',') goto yy130; + if(yych == '}') goto yy128; + goto yy95; yy126: - ++YYCURSOR; + ++YYCURSOR; yy127: -#line 259 "scanner.re" - { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); } -#line 1115 "scanner.cc" + { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); } yy128: - ++YYCURSOR; -#line 247 "scanner.re" - { yylval.extop.minsize = atoi((char *)tok+1); + ++YYCURSOR; + { yylval.extop.minsize = atoi((char *)tok+1); yylval.extop.maxsize = atoi((char *)tok+1); RETURN(CLOSESIZE); } -#line 1122 "scanner.cc" yy130: - yyaccept = 6; - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy133; - case '}': goto yy131; - default: goto yy127; - } -yy131: - ++YYCURSOR; -#line 255 "scanner.re" - { yylval.extop.minsize = atoi((char *)tok+1); + yyaccept = 6; + yych = *(YYMARKER = ++YYCURSOR); + if(yych <= '/') goto yy127; + if(yych <= '9') goto yy133; + if(yych != '}') goto yy127; + ++YYCURSOR; + { yylval.extop.minsize = atoi((char *)tok+1); yylval.extop.maxsize = -1; RETURN(CLOSESIZE); } -#line 1146 "scanner.cc" yy133: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy133; - case '}': goto yy135; - default: goto yy95; - } -yy135: - ++YYCURSOR; -#line 251 "scanner.re" - { yylval.extop.minsize = atoi((char *)tok+1); + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= '/') goto yy95; + if(yych <= '9') goto yy133; + if(yych != '}') goto yy95; + ++YYCURSOR; + { yylval.extop.minsize = atoi((char *)tok+1); yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1)); RETURN(CLOSESIZE); } -#line 1171 "scanner.cc" yy137: - yyaccept = 6; - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy133; - case '}': goto yy138; - default: goto yy127; - } -yy138: - ++YYCURSOR; -#line 244 "scanner.re" - { yylval.op = '*'; + yyaccept = 6; + yych = *(YYMARKER = ++YYCURSOR); + if(yych <= '/') goto yy127; + if(yych <= '9') goto yy133; + if(yych != '}') goto yy127; + ++YYCURSOR; + { yylval.op = '*'; RETURN(CLOSE); } -#line 1194 "scanner.cc" + } } -#line 290 "scanner.re" code: - -#line 1201 "scanner.cc" { - YYCTYPE yych; - if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); -(2); - yych = *YYCURSOR; - switch(yych) { - case 0x00: goto yy148; - case 0x0A: goto yy146; - case '"': goto yy152; - case '\'': goto yy153; - case '{': goto yy144; - case '}': goto yy142; - default: goto yy150; - } -yy142: - ++YYCURSOR; -#line 294 "scanner.re" - { if(--depth == 0){ + static const unsigned char yybm[] = { + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 0, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 64, 192, 192, 192, 192, 128, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 0, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, + }; + + { + YYCTYPE yych; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if(yych <= '&') { + if(yych <= 0x0A) { + if(yych <= 0x00) goto yy148; + if(yych <= 0x09) goto yy150; + goto yy146; + } else { + if(yych == '"') goto yy152; + goto yy150; + } + } else { + if(yych <= '{') { + if(yych <= '\'') goto yy153; + if(yych <= 'z') goto yy150; + goto yy144; + } else { + if(yych != '}') goto yy150; + } + } + ++YYCURSOR; + { if(--depth == 0){ cur = cursor; yylval.token = new Token(token(), tline); return CODE; } goto code; } -#line 1225 "scanner.cc" yy144: - ++YYCURSOR; -#line 300 "scanner.re" - { ++depth; + ++YYCURSOR; + { ++depth; goto code; } -#line 1231 "scanner.cc" yy146: - ++YYCURSOR; -#line 302 "scanner.re" - { if(cursor == eof) fatal("missing '}'"); + ++YYCURSOR; + { if(cursor == eof) fatal("missing '}'"); pos = cursor; cline++; goto code; } -#line 1239 "scanner.cc" yy148: - ++YYCURSOR; -#line 306 "scanner.re" - { if(cursor == eof) { + ++YYCURSOR; + { if(cursor == eof) { if (depth) fatal("missing '}'"); RETURN(0); } goto code; } -#line 1249 "scanner.cc" yy150: - ++YYCURSOR; + ++YYCURSOR; yy151: -#line 312 "scanner.re" - { goto code; } -#line 1255 "scanner.cc" + { goto code; } yy152: - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case 0x0A: goto yy151; - default: goto yy159; - } + yych = *(YYMARKER = ++YYCURSOR); + if(yych == 0x0A) goto yy151; + goto yy159; yy153: - yych = *(YYMARKER = ++YYCURSOR); - switch(yych) { - case 0x0A: goto yy151; - default: goto yy155; - } + yych = *(YYMARKER = ++YYCURSOR); + if(yych == 0x0A) goto yy151; + goto yy155; yy154: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; yy155: - switch(yych) { - case 0x0A: goto yy156; - case '\'': goto yy150; - case '\\': goto yy157; - default: goto yy154; - } + if(yybm[0+yych] & 64) { + goto yy154; + } + if(yych <= '&') goto yy156; + if(yych <= '\'') goto yy150; + goto yy157; yy156: - YYCURSOR = YYMARKER; - goto yy151; + YYCURSOR = YYMARKER; + goto yy151; yy157: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy156; - default: goto yy154; - } + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy156; + goto yy154; yy158: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; yy159: - switch(yych) { - case 0x0A: goto yy156; - case '"': goto yy150; - case '\\': goto yy160; - default: goto yy158; - } -yy160: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy156; - default: goto yy158; + if(yybm[0+yych] & 128) { + goto yy158; + } + if(yych <= '!') goto yy156; + if(yych <= '"') goto yy150; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy156; + goto yy158; } } -#line 313 "scanner.re" comment: - -#line 1315 "scanner.cc" { - YYCTYPE yych; - if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); -(2); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy166; - case '*': goto yy163; - case '/': goto yy165; - default: goto yy168; - } + + { + YYCTYPE yych; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if(yych <= ')') { + if(yych == 0x0A) goto yy166; + goto yy168; + } else { + if(yych <= '*') goto yy163; + if(yych == '/') goto yy165; + goto yy168; + } yy163: - ++YYCURSOR; - switch((yych = *YYCURSOR)) { - case '/': goto yy171; - default: goto yy164; - } + ++YYCURSOR; + if((yych = *YYCURSOR) == '/') goto yy171; yy164: -#line 328 "scanner.re" - { if(cursor == eof) RETURN(0); + { if(cursor == eof) RETURN(0); goto comment; } -#line 1337 "scanner.cc" yy165: - yych = *++YYCURSOR; - switch(yych) { - case '*': goto yy169; - default: goto yy164; - } + yych = *++YYCURSOR; + if(yych == '*') goto yy169; + goto yy164; yy166: - ++YYCURSOR; -#line 324 "scanner.re" - { if(cursor == eof) RETURN(0); + ++YYCURSOR; + { if(cursor == eof) RETURN(0); tok = pos = cursor; cline++; goto comment; } -#line 1351 "scanner.cc" yy168: - yych = *++YYCURSOR; - goto yy164; + yych = *++YYCURSOR; + goto yy164; yy169: - ++YYCURSOR; -#line 321 "scanner.re" - { ++depth; + ++YYCURSOR; + { ++depth; fatal("ambiguous /* found"); goto comment; } -#line 1361 "scanner.cc" yy171: - ++YYCURSOR; -#line 317 "scanner.re" - { if(--depth == 0) + ++YYCURSOR; + { if(--depth == 0) goto scan; else goto comment; } -#line 1369 "scanner.cc" + } } -#line 330 "scanner.re" config: - -#line 1376 "scanner.cc" { - YYCTYPE yych; - if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); -(2); - yych = *YYCURSOR; - switch(yych) { - case 0x09: - case ' ': goto yy175; - case '=': goto yy177; - default: goto yy179; - } + static const unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }; + + { + YYCTYPE yych; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if(yych <= 0x1F) { + if(yych != 0x09) goto yy179; + } else { + if(yych <= ' ') goto yy175; + if(yych == '=') goto yy177; + goto yy179; + } yy175: - ++YYCURSOR; - yych = *YYCURSOR; - goto yy184; + ++YYCURSOR; + yych = *YYCURSOR; + goto yy184; yy176: -#line 334 "scanner.re" - { goto config; } -#line 1395 "scanner.cc" + { goto config; } yy177: - ++YYCURSOR; - yych = *YYCURSOR; - goto yy182; + ++YYCURSOR; + yych = *YYCURSOR; + goto yy182; yy178: -#line 335 "scanner.re" - { iscfg = 2; + { iscfg = 2; cur = cursor; RETURN('='); } -#line 1406 "scanner.cc" yy179: - ++YYCURSOR; -#line 339 "scanner.re" - { fatal("missing '='"); } -#line 1411 "scanner.cc" + ++YYCURSOR; + { fatal("missing '='"); } yy181: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; yy182: - switch(yych) { - case 0x09: - case ' ': goto yy181; - default: goto yy178; - } + if(yybm[0+yych] & 128) { + goto yy181; + } + goto yy178; yy183: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; yy184: - switch(yych) { - case 0x09: - case ' ': goto yy183; - default: goto yy176; + if(yych == 0x09) goto yy183; + if(yych == ' ') goto yy183; + goto yy176; } } -#line 340 "scanner.re" value: - -#line 1438 "scanner.cc" { - YYCTYPE yych; - if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); -(2); - yych = *YYCURSOR; - switch(yych) { - case 0x09: - case 0x0A: - case 0x0D: - case ' ': - case ';': goto yy187; - case '"': goto yy195; - case '\'': goto yy197; - case '-': goto yy190; - case '0': goto yy188; - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy191; - default: goto yy193; - } + static const unsigned char yybm[] = { + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 192, 0, 248, 248, 192, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 192, 248, 104, 248, 248, 248, 248, 152, + 248, 248, 248, 248, 248, 248, 248, 248, + 252, 252, 252, 252, 252, 252, 252, 252, + 252, 252, 248, 192, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 8, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + 248, 248, 248, 248, 248, 248, 248, 248, + }; + + { + YYCTYPE yych; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if(yych <= '&') { + if(yych <= 0x0D) { + if(yych <= 0x08) goto yy193; + if(yych <= 0x0A) goto yy187; + if(yych <= 0x0C) goto yy193; + } else { + if(yych <= ' ') { + if(yych <= 0x1F) goto yy193; + } else { + if(yych == '"') goto yy195; + goto yy193; + } + } + } else { + if(yych <= '/') { + if(yych <= '\'') goto yy197; + if(yych == '-') goto yy190; + goto yy193; + } else { + if(yych <= '9') { + if(yych <= '0') goto yy188; + goto yy191; + } else { + if(yych != ';') goto yy193; + } + } + } yy187: -#line 349 "scanner.re" - { cur = cursor; + { cur = cursor; yylval.str = new Str(token()); iscfg = 0; return VALUE; } -#line 1472 "scanner.cc" yy188: - ++YYCURSOR; - switch((yych = *YYCURSOR)) { - case 0x09: - case 0x0A: - case 0x0D: - case ' ': - case ';': goto yy189; - default: goto yy193; - } + ++YYCURSOR; + if(yybm[0+(yych = *YYCURSOR)] & 8) { + goto yy193; + } yy189: -#line 344 "scanner.re" - { cur = cursor; + { cur = cursor; yylval.number = atoi(token().to_string().c_str()); iscfg = 0; return NUMBER; } -#line 1490 "scanner.cc" yy190: - yych = *++YYCURSOR; - switch(yych) { - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy191; - default: goto yy194; - } + yych = *++YYCURSOR; + if(yych <= '0') goto yy194; + if(yych >= ':') goto yy194; yy191: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x09: - case 0x0A: - case 0x0D: - case ' ': - case ';': goto yy189; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': goto yy191; - default: goto yy193; - } + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yybm[0+yych] & 4) { + goto yy191; + } + if(yych <= 0x0D) { + if(yych <= 0x08) goto yy193; + if(yych <= 0x0A) goto yy189; + if(yych >= 0x0D) goto yy189; + } else { + if(yych <= ' ') { + if(yych >= ' ') goto yy189; + } else { + if(yych == ';') goto yy189; + } + } yy193: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; yy194: - switch(yych) { - case 0x09: - case 0x0A: - case 0x0D: - case ' ': - case ';': goto yy187; - default: goto yy193; - } + if(yybm[0+yych] & 8) { + goto yy193; + } + goto yy187; yy195: - YYMARKER = ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x09: - case 0x0D: - case ' ': - case ';': goto yy205; - case 0x0A: goto yy187; - case '"': goto yy193; - case '\\': goto yy207; - default: goto yy195; - } + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yybm[0+yych] & 16) { + goto yy195; + } + if(yych <= '!') { + if(yych == 0x0A) goto yy187; + goto yy205; + } else { + if(yych <= '"') goto yy193; + if(yych <= '[') goto yy205; + goto yy207; + } yy197: - YYMARKER = ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x09: - case 0x0D: - case ' ': - case ';': goto yy199; - case 0x0A: goto yy187; - case '\'': goto yy193; - case '\\': goto yy202; - default: goto yy197; - } + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yybm[0+yych] & 32) { + goto yy197; + } + if(yych <= '&') { + if(yych == 0x0A) goto yy187; + } else { + if(yych <= '\'') goto yy193; + if(yych >= '\\') goto yy202; + } yy199: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy201; - case '\'': goto yy203; - case '\\': goto yy204; - default: goto yy199; - } + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yybm[0+yych] & 64) { + goto yy199; + } + if(yych <= '&') goto yy201; + if(yych <= '\'') goto yy203; + goto yy204; yy201: - YYCURSOR = YYMARKER; - goto yy187; + YYCURSOR = YYMARKER; + goto yy187; yy202: - YYMARKER = ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x09: - case 0x0D: - case ' ': - case ';': goto yy199; - case 0x0A: goto yy187; - default: goto yy197; - } + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= 0x0D) { + if(yych <= 0x09) { + if(yych <= 0x08) goto yy197; + goto yy199; + } else { + if(yych <= 0x0A) goto yy187; + if(yych <= 0x0C) goto yy197; + goto yy199; + } + } else { + if(yych <= ' ') { + if(yych <= 0x1F) goto yy197; + goto yy199; + } else { + if(yych == ';') goto yy199; + goto yy197; + } + } yy203: - yych = *++YYCURSOR; - goto yy187; + yych = *++YYCURSOR; + goto yy187; yy204: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy201; - default: goto yy199; - } + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy201; + goto yy199; yy205: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy201; - case '"': goto yy203; - case '\\': goto yy208; - default: goto yy205; - } + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yybm[0+yych] & 128) { + goto yy205; + } + if(yych <= '!') goto yy201; + if(yych <= '"') goto yy203; + goto yy208; yy207: - YYMARKER = ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x09: - case 0x0D: - case ' ': - case ';': goto yy205; - case 0x0A: goto yy187; - default: goto yy195; - } + YYMARKER = ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= 0x0D) { + if(yych <= 0x09) { + if(yych <= 0x08) goto yy195; + goto yy205; + } else { + if(yych <= 0x0A) goto yy187; + if(yych <= 0x0C) goto yy195; + goto yy205; + } + } else { + if(yych <= ' ') { + if(yych <= 0x1F) goto yy195; + goto yy205; + } else { + if(yych == ';') goto yy205; + goto yy195; + } + } yy208: - ++YYCURSOR; - if(YYLIMIT == YYCURSOR) YYFILL(1); - yych = *YYCURSOR; - switch(yych) { - case 0x0A: goto yy201; - default: goto yy205; + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy201; + goto yy205; } } -#line 354 "scanner.re" } diff --git a/tools/re2c/scanner.re b/tools/re2c/scanner.re index 743675df6e..fde59be72b 100644 --- a/tools/re2c/scanner.re +++ b/tools/re2c/scanner.re @@ -1,373 +1,373 @@ -/* $Id:$ */ -#include -#include -#include -#include -#include "scanner.h" -#include "parser.h" -#include "y.tab.h" -#include "globals.h" -#include "dfa.h" - -extern YYSTYPE yylval; - -#ifndef MAX -#define MAX(a,b) (((a)>(b))?(a):(b)) -#endif - -#define BSIZE 8192 - -#define YYCTYPE unsigned char -#define YYCURSOR cursor -#define YYLIMIT lim -#define YYMARKER ptr -#define YYFILL(n) {cursor = fill(cursor);} - -#define RETURN(i) {cur = cursor; return i;} - -namespace re2c -{ - -Scanner::Scanner(const char *fn, std::istream& i, std::ostream& o) - : in(i) - , out(o) - , bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL) - , top(NULL), eof(NULL), tchar(0), tline(0), cline(1), iscfg(0), filename(fn) -{ - ; -} - -char *Scanner::fill(char *cursor) -{ - if(!eof) - { - uint cnt = tok - bot; - if(cnt) - { - memcpy(bot, tok, lim - tok); - tok = bot; - ptr -= cnt; - cursor -= cnt; - pos -= cnt; - lim -= cnt; - } - if((top - lim) < BSIZE) - { - char *buf = new char[(lim - bot) + BSIZE]; - memcpy(buf, tok, lim - tok); - tok = buf; - ptr = &buf[ptr - bot]; - cursor = &buf[cursor - bot]; - pos = &buf[pos - bot]; - lim = &buf[lim - bot]; - top = &lim[BSIZE]; - delete [] bot; - bot = buf; - } - in.read(lim, BSIZE); - if ((cnt = in.gcount()) != BSIZE ) - { - eof = &lim[cnt]; *eof++ = '\0'; - } - lim += cnt; - } - return cursor; -} - -/*!re2c -zero = "\000"; -any = [\000-\377]; -dot = any \ [\n]; -esc = dot \ [\\]; -istring = "[" "^" ((esc \ [\]]) | "\\" dot)* "]" ; -cstring = "[" ((esc \ [\]]) | "\\" dot)* "]" ; -dstring = "\"" ((esc \ ["] ) | "\\" dot)* "\""; -sstring = "'" ((esc \ ['] ) | "\\" dot)* "'" ; -letter = [a-zA-Z]; -digit = [0-9]; -number = "0" | ("-"? [1-9] digit*); +/* $Id: scanner.re 663 2007-04-01 11:22:15Z helly $ */ +#include +#include +#include +#include +#include "scanner.h" +#include "parser.h" +#include "y.tab.h" +#include "globals.h" +#include "dfa.h" + +extern YYSTYPE yylval; + +#ifndef MAX +#define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + +#define BSIZE 8192 + +#define YYCTYPE unsigned char +#define YYCURSOR cursor +#define YYLIMIT lim +#define YYMARKER ptr +#define YYFILL(n) {cursor = fill(cursor);} + +#define RETURN(i) {cur = cursor; return i;} + +namespace re2c +{ + +Scanner::Scanner(const char *fn, std::istream& i, std::ostream& o) + : in(i) + , out(o) + , bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL) + , top(NULL), eof(NULL), tchar(0), tline(0), cline(1), iscfg(0), filename(fn) +{ + ; +} + +char *Scanner::fill(char *cursor) +{ + if(!eof) + { + uint cnt = tok - bot; + if(cnt) + { + memcpy(bot, tok, lim - tok); + tok = bot; + ptr -= cnt; + cursor -= cnt; + pos -= cnt; + lim -= cnt; + } + if((top - lim) < BSIZE) + { + char *buf = new char[(lim - bot) + BSIZE]; + memcpy(buf, tok, lim - tok); + tok = buf; + ptr = &buf[ptr - bot]; + cursor = &buf[cursor - bot]; + pos = &buf[pos - bot]; + lim = &buf[lim - bot]; + top = &lim[BSIZE]; + delete [] bot; + bot = buf; + } + in.read(lim, BSIZE); + if ((cnt = in.gcount()) != BSIZE ) + { + eof = &lim[cnt]; *eof++ = '\0'; + } + lim += cnt; + } + return cursor; +} + +/*!re2c +zero = "\000"; +any = [\000-\377]; +dot = any \ [\n]; +esc = dot \ [\\]; +istring = "[" "^" ((esc \ [\]]) | "\\" dot)* "]" ; +cstring = "[" ((esc \ [\]]) | "\\" dot)* "]" ; +dstring = "\"" ((esc \ ["] ) | "\\" dot)* "\""; +sstring = "'" ((esc \ ['] ) | "\\" dot)* "'" ; +letter = [a-zA-Z]; +digit = [0-9]; +number = "0" | ("-"? [1-9] digit*); name = (letter|"_") (letter|digit|"_")*; cname = ":" name; -space = [ \t]; -eol = ("\r\n" | "\n"); -config = "re2c" cname+; -value = [^\r\n; \t]* | dstring | sstring; -*/ - -int Scanner::echo() -{ - char *cursor = cur; - bool ignore_eoc = false; - int ignore_cnt = 0; - - if (eof && cursor == eof) // Catch EOF - { - return 0; - } - - tok = cursor; -echo: -/*!re2c - "/*!re2c" { - if (bUsedYYMaxFill && bSinglePass) { - fatal("found scanner block after YYMAXFILL declaration"); - } - out.write((const char*)(tok), (const char*)(&cursor[-7]) - (const char*)(tok)); - tok = cursor; - RETURN(1); - } - "/*!max:re2c" { - if (bUsedYYMaxFill) { - fatal("cannot generate YYMAXFILL twice"); - } - out << "#define YYMAXFILL " << maxFill << std::endl; - tok = pos = cursor; - ignore_eoc = true; - bUsedYYMaxFill = true; - goto echo; - } - "/*!getstate:re2c" { - tok = pos = cursor; - genGetState(out, topIndent, 0); - ignore_eoc = true; - goto echo; - } - "/*!ignore:re2c" { - tok = pos = cursor; - ignore_eoc = true; - goto echo; - } - "*" "/" "\r"? "\n" { - cline++; - if (ignore_eoc) { - if (ignore_cnt) { - out << sourceFileInfo; - } - ignore_eoc = false; - ignore_cnt = 0; - } else { - out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok)); - } - tok = pos = cursor; - goto echo; - } - "*" "/" { - if (ignore_eoc) { - if (ignore_cnt) { - out << "\n" << sourceFileInfo; - } - ignore_eoc = false; - ignore_cnt = 0; - } else { - out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok)); - } - tok = pos = cursor; - goto echo; - } - "\n" { - if (ignore_eoc) { - ignore_cnt++; - } else { - out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok)); - } - tok = pos = cursor; cline++; - goto echo; - } - zero { - if (!ignore_eoc) { - out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok) - 1); // -1 so we don't write out the \0 - } - if(cursor == eof) { - RETURN(0); - } - } - any { - goto echo; - } -*/ -} - - -int Scanner::scan() -{ - char *cursor = cur; - uint depth; - -scan: - tchar = cursor - pos; - tline = cline; - tok = cursor; - if (iscfg == 1) - { - goto config; - } - else if (iscfg == 2) - { - goto value; - } -/*!re2c - "{" { depth = 1; - goto code; - } - "/*" { depth = 1; - goto comment; } - - "*/" { tok = cursor; - RETURN(0); } - - dstring { cur = cursor; - yylval.regexp = strToRE(token()); - return STRING; } - - sstring { cur = cursor; - yylval.regexp = strToCaseInsensitiveRE(token()); - return STRING; } - - "\"" { fatal("unterminated string constant (missing \")"); } - "'" { fatal("unterminated string constant (missing ')"); } - - istring { cur = cursor; - yylval.regexp = invToRE(token()); - return RANGE; } - - cstring { cur = cursor; - yylval.regexp = ranToRE(token()); - return RANGE; } - - "[" { fatal("unterminated range (missing ])"); } - - [()|=;/\\] { RETURN(*tok); } - - [*+?] { yylval.op = *tok; - RETURN(CLOSE); } - - "{0,}" { yylval.op = '*'; - RETURN(CLOSE); } - - "{" [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1); - yylval.extop.maxsize = atoi((char *)tok+1); - RETURN(CLOSESIZE); } - - "{" [0-9]+ "," [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1); - yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1)); - RETURN(CLOSESIZE); } - - "{" [0-9]+ ",}" { yylval.extop.minsize = atoi((char *)tok+1); - yylval.extop.maxsize = -1; - RETURN(CLOSESIZE); } - - "{" [0-9]* "," { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); } - - config { cur = cursor; - tok+= 5; /* skip "re2c:" */ - iscfg = 1; - yylval.str = new Str(token()); - return CONFIG; - } - - name { cur = cursor; - yylval.symbol = Symbol::find(token()); - return ID; } - - "." { cur = cursor; - yylval.regexp = mkDot(); - return RANGE; - } - - space+ { goto scan; } - - eol { if(cursor == eof) RETURN(0); - pos = cursor; cline++; - goto scan; - } - - any { std::ostringstream msg; - msg << "unexpected character: "; - prtChOrHex(msg, *tok); - fatal(msg.str().c_str()); - goto scan; - } -*/ - -code: -/*!re2c - "}" { if(--depth == 0){ - cur = cursor; - yylval.token = new Token(token(), tline); - return CODE; - } - goto code; } - "{" { ++depth; - goto code; } - "\n" { if(cursor == eof) fatal("missing '}'"); - pos = cursor; cline++; - goto code; - } - zero { if(cursor == eof) { - if (depth) fatal("missing '}'"); - RETURN(0); - } - goto code; - } - dstring | sstring | any { goto code; } -*/ - -comment: -/*!re2c - "*/" { if(--depth == 0) - goto scan; - else - goto comment; } - "/*" { ++depth; - fatal("ambiguous /* found"); - goto comment; } - "\n" { if(cursor == eof) RETURN(0); - tok = pos = cursor; cline++; - goto comment; - } - any { if(cursor == eof) RETURN(0); - goto comment; } -*/ - -config: -/*!re2c - space+ { goto config; } - "=" space* { iscfg = 2; - cur = cursor; - RETURN('='); - } - any { fatal("missing '='"); } -*/ - -value: -/*!re2c - number { cur = cursor; - yylval.number = atoi(token().to_string().c_str()); - iscfg = 0; - return NUMBER; - } - value { cur = cursor; - yylval.str = new Str(token()); - iscfg = 0; - return VALUE; - } -*/ -} - -void Scanner::fatal(uint ofs, const char *msg) const -{ - out.flush(); -#ifdef _MSC_VER - std::cerr << filename << "(" << tline << "): error : " - << "column " << (tchar + ofs + 1) << ": " - << msg << std::endl; -#else - std::cerr << "re2c: error: " - << "line " << tline << ", column " << (tchar + ofs + 1) << ": " - << msg << std::endl; -#endif - exit(1); -} +space = [ \t]; +eol = ("\r\n" | "\n"); +config = "re2c" cname+; +value = [^\r\n; \t]* | dstring | sstring; +*/ + +int Scanner::echo() +{ + char *cursor = cur; + bool ignore_eoc = false; + int ignore_cnt = 0; + + if (eof && cursor == eof) // Catch EOF + { + return 0; + } + + tok = cursor; +echo: +/*!re2c + "/*!re2c" { + if (bUsedYYMaxFill && bSinglePass) { + fatal("found scanner block after YYMAXFILL declaration"); + } + out.write((const char*)(tok), (const char*)(&cursor[-7]) - (const char*)(tok)); + tok = cursor; + RETURN(1); + } + "/*!max:re2c" { + if (bUsedYYMaxFill) { + fatal("cannot generate YYMAXFILL twice"); + } + out << "#define YYMAXFILL " << maxFill << std::endl; + tok = pos = cursor; + ignore_eoc = true; + bUsedYYMaxFill = true; + goto echo; + } + "/*!getstate:re2c" { + tok = pos = cursor; + genGetState(out, topIndent, 0); + ignore_eoc = true; + goto echo; + } + "/*!ignore:re2c" { + tok = pos = cursor; + ignore_eoc = true; + goto echo; + } + "*" "/" "\r"? "\n" { + cline++; + if (ignore_eoc) { + if (ignore_cnt) { + out << sourceFileInfo; + } + ignore_eoc = false; + ignore_cnt = 0; + } else { + out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok)); + } + tok = pos = cursor; + goto echo; + } + "*" "/" { + if (ignore_eoc) { + if (ignore_cnt) { + out << "\n" << sourceFileInfo; + } + ignore_eoc = false; + ignore_cnt = 0; + } else { + out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok)); + } + tok = pos = cursor; + goto echo; + } + "\n" { + if (ignore_eoc) { + ignore_cnt++; + } else { + out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok)); + } + tok = pos = cursor; cline++; + goto echo; + } + zero { + if (!ignore_eoc) { + out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok) - 1); // -1 so we don't write out the \0 + } + if(cursor == eof) { + RETURN(0); + } + } + any { + goto echo; + } +*/ +} + + +int Scanner::scan() +{ + char *cursor = cur; + uint depth; + +scan: + tchar = cursor - pos; + tline = cline; + tok = cursor; + if (iscfg == 1) + { + goto config; + } + else if (iscfg == 2) + { + goto value; + } +/*!re2c + "{" { depth = 1; + goto code; + } + "/*" { depth = 1; + goto comment; } + + "*/" { tok = cursor; + RETURN(0); } + + dstring { cur = cursor; + yylval.regexp = strToRE(token()); + return STRING; } + + sstring { cur = cursor; + yylval.regexp = strToCaseInsensitiveRE(token()); + return STRING; } + + "\"" { fatal("unterminated string constant (missing \")"); } + "'" { fatal("unterminated string constant (missing ')"); } + + istring { cur = cursor; + yylval.regexp = invToRE(token()); + return RANGE; } + + cstring { cur = cursor; + yylval.regexp = ranToRE(token()); + return RANGE; } + + "[" { fatal("unterminated range (missing ])"); } + + [()|=;/\\] { RETURN(*tok); } + + [*+?] { yylval.op = *tok; + RETURN(CLOSE); } + + "{0,}" { yylval.op = '*'; + RETURN(CLOSE); } + + "{" [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1); + yylval.extop.maxsize = atoi((char *)tok+1); + RETURN(CLOSESIZE); } + + "{" [0-9]+ "," [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1); + yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1)); + RETURN(CLOSESIZE); } + + "{" [0-9]+ ",}" { yylval.extop.minsize = atoi((char *)tok+1); + yylval.extop.maxsize = -1; + RETURN(CLOSESIZE); } + + "{" [0-9]* "," { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); } + + config { cur = cursor; + tok+= 5; /* skip "re2c:" */ + iscfg = 1; + yylval.str = new Str(token()); + return CONFIG; + } + + name { cur = cursor; + yylval.symbol = Symbol::find(token()); + return ID; } + + "." { cur = cursor; + yylval.regexp = mkDot(); + return RANGE; + } + + space+ { goto scan; } + + eol { if(cursor == eof) RETURN(0); + pos = cursor; cline++; + goto scan; + } + + any { std::ostringstream msg; + msg << "unexpected character: "; + prtChOrHex(msg, *tok); + fatal(msg.str().c_str()); + goto scan; + } +*/ + +code: +/*!re2c + "}" { if(--depth == 0){ + cur = cursor; + yylval.token = new Token(token(), tline); + return CODE; + } + goto code; } + "{" { ++depth; + goto code; } + "\n" { if(cursor == eof) fatal("missing '}'"); + pos = cursor; cline++; + goto code; + } + zero { if(cursor == eof) { + if (depth) fatal("missing '}'"); + RETURN(0); + } + goto code; + } + dstring | sstring | any { goto code; } +*/ + +comment: +/*!re2c + "*/" { if(--depth == 0) + goto scan; + else + goto comment; } + "/*" { ++depth; + fatal("ambiguous /* found"); + goto comment; } + "\n" { if(cursor == eof) RETURN(0); + tok = pos = cursor; cline++; + goto comment; + } + any { if(cursor == eof) RETURN(0); + goto comment; } +*/ + +config: +/*!re2c + space+ { goto config; } + "=" space* { iscfg = 2; + cur = cursor; + RETURN('='); + } + any { fatal("missing '='"); } +*/ + +value: +/*!re2c + number { cur = cursor; + yylval.number = atoi(token().to_string().c_str()); + iscfg = 0; + return NUMBER; + } + value { cur = cursor; + yylval.str = new Str(token()); + iscfg = 0; + return VALUE; + } +*/ +} + +void Scanner::fatal(uint ofs, const char *msg) const +{ + out.flush(); +#ifdef _MSC_VER + std::cerr << filename << "(" << tline << "): error : " + << "column " << (tchar + ofs + 1) << ": " + << msg << std::endl; +#else + std::cerr << "re2c: error: " + << "line " << tline << ", column " << (tchar + ofs + 1) << ": " + << msg << std::endl; +#endif + exit(1); +} Scanner::~Scanner() { @@ -376,6 +376,6 @@ Scanner::~Scanner() delete [] bot; } } - -} // end namespace re2c - + +} // end namespace re2c + diff --git a/tools/re2c/stream_lc.h b/tools/re2c/stream_lc.h index 92a56c309b..cc6682291b 100644 --- a/tools/re2c/stream_lc.h +++ b/tools/re2c/stream_lc.h @@ -2,7 +2,7 @@ Author: Marcus Boerger */ -/* $Id: stream_lc.h,v 1.10 2006/02/26 20:36:09 helly Exp $ */ +/* $Id: stream_lc.h 767 2007-06-26 15:21:10Z helly $ */ #ifndef _stream_lc_h #define _stream_lc_h diff --git a/tools/re2c/substr.cc b/tools/re2c/substr.cc index be667f2902..7796c1dc07 100644 --- a/tools/re2c/substr.cc +++ b/tools/re2c/substr.cc @@ -1,4 +1,4 @@ -/* $Id: substr.cc,v 1.11 2006/02/26 20:30:54 helly Exp $ */ +/* $Id: substr.cc 546 2006-05-25 13:40:14Z helly $ */ #include #include #include "substr.h" diff --git a/tools/re2c/substr.h b/tools/re2c/substr.h index eec50614ab..7b56e0042a 100644 --- a/tools/re2c/substr.h +++ b/tools/re2c/substr.h @@ -1,4 +1,4 @@ -/* $Id: substr.h,v 1.10 2006/01/01 13:42:10 helly Exp $ */ +/* $Id: substr.h 530 2006-05-25 13:34:33Z helly $ */ #ifndef _substr_h #define _substr_h diff --git a/tools/re2c/token.h b/tools/re2c/token.h index b0bb6cc25c..4abfbff010 100644 --- a/tools/re2c/token.h +++ b/tools/re2c/token.h @@ -1,4 +1,4 @@ -/* $Id: token.h,v 1.4 2004/11/01 04:35:57 nuffer Exp $ */ +/* $Id: token.h 547 2006-05-25 13:40:35Z helly $ */ #ifndef _token_h #define _token_h diff --git a/tools/re2c/translate.cc b/tools/re2c/translate.cc index 3955622ebe..0393856faf 100644 --- a/tools/re2c/translate.cc +++ b/tools/re2c/translate.cc @@ -1,4 +1,4 @@ -/* $Id: translate.cc,v 1.5 2005/12/28 18:33:37 helly Exp $ */ +/* $Id: translate.cc 713 2007-04-29 15:33:47Z helly $ */ #include "globals.h" namespace re2c diff --git a/tools/xlatcc/gen.c b/tools/xlatcc/gen.c index a022933c73..010dec693b 100644 --- a/tools/xlatcc/gen.c +++ b/tools/xlatcc/gen.c @@ -250,7 +250,7 @@ int main (int argc, char **argv) printf ("Usage: %s \n", argv[0]); return -1; } -#if !defined(NDEBUG) && 1 +#if !defined(NDEBUG) && 0 ParseTrace(fopen("trace.txt", "w"), ":"); #endif IncludeFile (argv[1]); diff --git a/tools/xlatcc/xlat-parse.c b/tools/xlatcc/xlat-parse.c index 43dc70c2d3..33504302de 100644 --- a/tools/xlatcc/xlat-parse.c +++ b/tools/xlatcc/xlat-parse.c @@ -1,2131 +1,2167 @@ -/* Driver template for the LEMON parser generator. -** The author disclaims copyright to this source code. -*/ -/* First off, code is included which follows the "include" declaration -** in the input file. */ -#include -#include -#include -#line 1 "xlat-parse.y" - -#include "xlat.h" -#include "xlat-parse.h" -#include -#include - -int yyerror (char *s); - -typedef struct _Symbol -{ - struct _Symbol *Next; - int Value; - char Sym[1]; -} Symbol; - -static bool FindToken (char *tok, int *type); -static void AddSym (char *sym, int val); -static bool FindSym (char *sym, Symbol **val); - -static int EnumVal; - -struct ListFilter -{ - WORD filter; - BYTE value; -}; - -typedef struct _morefilters -{ - struct _morefilters *next; - struct ListFilter filter; -} MoreFilters; - -typedef struct _morelines -{ - struct _morelines *next; - BoomArg arg; -} MoreLines; - -typedef struct _specialargs -{ - BYTE addflags; - BYTE args[5]; -} SpecialArgs; - -typedef struct _boomarg -{ - BYTE constant; - WORD mask; - MoreFilters *filters; -} ParseBoomArg; - -typedef union YYSTYPE -{ - int val; - char sym[80]; - char string[80]; - Symbol *symval; -} YYSTYPE; - -#include -#include - -int yylex (YYSTYPE *yylval) -{ - char token[80]; - int toksize; - int c; - -loop: - while (Source == NULL) - { - if (!EndFile ()) - return 0; - } - while (isspace (c = fgetc (Source)) && c != EOF) - { - if (c == '\n') - SourceLine++; - } - - if (c == EOF) - { - if (EndFile ()) - goto loop; - return 0; - } - if (isdigit (c)) - { - int buildup = c - '0'; - if (c == '0') - { - c = fgetc (Source); - if (c == 'x' || c == 'X') - { - for (;;) - { - c = fgetc (Source); - if (isdigit (c)) - { - buildup = (buildup<<4) + c - '0'; - } - else if (c >= 'a' && c <= 'f') - { - buildup = (buildup<<4) + c - 'a' + 10; - } - else if (c >= 'A' && c <= 'F') - { - buildup = (buildup<<4) + c - 'A' + 10; - } - else - { - ungetc (c, Source); - yylval->val = buildup; - return NUM; - } - } - } - else - { - ungetc (c, Source); - } - } - while (isdigit (c = fgetc (Source))) - { - buildup = buildup*10 + c - '0'; - } - ungetc (c, Source); - yylval->val = buildup; - return NUM; - } - if (isalpha (c)) - { - int buildup = 0; - - token[0] = c; - toksize = 1; - while (toksize < 79 && (isalnum (c = fgetc (Source)) || c == '_')) - { - token[toksize++] = c; - } - token[toksize] = 0; - if (toksize == 79 && isalnum (c)) - { - while (isalnum (c = fgetc (Source))) - ; - } - ungetc (c, Source); - if (FindToken (token, &buildup)) - { - return buildup; - } - if (FindSym (token, &yylval->symval)) - { - return SYMNUM; - } - strcpy (yylval->sym, token); - return SYM; - } - if (c == '/') - { - c = fgetc (Source); - if (c == '*') - { - for (;;) - { - while ((c = fgetc (Source)) != '*' && c != EOF) - { - if (c == '\n') - SourceLine++; - } - if (c == EOF) - return 0; - if ((c = fgetc (Source)) == '/') - goto loop; - if (c == EOF) - return 0; - ungetc (c, Source); - } - } - else if (c == '/') - { - while ((c = fgetc (Source)) != '\n' && c != EOF) - ; - if (c == '\n') - SourceLine++; - else if (c == EOF) - return 0; - goto loop; - } - else - { - ungetc (c, Source); - return DIVIDE; - } - } - if (c == '"') - { - int tokensize = 0; - while ((c = fgetc (Source)) != '"' && c != EOF) - { - yylval->string[tokensize++] = c; - } - yylval->string[tokensize] = 0; - return STRING; - } - if (c == '|') - { - c = fgetc (Source); - if (c == '=') - return OR_EQUAL; - ungetc (c, Source); - return OR; - } - switch (c) - { - case '^': return XOR; - case '&': return AND; - case '-': return MINUS; - case '+': return PLUS; - case '*': return MULTIPLY; - case '(': return LPAREN; - case ')': return RPAREN; - case ',': return COMMA; - case '{': return LBRACE; - case '}': return RBRACE; - case '=': return EQUALS; - case ';': return SEMICOLON; - case ':': return COLON; - case '[': return LBRACKET; - case ']': return RBRACKET; - default: return 0; - } -} - -void *ParseAlloc(void *(*mallocProc)(size_t)); -void Parse(void *yyp, int yymajor, YYSTYPE yyminor); -void ParseFree(void *p, void (*freeProc)(void*)); -void ParseTrace(FILE *TraceFILE, char *zTracePrompt); - -void yyparse (void) -{ - void *pParser = ParseAlloc (malloc); - YYSTYPE token; - int tokentype; - - while ((tokentype = yylex(&token)) != 0) - { - Parse (pParser, tokentype, token); - } - memset (&token, 0, sizeof(token)); - Parse (pParser, 0, token); - ParseFree (pParser, free); -} - -static Symbol *FirstSym; - -static void AddSym (char *sym, int val) -{ - Symbol *syme = malloc (strlen (sym) + sizeof(Symbol)); - syme->Next = FirstSym; - syme->Value = val; - strcpy (syme->Sym, sym); - FirstSym = syme; -} - -static bool FindSym (char *sym, Symbol **val) -{ - Symbol *syme = FirstSym; - - while (syme != NULL) - { - if (strcmp (syme->Sym, sym) == 0) - { - *val = syme; - return 1; - } - syme = syme->Next; - } - return 0; -} - -static bool FindToken (char *tok, int *type) -{ - static const char tokens[][8] = - { - "endl", "print", "include", "special", "define", "enum", - "arg5", "arg4", "arg3", "arg2", "flags", "lineid", "tag" - - }; - static const short types[] = - { - ENDL, PRINT, INCLUDE, SPECIAL, DEFINE, ENUM, - ARG5, ARG4, ARG3, ARG2, FLAGS, LINEID, TAG - }; - int i; - - for (i = sizeof(tokens)/sizeof(tokens[0])-1; i >= 0; i--) - { - if (strcmp (tok, tokens[i]) == 0) - { - *type = types[i]; - return 1; - } - } - return 0; -} - -int yyerror (char *s) -{ - if (SourceName != NULL) - printf ("%s, line %d: %s\n", SourceName, SourceLine, s); - else - printf ("%s\n", s); - return 0; -} - -#line 328 "xlat-parse.c" -/* Next is all token values, in a form suitable for use by makeheaders. -** This section will be null unless lemon is run with the -m switch. -*/ -/* -** These constants (all generated automatically by the parser generator) -** specify the various kinds of tokens (terminals) that the parser -** understands. -** -** Each symbol here is a terminal symbol in the grammar. -*/ -/* Make sure the INTERFACE macro is defined. -*/ -#ifndef INTERFACE -# define INTERFACE 1 -#endif -/* The next thing included is series of defines which control -** various aspects of the generated parser. -** YYCODETYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 terminals -** and nonterminals. "int" is used otherwise. -** YYNOCODE is a number of type YYCODETYPE which corresponds -** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash -** table. -** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. -** YYACTIONTYPE is the data type used for storing terminal -** and nonterminal numbers. "unsigned char" is -** used if there are fewer than 250 rules and -** states combined. "int" is used otherwise. -** ParseTOKENTYPE is the data type used for minor tokens given -** directly to the parser from the tokenizer. -** YYMINORTYPE is the data type used for all minor tokens. -** This is typically a union of many types, one of -** which is ParseTOKENTYPE. The entry in the union -** for base tokens is called "yy0". -** YYSTACKDEPTH is the maximum depth of the parser's stack. If -** zero the stack is dynamically sized using realloc() -** ParseARG_SDECL A static variable declaration for the %extra_argument -** ParseARG_PDECL A parameter declaration for the %extra_argument -** ParseARG_STORE Code to store %extra_argument into yypParser -** ParseARG_FETCH Code to extract %extra_argument from yypParser -** YYNSTATE the combined number of states. -** YYNRULE the number of rules in the grammar -** YYERRORSYMBOL is the code number of the error symbol. If not -** defined, then do no error processing. -*/ -#define YYCODETYPE unsigned char -#define YYNOCODE 66 -#define YYACTIONTYPE unsigned short int -#define ParseTOKENTYPE YYSTYPE -typedef union { - ParseTOKENTYPE yy0; - MoreLines * yy49; - SpecialArgs yy57; - BoomArg yy58; - int yy72; - ParseBoomArg yy83; - MoreFilters * yy87; - struct ListFilter yy124; - int yy131; -} YYMINORTYPE; -#define YYSTACKDEPTH 100 -#define ParseARG_SDECL -#define ParseARG_PDECL -#define ParseARG_FETCH -#define ParseARG_STORE -#define YYNSTATE 173 -#define YYNRULE 93 -#define YYERRORSYMBOL 37 -#define YYERRSYMDT yy131 -#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) -#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) -#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) - -/* Next are that tables used to determine what action to take based on the -** current state and lookahead token. These tables are used to implement -** functions that take a state number and lookahead value and return an -** action integer. -** -** Suppose the action integer is N. Then the action is determined as -** follows -** -** 0 <= N < YYNSTATE Shift N. That is, push the lookahead -** token onto the stack and goto state N. -** -** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. -** -** N == YYNSTATE+YYNRULE A syntax error has occurred. -** -** N == YYNSTATE+YYNRULE+1 The parser accepts its input. -** -** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused -** slots in the yy_action[] table. -** -** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as -** -** yy_action[ yy_shift_ofst[S] + X ] -** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. -** -** The formula above is for computing the action when the lookahead is -** a terminal symbol. If the lookahead is a non-terminal (as occurs after -** a reduce action) then the yy_reduce_ofst[] array is used in place of -** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of -** YY_SHIFT_USE_DFLT. -** -** The following are the tables generated in this section: -** -** yy_action[] A single table containing all actions. -** yy_lookahead[] A table containing the lookahead for each entry in -** yy_action. Used to detect hash collisions. -** yy_shift_ofst[] For each state, the offset into yy_action for -** shifting terminals. -** yy_reduce_ofst[] For each state, the offset into yy_action for -** shifting non-terminals after a reduce. -** yy_default[] Default action for each state. -*/ -static const YYACTIONTYPE yy_action[] = { - /* 0 */ 65, 41, 32, 35, 52, 42, 28, 51, 77, 117, - /* 10 */ 267, 163, 160, 149, 148, 147, 146, 145, 144, 143, - /* 20 */ 30, 80, 14, 128, 164, 156, 151, 23, 123, 127, - /* 30 */ 55, 4, 152, 102, 33, 108, 80, 119, 128, 107, - /* 40 */ 5, 111, 113, 22, 2, 41, 32, 35, 52, 42, - /* 50 */ 28, 51, 32, 35, 52, 42, 28, 51, 19, 3, - /* 60 */ 41, 32, 35, 52, 42, 28, 51, 52, 42, 28, - /* 70 */ 51, 135, 116, 41, 32, 35, 52, 42, 28, 51, - /* 80 */ 41, 32, 35, 52, 42, 28, 51, 28, 51, 11, - /* 90 */ 9, 168, 169, 170, 171, 172, 77, 106, 26, 66, - /* 100 */ 41, 32, 35, 52, 42, 28, 51, 35, 52, 42, - /* 110 */ 28, 51, 10, 27, 61, 41, 32, 35, 52, 42, - /* 120 */ 28, 51, 68, 120, 100, 139, 165, 49, 18, 166, - /* 130 */ 41, 32, 35, 52, 42, 28, 51, 55, 4, 101, - /* 140 */ 167, 12, 40, 29, 43, 41, 32, 35, 52, 42, - /* 150 */ 28, 51, 136, 131, 113, 91, 66, 98, 16, 115, - /* 160 */ 41, 32, 35, 52, 42, 28, 51, 124, 130, 159, - /* 170 */ 56, 59, 129, 37, 61, 41, 32, 35, 52, 42, - /* 180 */ 28, 51, 138, 109, 48, 57, 60, 154, 20, 54, - /* 190 */ 41, 32, 35, 52, 42, 28, 51, 13, 62, 90, - /* 200 */ 89, 17, 15, 21, 7, 41, 32, 35, 52, 42, - /* 210 */ 28, 51, 39, 132, 63, 99, 94, 87, 31, 142, - /* 220 */ 41, 32, 35, 52, 42, 28, 51, 134, 133, 67, - /* 230 */ 88, 157, 74, 41, 32, 35, 52, 42, 28, 51, - /* 240 */ 41, 32, 35, 52, 42, 28, 51, 84, 161, 30, - /* 250 */ 141, 104, 86, 38, 156, 151, 23, 1, 153, 6, - /* 260 */ 96, 41, 32, 35, 52, 42, 28, 51, 41, 32, - /* 270 */ 35, 52, 42, 28, 51, 8, 41, 32, 35, 52, - /* 280 */ 42, 28, 51, 25, 103, 64, 97, 125, 71, 95, - /* 290 */ 24, 76, 41, 32, 35, 52, 42, 28, 51, 150, - /* 300 */ 158, 78, 268, 162, 268, 45, 83, 41, 32, 35, - /* 310 */ 52, 42, 28, 51, 92, 81, 82, 268, 70, 69, - /* 320 */ 44, 85, 41, 32, 35, 52, 42, 28, 51, 268, - /* 330 */ 72, 79, 75, 58, 73, 36, 93, 41, 32, 35, - /* 340 */ 52, 42, 28, 51, 268, 268, 268, 268, 268, 268, - /* 350 */ 46, 268, 41, 32, 35, 52, 42, 28, 51, 268, - /* 360 */ 268, 268, 268, 268, 268, 34, 268, 41, 32, 35, - /* 370 */ 52, 42, 28, 51, 268, 268, 268, 268, 268, 268, - /* 380 */ 47, 268, 41, 32, 35, 52, 42, 28, 51, 268, - /* 390 */ 268, 268, 268, 268, 268, 50, 268, 41, 32, 35, - /* 400 */ 52, 42, 28, 51, 268, 268, 268, 268, 268, 268, - /* 410 */ 53, 88, 41, 32, 35, 52, 42, 28, 51, 30, - /* 420 */ 268, 268, 30, 268, 156, 151, 23, 156, 151, 23, - /* 430 */ 30, 110, 104, 140, 137, 156, 151, 23, 268, 268, - /* 440 */ 30, 268, 268, 268, 105, 156, 151, 23, 268, 30, - /* 450 */ 114, 126, 30, 268, 156, 151, 23, 156, 151, 23, - /* 460 */ 30, 268, 268, 30, 268, 156, 151, 23, 156, 151, - /* 470 */ 23, 155, 268, 268, 268, 268, 268, 268, 268, 268, - /* 480 */ 122, 268, 268, 118, 268, 268, 268, 268, 268, 268, - /* 490 */ 268, 121, 268, 268, 112, -}; -static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 38, 1, 2, 3, 4, 5, 6, 7, 38, 39, - /* 10 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 20 */ 4, 38, 60, 40, 41, 9, 10, 11, 28, 13, - /* 30 */ 44, 45, 46, 17, 14, 19, 38, 21, 40, 41, - /* 40 */ 24, 61, 62, 27, 11, 1, 2, 3, 4, 5, - /* 50 */ 6, 7, 2, 3, 4, 5, 6, 7, 14, 22, - /* 60 */ 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, - /* 70 */ 7, 12, 18, 1, 2, 3, 4, 5, 6, 7, - /* 80 */ 1, 2, 3, 4, 5, 6, 7, 6, 7, 11, - /* 90 */ 11, 29, 30, 31, 32, 33, 38, 39, 26, 38, - /* 100 */ 1, 2, 3, 4, 5, 6, 7, 3, 4, 5, - /* 110 */ 6, 7, 43, 14, 38, 1, 2, 3, 4, 5, - /* 120 */ 6, 7, 38, 47, 63, 64, 42, 11, 14, 23, - /* 130 */ 1, 2, 3, 4, 5, 6, 7, 44, 45, 46, - /* 140 */ 34, 14, 14, 14, 14, 1, 2, 3, 4, 5, - /* 150 */ 6, 7, 25, 61, 62, 38, 38, 38, 14, 10, - /* 160 */ 1, 2, 3, 4, 5, 6, 7, 18, 12, 38, - /* 170 */ 38, 38, 22, 14, 38, 1, 2, 3, 4, 5, - /* 180 */ 6, 7, 64, 47, 14, 38, 38, 12, 14, 23, - /* 190 */ 1, 2, 3, 4, 5, 6, 7, 11, 38, 38, - /* 200 */ 38, 14, 14, 14, 14, 1, 2, 3, 4, 5, - /* 210 */ 6, 7, 14, 20, 38, 38, 38, 38, 14, 12, - /* 220 */ 1, 2, 3, 4, 5, 6, 7, 12, 15, 38, - /* 230 */ 38, 12, 38, 1, 2, 3, 4, 5, 6, 7, - /* 240 */ 1, 2, 3, 4, 5, 6, 7, 38, 28, 4, - /* 250 */ 58, 59, 38, 14, 9, 10, 11, 14, 12, 27, - /* 260 */ 38, 1, 2, 3, 4, 5, 6, 7, 1, 2, - /* 270 */ 3, 4, 5, 6, 7, 11, 1, 2, 3, 4, - /* 280 */ 5, 6, 7, 11, 18, 38, 26, 12, 38, 38, - /* 290 */ 23, 38, 1, 2, 3, 4, 5, 6, 7, 20, - /* 300 */ 38, 38, 65, 38, 65, 14, 38, 1, 2, 3, - /* 310 */ 4, 5, 6, 7, 38, 38, 38, 65, 38, 38, - /* 320 */ 14, 38, 1, 2, 3, 4, 5, 6, 7, 65, - /* 330 */ 38, 38, 38, 38, 38, 14, 38, 1, 2, 3, - /* 340 */ 4, 5, 6, 7, 65, 65, 65, 65, 65, 65, - /* 350 */ 14, 65, 1, 2, 3, 4, 5, 6, 7, 65, - /* 360 */ 65, 65, 65, 65, 65, 14, 65, 1, 2, 3, - /* 370 */ 4, 5, 6, 7, 65, 65, 65, 65, 65, 65, - /* 380 */ 14, 65, 1, 2, 3, 4, 5, 6, 7, 65, - /* 390 */ 65, 65, 65, 65, 65, 14, 65, 1, 2, 3, - /* 400 */ 4, 5, 6, 7, 65, 65, 65, 65, 65, 65, - /* 410 */ 14, 38, 1, 2, 3, 4, 5, 6, 7, 4, - /* 420 */ 65, 65, 4, 65, 9, 10, 11, 9, 10, 11, - /* 430 */ 4, 58, 59, 15, 16, 9, 10, 11, 65, 65, - /* 440 */ 4, 65, 65, 65, 18, 9, 10, 11, 65, 4, - /* 450 */ 35, 36, 4, 65, 9, 10, 11, 9, 10, 11, - /* 460 */ 4, 65, 65, 4, 65, 9, 10, 11, 9, 10, - /* 470 */ 11, 35, 65, 65, 65, 65, 65, 65, 65, 65, - /* 480 */ 35, 65, 65, 35, 65, 65, 65, 65, 65, 65, - /* 490 */ 65, 35, 65, 65, 35, -}; -#define YY_SHIFT_USE_DFLT (-1) -#define YY_SHIFT_MAX 128 -static const short yy_shift_ofst[] = { - /* 0 */ 16, 418, 418, 62, 62, 245, 245, 245, 415, 415, - /* 10 */ 245, 245, 245, 245, 54, 54, 456, 459, 448, 426, - /* 20 */ 445, 436, 245, 245, 245, 245, 245, 245, 245, 245, - /* 30 */ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, - /* 40 */ 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, - /* 50 */ 245, 245, 245, 245, 245, 106, 396, 381, 366, 351, - /* 60 */ 336, 321, 306, 291, 275, 267, 260, 239, 232, 0, - /* 70 */ 219, 204, 189, 174, 159, 144, 129, 114, 99, 79, - /* 80 */ 72, 59, 44, 411, 411, 411, 411, 411, 411, 411, - /* 90 */ 411, 411, 411, 411, 50, 104, 63, 149, 81, 81, - /* 100 */ 127, 279, 266, 272, 243, 264, 246, 220, 213, 215, - /* 110 */ 207, 193, 198, 188, 187, 186, 166, 175, 170, 150, - /* 120 */ 156, 130, 128, 116, 78, 37, 20, 33, 190, -}; -#define YY_REDUCE_USE_DFLT (-39) -#define YY_REDUCE_MAX 55 -static const short yy_reduce_ofst[] = { - /* 0 */ -38, 192, 373, 93, -14, 61, -2, -17, 58, -30, - /* 10 */ 84, 76, 118, 136, -20, 92, 296, 295, 294, 293, - /* 20 */ 292, 283, 281, 280, 278, 277, 276, 268, 265, 263, - /* 30 */ 262, 253, 251, 250, 247, 222, 214, 209, 194, 191, - /* 40 */ 179, 178, 177, 176, 162, 161, 160, 148, 147, 133, - /* 50 */ 132, 131, 119, 298, 117, 69, -}; -static const YYACTIONTYPE yy_default[] = { - /* 0 */ 185, 195, 195, 221, 221, 266, 266, 266, 236, 236, - /* 10 */ 266, 215, 266, 215, 205, 205, 266, 266, 266, 266, - /* 20 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, - /* 30 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, - /* 40 */ 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, - /* 50 */ 266, 266, 266, 266, 266, 266, 258, 257, 238, 266, - /* 60 */ 239, 216, 240, 261, 266, 266, 266, 243, 231, 266, - /* 70 */ 266, 247, 254, 253, 244, 252, 248, 251, 249, 266, - /* 80 */ 266, 266, 266, 250, 245, 255, 217, 264, 199, 241, - /* 90 */ 262, 209, 235, 259, 180, 182, 181, 266, 177, 176, - /* 100 */ 266, 266, 266, 266, 196, 266, 266, 266, 266, 266, - /* 110 */ 266, 266, 242, 206, 237, 266, 208, 266, 256, 266, - /* 120 */ 266, 260, 263, 266, 266, 266, 246, 266, 233, 204, - /* 130 */ 213, 207, 203, 202, 214, 201, 210, 200, 212, 211, - /* 140 */ 198, 197, 194, 193, 192, 191, 190, 189, 188, 187, - /* 150 */ 220, 175, 222, 219, 218, 265, 174, 184, 183, 179, - /* 160 */ 186, 232, 178, 173, 234, 223, 229, 230, 224, 225, - /* 170 */ 226, 227, 228, -}; -#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) - -/* The next table maps tokens into fallback tokens. If a construct -** like the following: -** -** %fallback ID X Y Z. -** -** appears in the grammer, then ID becomes a fallback token for X, Y, -** and Z. Whenever one of the tokens X, Y, or Z is input to the parser -** but it does not parse, the type of the token is changed to ID and -** the parse is retried before an error is thrown. -*/ -#ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { -}; -#endif /* YYFALLBACK */ - -/* The following structure represents a single element of the -** parser's stack. Information stored includes: -** -** + The state number for the parser at this level of the stack. -** -** + The value of the token stored at this level of the stack. -** (In other words, the "major" token.) -** -** + The semantic value stored at this level of the stack. This is -** the information used by the action routines in the grammar. -** It is sometimes called the "minor" token. -*/ -struct yyStackEntry { - int stateno; /* The state-number */ - int major; /* The major token value. This is the code - ** number for the token at this stack level */ - YYMINORTYPE minor; /* The user-supplied minor token value. This - ** is the value of the token */ -}; -typedef struct yyStackEntry yyStackEntry; - -/* The state of the parser is completely contained in an instance of -** the following structure */ -struct yyParser { - int yyidx; /* Index of top element in stack */ - int yyerrcnt; /* Shifts left before out of the error */ - ParseARG_SDECL /* A place to hold %extra_argument */ -#if YYSTACKDEPTH<=0 - int yystksz; /* Current side of the stack */ - yyStackEntry *yystack; /* The parser's stack */ -#else - yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ -#endif -}; -typedef struct yyParser yyParser; - -#ifndef NDEBUG -#include -static FILE *yyTraceFILE = 0; -static char *yyTracePrompt = 0; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* -** Turn parser tracing on by giving a stream to which to write the trace -** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL -** -** Inputs: -**
    -**
  • A FILE* to which trace output should be written. -** If NULL, then tracing is turned off. -**
  • A prefix string written at the beginning of every -** line of trace output. If NULL, then tracing is -** turned off. -**
-** -** Outputs: -** None. -*/ -void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ - yyTraceFILE = TraceFILE; - yyTracePrompt = zTracePrompt; - if( yyTraceFILE==0 ) yyTracePrompt = 0; - else if( yyTracePrompt==0 ) yyTraceFILE = 0; -} -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing shifts, the names of all terminals and nonterminals -** are required. The following table supplies these names */ -static const char *const yyTokenName[] = { - "$", "OR", "XOR", "AND", - "MINUS", "PLUS", "MULTIPLY", "DIVIDE", - "NEG", "NUM", "SYMNUM", "LPAREN", - "RPAREN", "PRINT", "COMMA", "STRING", - "ENDL", "DEFINE", "SYM", "INCLUDE", - "RBRACE", "ENUM", "LBRACE", "EQUALS", - "SPECIAL", "SEMICOLON", "COLON", "LBRACKET", - "RBRACKET", "FLAGS", "ARG2", "ARG3", - "ARG4", "ARG5", "OR_EQUAL", "TAG", - "LINEID", "error", "exp", "special_args", - "list_val", "arg_list", "boom_args", "boom_op", - "boom_selector", "boom_line", "boom_body", "maybe_argcount", - "main", "translation_unit", "external_declaration", "define_statement", - "include_statement", "print_statement", "enum_statement", "linetype_declaration", - "boom_declaration", "special_declaration", "print_list", "print_item", - "enum_open", "enum_list", "single_enum", "special_list", - "special_def", -}; -#endif /* NDEBUG */ - -#ifndef NDEBUG -/* For tracing reduce actions, the names of all rules are required. -*/ -static const char *const yyRuleName[] = { - /* 0 */ "main ::= translation_unit", - /* 1 */ "exp ::= NUM", - /* 2 */ "exp ::= SYMNUM", - /* 3 */ "exp ::= exp PLUS exp", - /* 4 */ "exp ::= exp MINUS exp", - /* 5 */ "exp ::= exp MULTIPLY exp", - /* 6 */ "exp ::= exp DIVIDE exp", - /* 7 */ "exp ::= exp OR exp", - /* 8 */ "exp ::= exp AND exp", - /* 9 */ "exp ::= exp XOR exp", - /* 10 */ "exp ::= MINUS exp", - /* 11 */ "exp ::= LPAREN exp RPAREN", - /* 12 */ "translation_unit ::=", - /* 13 */ "translation_unit ::= external_declaration", - /* 14 */ "external_declaration ::= define_statement", - /* 15 */ "external_declaration ::= include_statement", - /* 16 */ "external_declaration ::= print_statement", - /* 17 */ "external_declaration ::= enum_statement", - /* 18 */ "external_declaration ::= linetype_declaration", - /* 19 */ "external_declaration ::= boom_declaration", - /* 20 */ "external_declaration ::= special_declaration", - /* 21 */ "print_statement ::= PRINT LPAREN print_list RPAREN", - /* 22 */ "print_list ::=", - /* 23 */ "print_list ::= print_item", - /* 24 */ "print_list ::= print_item COMMA print_list", - /* 25 */ "print_item ::= STRING", - /* 26 */ "print_item ::= exp", - /* 27 */ "print_item ::= ENDL", - /* 28 */ "define_statement ::= DEFINE SYM LPAREN exp RPAREN", - /* 29 */ "include_statement ::= INCLUDE STRING", - /* 30 */ "enum_statement ::= enum_open enum_list RBRACE", - /* 31 */ "enum_open ::= ENUM LBRACE", - /* 32 */ "enum_list ::=", - /* 33 */ "enum_list ::= single_enum", - /* 34 */ "enum_list ::= single_enum COMMA enum_list", - /* 35 */ "single_enum ::= SYM", - /* 36 */ "single_enum ::= SYM EQUALS exp", - /* 37 */ "special_declaration ::= SPECIAL special_list SEMICOLON", - /* 38 */ "special_list ::= special_def", - /* 39 */ "special_list ::= special_list COMMA special_def", - /* 40 */ "special_def ::= exp COLON SYM LPAREN maybe_argcount RPAREN", - /* 41 */ "special_def ::= exp COLON SYMNUM LPAREN maybe_argcount RPAREN", - /* 42 */ "maybe_argcount ::=", - /* 43 */ "maybe_argcount ::= exp", - /* 44 */ "maybe_argcount ::= exp COMMA exp", - /* 45 */ "linetype_declaration ::= exp EQUALS exp COMMA exp LPAREN special_args RPAREN", - /* 46 */ "linetype_declaration ::= exp EQUALS exp COMMA SYM LPAREN special_args RPAREN", - /* 47 */ "boom_declaration ::= LBRACKET exp RBRACKET LPAREN exp COMMA exp RPAREN LBRACE boom_body RBRACE", - /* 48 */ "boom_body ::=", - /* 49 */ "boom_body ::= boom_line boom_body", - /* 50 */ "boom_line ::= boom_selector boom_op boom_args", - /* 51 */ "boom_selector ::= FLAGS", - /* 52 */ "boom_selector ::= ARG2", - /* 53 */ "boom_selector ::= ARG3", - /* 54 */ "boom_selector ::= ARG4", - /* 55 */ "boom_selector ::= ARG5", - /* 56 */ "boom_op ::= EQUALS", - /* 57 */ "boom_op ::= OR_EQUAL", - /* 58 */ "boom_args ::= exp", - /* 59 */ "boom_args ::= exp LBRACKET arg_list RBRACKET", - /* 60 */ "arg_list ::= list_val", - /* 61 */ "arg_list ::= list_val COMMA arg_list", - /* 62 */ "list_val ::= exp COLON exp", - /* 63 */ "special_args ::=", - /* 64 */ "special_args ::= TAG", - /* 65 */ "special_args ::= TAG COMMA exp", - /* 66 */ "special_args ::= TAG COMMA exp COMMA exp", - /* 67 */ "special_args ::= TAG COMMA exp COMMA exp COMMA exp", - /* 68 */ "special_args ::= TAG COMMA exp COMMA exp COMMA exp COMMA exp", - /* 69 */ "special_args ::= TAG COMMA TAG", - /* 70 */ "special_args ::= TAG COMMA TAG COMMA exp", - /* 71 */ "special_args ::= TAG COMMA TAG COMMA exp COMMA exp", - /* 72 */ "special_args ::= TAG COMMA TAG COMMA exp COMMA exp COMMA exp", - /* 73 */ "special_args ::= LINEID", - /* 74 */ "special_args ::= LINEID COMMA exp", - /* 75 */ "special_args ::= LINEID COMMA exp COMMA exp", - /* 76 */ "special_args ::= LINEID COMMA exp COMMA exp COMMA exp", - /* 77 */ "special_args ::= LINEID COMMA exp COMMA exp COMMA exp COMMA exp", - /* 78 */ "special_args ::= exp", - /* 79 */ "special_args ::= exp COMMA exp", - /* 80 */ "special_args ::= exp COMMA exp COMMA exp", - /* 81 */ "special_args ::= exp COMMA exp COMMA exp COMMA exp", - /* 82 */ "special_args ::= exp COMMA exp COMMA exp COMMA exp COMMA exp", - /* 83 */ "special_args ::= exp COMMA TAG", - /* 84 */ "special_args ::= exp COMMA TAG COMMA exp", - /* 85 */ "special_args ::= exp COMMA TAG COMMA exp COMMA exp", - /* 86 */ "special_args ::= exp COMMA TAG COMMA exp COMMA exp COMMA exp", - /* 87 */ "special_args ::= exp COMMA exp COMMA TAG", - /* 88 */ "special_args ::= exp COMMA exp COMMA TAG COMMA exp", - /* 89 */ "special_args ::= exp COMMA exp COMMA TAG COMMA exp COMMA exp", - /* 90 */ "special_args ::= exp COMMA exp COMMA exp COMMA TAG", - /* 91 */ "special_args ::= exp COMMA exp COMMA exp COMMA TAG COMMA exp", - /* 92 */ "special_args ::= exp COMMA exp COMMA exp COMMA exp COMMA TAG", -}; -#endif /* NDEBUG */ - -#if YYSTACKDEPTH<=0 -/* -** Try to increase the size of the parser stack. -*/ -static void yyGrowStack(yyParser *p){ - int newSize; - yyStackEntry *pNew; - - newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); - if( pNew ){ - p->yystack = pNew; - p->yystksz = newSize; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); - } -#endif - } -} -#endif - -/* -** This function allocates a new parser. -** The only argument is a pointer to a function which works like -** malloc. -** -** Inputs: -** A pointer to the function used to allocate memory. -** -** Outputs: -** A pointer to a parser. This pointer is used in subsequent calls -** to Parse and ParseFree. -*/ -void *ParseAlloc(void *(*mallocProc)(size_t)){ - yyParser *pParser; - pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); - if( pParser ){ - pParser->yyidx = -1; -#if YYSTACKDEPTH<=0 - yyGrowStack(pParser); -#endif - } - return pParser; -} - -/* The following function deletes the value associated with a -** symbol. The symbol can be either a terminal or nonterminal. -** "yymajor" is the symbol code, and "yypminor" is a pointer to -** the value. -*/ -static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ - switch( yymajor ){ - /* Here is inserted the actions which take place when a - ** terminal or non-terminal is destroyed. This can happen - ** when the symbol is popped from the stack during a - ** reduce or during error processing or when a parser is - ** being destroyed before it is finished parsing. - ** - ** Note: during a reduce, the only symbols destroyed are those - ** which appear on the RHS of the rule, but which are not used - ** inside the C code. - */ - default: break; /* If no destructor action specified: do nothing */ - } -} - -/* -** Pop the parser's stack once. -** -** If there is a destructor routine associated with the token which -** is popped from the stack, then call it. -** -** Return the major token number for the symbol popped. -*/ -static int yy_pop_parser_stack(yyParser *pParser){ - YYCODETYPE yymajor; - yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - - if( pParser->yyidx<0 ) return 0; -#ifndef NDEBUG - if( yyTraceFILE && pParser->yyidx>=0 ){ - fprintf(yyTraceFILE,"%sPopping %s\n", - yyTracePrompt, - yyTokenName[yytos->major]); - } -#endif - yymajor = yytos->major; - yy_destructor( yymajor, &yytos->minor); - pParser->yyidx--; - return yymajor; -} - -/* -** Deallocate and destroy a parser. Destructors are all called for -** all stack elements before shutting the parser down. -** -** Inputs: -**
    -**
  • A pointer to the parser. This should be a pointer -** obtained from ParseAlloc. -**
  • A pointer to a function used to reclaim memory obtained -** from malloc. -**
-*/ -void ParseFree( - void *p, /* The parser to be deleted */ - void (*freeProc)(void*) /* Function used to reclaim memory */ -){ - yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); -#if YYSTACKDEPTH<=0 - free(pParser->yystack); -#endif - (*freeProc)((void*)pParser); -} - -/* -** Find the appropriate action for a parser given the terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_shift_action( - yyParser *pParser, /* The parser */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; - - if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ - return yy_default[stateno]; - } - if( iLookAhead==YYNOCODE ){ - return YY_NO_ACTION; - } - i += iLookAhead; - if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ -#ifdef YYFALLBACK - int iFallback; /* Fallback token */ - if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - return yy_find_shift_action(pParser, iFallback); - } -#endif -#ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( j>=0 && j %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; - } - } -#endif /* YYWILDCARD */ - } - return yy_default[stateno]; - }else{ - return yy_action[i]; - } -} - -/* -** Find the appropriate action for a parser given the non-terminal -** look-ahead token iLookAhead. -** -** If the look-ahead token is YYNOCODE, then check to see if the action is -** independent of the look-ahead. If it is, return the action, otherwise -** return YY_NO_ACTION. -*/ -static int yy_find_reduce_action( - int stateno, /* Current state number */ - YYCODETYPE iLookAhead /* The look-ahead token */ -){ - int i; - assert( stateno<=YY_REDUCE_MAX ); - i = yy_reduce_ofst[stateno]; - assert( i!=YY_REDUCE_USE_DFLT ); - assert( iLookAhead!=YYNOCODE ); - i += iLookAhead; - assert( i>=0 && iyyidx--; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will execute if the parser - ** stack every overflows */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ -} - -/* -** Perform a shift action. -*/ -static void yy_shift( - yyParser *yypParser, /* The parser to be shifted */ - int yyNewState, /* The new state to shift in */ - int yyMajor, /* The major token to shift in */ - YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */ -){ - yyStackEntry *yytos; - yypParser->yyidx++; -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ - yyStackOverflow(yypParser, yypMinor); - return; - } -#else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ - yyStackOverflow(yypParser, yypMinor); - return; - } - } -#endif - yytos = &yypParser->yystack[yypParser->yyidx]; - yytos->stateno = yyNewState; - yytos->major = yyMajor; - yytos->minor = *yypMinor; -#ifndef NDEBUG - if( yyTraceFILE && yypParser->yyidx>0 ){ - int i; - fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); - fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]); - fprintf(yyTraceFILE,"\n"); - } -#endif -} - -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - unsigned char nrhs; /* Number of right-hand side symbols in the rule */ -} yyRuleInfo[] = { - { 48, 1 }, - { 38, 1 }, - { 38, 1 }, - { 38, 3 }, - { 38, 3 }, - { 38, 3 }, - { 38, 3 }, - { 38, 3 }, - { 38, 3 }, - { 38, 3 }, - { 38, 2 }, - { 38, 3 }, - { 49, 0 }, - { 49, 1 }, - { 50, 1 }, - { 50, 1 }, - { 50, 1 }, - { 50, 1 }, - { 50, 1 }, - { 50, 1 }, - { 50, 1 }, - { 53, 4 }, - { 58, 0 }, - { 58, 1 }, - { 58, 3 }, - { 59, 1 }, - { 59, 1 }, - { 59, 1 }, - { 51, 5 }, - { 52, 2 }, - { 54, 3 }, - { 60, 2 }, - { 61, 0 }, - { 61, 1 }, - { 61, 3 }, - { 62, 1 }, - { 62, 3 }, - { 57, 3 }, - { 63, 1 }, - { 63, 3 }, - { 64, 6 }, - { 64, 6 }, - { 47, 0 }, - { 47, 1 }, - { 47, 3 }, - { 55, 8 }, - { 55, 8 }, - { 56, 11 }, - { 46, 0 }, - { 46, 2 }, - { 45, 3 }, - { 44, 1 }, - { 44, 1 }, - { 44, 1 }, - { 44, 1 }, - { 44, 1 }, - { 43, 1 }, - { 43, 1 }, - { 42, 1 }, - { 42, 4 }, - { 41, 1 }, - { 41, 3 }, - { 40, 3 }, - { 39, 0 }, - { 39, 1 }, - { 39, 3 }, - { 39, 5 }, - { 39, 7 }, - { 39, 9 }, - { 39, 3 }, - { 39, 5 }, - { 39, 7 }, - { 39, 9 }, - { 39, 1 }, - { 39, 3 }, - { 39, 5 }, - { 39, 7 }, - { 39, 9 }, - { 39, 1 }, - { 39, 3 }, - { 39, 5 }, - { 39, 7 }, - { 39, 9 }, - { 39, 3 }, - { 39, 5 }, - { 39, 7 }, - { 39, 9 }, - { 39, 5 }, - { 39, 7 }, - { 39, 9 }, - { 39, 7 }, - { 39, 9 }, - { 39, 9 }, -}; - -static void yy_accept(yyParser*); /* Forward Declaration */ - -/* -** Perform a reduce action and the shift that must immediately -** follow the reduce. -*/ -static void yy_reduce( - yyParser *yypParser, /* The parser */ - int yyruleno /* Number of the rule by which to reduce */ -){ - int yygoto; /* The next state */ - int yyact; /* The next action */ - YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ - yyStackEntry *yymsp; /* The top of the parser's stack */ - int yysize; /* Amount to pop the stack */ - ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno>=0 - && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, - yyRuleName[yyruleno]); - } -#endif /* NDEBUG */ - - /* Silence complaints from purify about yygotominor being uninitialized - ** in some cases when it is copied into the stack after the following - ** switch. yygotominor is uninitialized when a rule reduces that does - ** not set the value of its left-hand side nonterminal. Leaving the - ** value of the nonterminal uninitialized is utterly harmless as long - ** as the value is never used. So really the only thing this code - ** accomplishes is to quieten purify. - ** - ** 2007-01-16: The wireshark project (www.wireshark.org) reports that - ** without this code, their parser segfaults. I'm not sure what there - ** parser is doing to make this happen. This is the second bug report - ** from wireshark this week. Clearly they are stressing Lemon in ways - ** that it has not been previously stressed... (SQLite ticket #2172) - */ - memset(&yygotominor, 0, sizeof(yygotominor)); - - - switch( yyruleno ){ - /* Beginning here are the reduction cases. A typical example - ** follows: - ** case 0: - ** #line - ** { ... } // User supplied code - ** #line - ** break; - */ - case 1: -#line 344 "xlat-parse.y" -{ yygotominor.yy72 = yymsp[0].minor.yy0.val; } -#line 1227 "xlat-parse.c" - break; - case 2: -#line 345 "xlat-parse.y" -{ yygotominor.yy72 = yymsp[0].minor.yy0.symval->Value; } -#line 1232 "xlat-parse.c" - break; - case 3: -#line 346 "xlat-parse.y" -{ yygotominor.yy72 = yymsp[-2].minor.yy72 + yymsp[0].minor.yy72; } -#line 1237 "xlat-parse.c" - break; - case 4: -#line 347 "xlat-parse.y" -{ yygotominor.yy72 = yymsp[-2].minor.yy72 - yymsp[0].minor.yy72; } -#line 1242 "xlat-parse.c" - break; - case 5: -#line 348 "xlat-parse.y" -{ yygotominor.yy72 = yymsp[-2].minor.yy72 * yymsp[0].minor.yy72; } -#line 1247 "xlat-parse.c" - break; - case 6: -#line 349 "xlat-parse.y" -{ yygotominor.yy72 = yymsp[-2].minor.yy72 / yymsp[0].minor.yy72; } -#line 1252 "xlat-parse.c" - break; - case 7: -#line 350 "xlat-parse.y" -{ yygotominor.yy72 = yymsp[-2].minor.yy72 | yymsp[0].minor.yy72; } -#line 1257 "xlat-parse.c" - break; - case 8: -#line 351 "xlat-parse.y" -{ yygotominor.yy72 = yymsp[-2].minor.yy72 & yymsp[0].minor.yy72; } -#line 1262 "xlat-parse.c" - break; - case 9: -#line 352 "xlat-parse.y" -{ yygotominor.yy72 = yymsp[-2].minor.yy72 ^ yymsp[0].minor.yy72; } -#line 1267 "xlat-parse.c" - break; - case 10: -#line 353 "xlat-parse.y" -{ yygotominor.yy72 = -yymsp[0].minor.yy72; } -#line 1272 "xlat-parse.c" - break; - case 11: -#line 354 "xlat-parse.y" -{ yygotominor.yy72 = yymsp[-1].minor.yy72; } -#line 1277 "xlat-parse.c" - break; - case 21: -#line 368 "xlat-parse.y" -{ - printf ("\n"); -} -#line 1284 "xlat-parse.c" - break; - case 25: -#line 376 "xlat-parse.y" -{ printf ("%s", yymsp[0].minor.yy0.string); } -#line 1289 "xlat-parse.c" - break; - case 26: -#line 377 "xlat-parse.y" -{ printf ("%d", yymsp[0].minor.yy72); } -#line 1294 "xlat-parse.c" - break; - case 27: -#line 378 "xlat-parse.y" -{ printf ("\n"); } -#line 1299 "xlat-parse.c" - break; - case 28: -#line 381 "xlat-parse.y" -{ - AddSym (yymsp[-3].minor.yy0.sym, yymsp[-1].minor.yy72); -} -#line 1306 "xlat-parse.c" - break; - case 29: -#line 386 "xlat-parse.y" -{ - IncludeFile (yymsp[0].minor.yy0.string); -} -#line 1313 "xlat-parse.c" - break; - case 31: -#line 393 "xlat-parse.y" -{ - EnumVal = 0; -} -#line 1320 "xlat-parse.c" - break; - case 35: -#line 402 "xlat-parse.y" -{ - AddSym (yymsp[0].minor.yy0.sym, EnumVal++); -} -#line 1327 "xlat-parse.c" - break; - case 36: -#line 407 "xlat-parse.y" -{ - AddSym (yymsp[-2].minor.yy0.sym, EnumVal = yymsp[0].minor.yy72); -} -#line 1334 "xlat-parse.c" - break; - case 40: -#line 420 "xlat-parse.y" -{ - AddSym (yymsp[-3].minor.yy0.sym, yymsp[-5].minor.yy72); -} -#line 1341 "xlat-parse.c" - break; - case 41: -#line 424 "xlat-parse.y" -{ - printf ("%s, line %d: %s is already defined\n", SourceName, SourceLine, yymsp[-3].minor.yy0.symval->Sym); -} -#line 1348 "xlat-parse.c" - break; - case 45: -#line 433 "xlat-parse.y" -{ - Simple[yymsp[-7].minor.yy72].NewSpecial = yymsp[-3].minor.yy72; - Simple[yymsp[-7].minor.yy72].Flags = yymsp[-5].minor.yy72 | yymsp[-1].minor.yy57.addflags; - Simple[yymsp[-7].minor.yy72].Args[0] = yymsp[-1].minor.yy57.args[0]; - Simple[yymsp[-7].minor.yy72].Args[1] = yymsp[-1].minor.yy57.args[1]; - Simple[yymsp[-7].minor.yy72].Args[2] = yymsp[-1].minor.yy57.args[2]; - Simple[yymsp[-7].minor.yy72].Args[3] = yymsp[-1].minor.yy57.args[3]; - Simple[yymsp[-7].minor.yy72].Args[4] = yymsp[-1].minor.yy57.args[4]; -} -#line 1361 "xlat-parse.c" - break; - case 46: -#line 443 "xlat-parse.y" -{ - printf ("%s, line %d: %s is undefined\n", SourceName, SourceLine, yymsp[-3].minor.yy0.sym); -} -#line 1368 "xlat-parse.c" - break; - case 47: -#line 448 "xlat-parse.y" -{ - if (NumBoomish == MAX_BOOMISH) - { - MoreLines *probe = yymsp[-1].minor.yy49; - - while (probe != NULL) - { - MoreLines *next = probe->next; - free (probe); - probe = next; - } - printf ("%s, line %d: Too many BOOM translators\n", SourceName, SourceLine); - } - else - { - int i; - MoreLines *probe; - - Boomish[NumBoomish].FirstLinetype = yymsp[-6].minor.yy72; - Boomish[NumBoomish].LastLinetype = yymsp[-4].minor.yy72; - Boomish[NumBoomish].NewSpecial = yymsp[-9].minor.yy72; - - for (i = 0, probe = yymsp[-1].minor.yy49; probe != NULL; i++) - { - MoreLines *next = probe->next;; - if (i < MAX_BOOMISH_EXEC) - { - Boomish[NumBoomish].Args[i] = probe->arg; - } - else if (i == MAX_BOOMISH_EXEC) - { - printf ("%s, line %d: Too many commands for this BOOM translator\n", SourceName, SourceLine); - } - free (probe); - probe = next; - } - if (i < MAX_BOOMISH_EXEC) - { - Boomish[NumBoomish].Args[i].bDefined = 0; - } - NumBoomish++; - } -} -#line 1415 "xlat-parse.c" - break; - case 48: -#line 493 "xlat-parse.y" -{ - yygotominor.yy49 = NULL; -} -#line 1422 "xlat-parse.c" - break; - case 49: -#line 497 "xlat-parse.y" -{ - yygotominor.yy49 = malloc (sizeof(MoreLines)); - yygotominor.yy49->next = yymsp[0].minor.yy49; - yygotominor.yy49->arg = yymsp[-1].minor.yy58; -} -#line 1431 "xlat-parse.c" - break; - case 50: -#line 504 "xlat-parse.y" -{ - yygotominor.yy58.bDefined = 1; - yygotominor.yy58.bOrExisting = (yymsp[-1].minor.yy72 == OR_EQUAL); - yygotominor.yy58.bUseConstant = (yymsp[0].minor.yy83.filters == NULL); - yygotominor.yy58.ArgNum = yymsp[-2].minor.yy72; - yygotominor.yy58.ConstantValue = yymsp[0].minor.yy83.constant; - yygotominor.yy58.AndValue = yymsp[0].minor.yy83.mask; - - if (yymsp[0].minor.yy83.filters != NULL) - { - int i; - MoreFilters *probe; - - for (i = 0, probe = yymsp[0].minor.yy83.filters; probe != NULL; i++) - { - MoreFilters *next = probe->next; - if (i < 15) - { - yygotominor.yy58.ResultFilter[i] = probe->filter.filter; - yygotominor.yy58.ResultValue[i] = probe->filter.value; - } - else if (i == 15) - { - yyerror ("Lists can only have 15 elements"); - } - free (probe); - probe = next; - } - yygotominor.yy58.ListSize = i > 15 ? 15 : i; - } -} -#line 1466 "xlat-parse.c" - break; - case 51: -#line 536 "xlat-parse.y" -{ yygotominor.yy72 = 4; } -#line 1471 "xlat-parse.c" - break; - case 52: -#line 537 "xlat-parse.y" -{ yygotominor.yy72 = 0; } -#line 1476 "xlat-parse.c" - break; - case 53: -#line 538 "xlat-parse.y" -{ yygotominor.yy72 = 1; } -#line 1481 "xlat-parse.c" - break; - case 54: -#line 539 "xlat-parse.y" -{ yygotominor.yy72 = 2; } -#line 1486 "xlat-parse.c" - break; - case 55: -#line 540 "xlat-parse.y" -{ yygotominor.yy72 = 3; } -#line 1491 "xlat-parse.c" - break; - case 56: -#line 542 "xlat-parse.y" -{ yygotominor.yy72 = '='; } -#line 1496 "xlat-parse.c" - break; - case 57: -#line 543 "xlat-parse.y" -{ yygotominor.yy72 = OR_EQUAL; } -#line 1501 "xlat-parse.c" - break; - case 58: -#line 546 "xlat-parse.y" -{ - yygotominor.yy83.constant = yymsp[0].minor.yy72; - yygotominor.yy83.filters = NULL; -} -#line 1509 "xlat-parse.c" - break; - case 59: -#line 551 "xlat-parse.y" -{ - yygotominor.yy83.mask = yymsp[-3].minor.yy72; - yygotominor.yy83.filters = yymsp[-1].minor.yy87; -} -#line 1517 "xlat-parse.c" - break; - case 60: -#line 557 "xlat-parse.y" -{ - yygotominor.yy87 = malloc (sizeof(MoreFilters)); - yygotominor.yy87->next = NULL; - yygotominor.yy87->filter = yymsp[0].minor.yy124; -} -#line 1526 "xlat-parse.c" - break; - case 61: -#line 563 "xlat-parse.y" -{ - yygotominor.yy87 = malloc (sizeof(MoreFilters)); - yygotominor.yy87->next = yymsp[0].minor.yy87; - yygotominor.yy87->filter = yymsp[-2].minor.yy124; -} -#line 1535 "xlat-parse.c" - break; - case 62: -#line 570 "xlat-parse.y" -{ - yygotominor.yy124.filter = yymsp[-2].minor.yy72; - yygotominor.yy124.value = yymsp[0].minor.yy72; -} -#line 1543 "xlat-parse.c" - break; - case 63: -#line 576 "xlat-parse.y" -{ - yygotominor.yy57.addflags = 0; - memset (yygotominor.yy57.args, 0, 5); -} -#line 1551 "xlat-parse.c" - break; - case 64: -#line 581 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT1; - memset (yygotominor.yy57.args, 0, 5); -} -#line 1559 "xlat-parse.c" - break; - case 65: -#line 586 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT1; - yygotominor.yy57.args[0] = 0; - yygotominor.yy57.args[1] = yymsp[0].minor.yy72; - yygotominor.yy57.args[2] = 0; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1571 "xlat-parse.c" - break; - case 66: -#line 595 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT1; - yygotominor.yy57.args[0] = 0; - yygotominor.yy57.args[1] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[2] = yymsp[0].minor.yy72; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1583 "xlat-parse.c" - break; - case 67: -#line 604 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT1; - yygotominor.yy57.args[0] = 0; - yygotominor.yy57.args[1] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[2] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[3] = yymsp[0].minor.yy72; - yygotominor.yy57.args[4] = 0; -} -#line 1595 "xlat-parse.c" - break; - case 68: -#line 613 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT1; - yygotominor.yy57.args[0] = 0; - yygotominor.yy57.args[1] = yymsp[-6].minor.yy72; - yygotominor.yy57.args[2] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[3] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[4] = yymsp[0].minor.yy72; -} -#line 1607 "xlat-parse.c" - break; - case 69: -#line 622 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HAS2TAGS; - yygotominor.yy57.args[0] = yygotominor.yy57.args[1] = 0; - yygotominor.yy57.args[2] = 0; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1618 "xlat-parse.c" - break; - case 70: -#line 630 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HAS2TAGS; - yygotominor.yy57.args[0] = yygotominor.yy57.args[1] = 0; - yygotominor.yy57.args[2] = yymsp[0].minor.yy72; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1629 "xlat-parse.c" - break; - case 71: -#line 638 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HAS2TAGS; - yygotominor.yy57.args[0] = yygotominor.yy57.args[1] = 0; - yygotominor.yy57.args[2] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[3] = yymsp[0].minor.yy72; - yygotominor.yy57.args[4] = 0; -} -#line 1640 "xlat-parse.c" - break; - case 72: -#line 646 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HAS2TAGS; - yygotominor.yy57.args[0] = yygotominor.yy57.args[1] = 0; - yygotominor.yy57.args[2] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[3] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[4] = yymsp[0].minor.yy72; -} -#line 1651 "xlat-parse.c" - break; - case 73: -#line 654 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASLINEID; - memset (yygotominor.yy57.args, 0, 5); -} -#line 1659 "xlat-parse.c" - break; - case 74: -#line 659 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASLINEID; - yygotominor.yy57.args[0] = 0; - yygotominor.yy57.args[1] = yymsp[0].minor.yy72; - yygotominor.yy57.args[2] = 0; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1671 "xlat-parse.c" - break; - case 75: -#line 668 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASLINEID; - yygotominor.yy57.args[0] = 0; - yygotominor.yy57.args[1] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[2] = yymsp[0].minor.yy72; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1683 "xlat-parse.c" - break; - case 76: -#line 677 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASLINEID; - yygotominor.yy57.args[0] = 0; - yygotominor.yy57.args[1] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[2] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[3] = yymsp[0].minor.yy72; - yygotominor.yy57.args[4] = 0; -} -#line 1695 "xlat-parse.c" - break; - case 77: -#line 686 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASLINEID; - yygotominor.yy57.args[0] = 0; - yygotominor.yy57.args[1] = yymsp[-6].minor.yy72; - yygotominor.yy57.args[2] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[3] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[4] = yymsp[0].minor.yy72; -} -#line 1707 "xlat-parse.c" - break; - case 78: -#line 695 "xlat-parse.y" -{ - yygotominor.yy57.addflags = 0; - yygotominor.yy57.args[0] = yymsp[0].minor.yy72; - yygotominor.yy57.args[1] = 0; - yygotominor.yy57.args[2] = 0; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1719 "xlat-parse.c" - break; - case 79: -#line 704 "xlat-parse.y" -{ - yygotominor.yy57.addflags = 0; - yygotominor.yy57.args[0] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[1] = yymsp[0].minor.yy72; - yygotominor.yy57.args[2] = 0; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1731 "xlat-parse.c" - break; - case 80: -#line 713 "xlat-parse.y" -{ - yygotominor.yy57.addflags = 0; - yygotominor.yy57.args[0] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[1] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[2] = yymsp[0].minor.yy72; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1743 "xlat-parse.c" - break; - case 81: -#line 722 "xlat-parse.y" -{ - yygotominor.yy57.addflags = 0; - yygotominor.yy57.args[0] = yymsp[-6].minor.yy72; - yygotominor.yy57.args[1] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[2] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[3] = yymsp[0].minor.yy72; - yygotominor.yy57.args[4] = 0; -} -#line 1755 "xlat-parse.c" - break; - case 82: -#line 731 "xlat-parse.y" -{ - yygotominor.yy57.addflags = 0; - yygotominor.yy57.args[0] = yymsp[-8].minor.yy72; - yygotominor.yy57.args[1] = yymsp[-6].minor.yy72; - yygotominor.yy57.args[2] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[3] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[4] = yymsp[0].minor.yy72; -} -#line 1767 "xlat-parse.c" - break; - case 83: -#line 740 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT2; - yygotominor.yy57.args[0] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[1] = 0; - yygotominor.yy57.args[2] = 0; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1779 "xlat-parse.c" - break; - case 84: -#line 749 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT2; - yygotominor.yy57.args[0] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[1] = 0; - yygotominor.yy57.args[2] = yymsp[0].minor.yy72; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1791 "xlat-parse.c" - break; - case 85: -#line 758 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT2; - yygotominor.yy57.args[0] = yymsp[-6].minor.yy72; - yygotominor.yy57.args[1] = 0; - yygotominor.yy57.args[2] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[3] = yymsp[0].minor.yy72; - yygotominor.yy57.args[4] = 0; -} -#line 1803 "xlat-parse.c" - break; - case 86: -#line 767 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT2; - yygotominor.yy57.args[0] = yymsp[-8].minor.yy72; - yygotominor.yy57.args[1] = 0; - yygotominor.yy57.args[2] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[3] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[4] = yymsp[0].minor.yy72; -} -#line 1815 "xlat-parse.c" - break; - case 87: -#line 776 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT3; - yygotominor.yy57.args[0] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[1] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[2] = 0; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1827 "xlat-parse.c" - break; - case 88: -#line 785 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT3; - yygotominor.yy57.args[0] = yymsp[-6].minor.yy72; - yygotominor.yy57.args[1] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[2] = 0; - yygotominor.yy57.args[3] = yymsp[0].minor.yy72; - yygotominor.yy57.args[4] = 0; -} -#line 1839 "xlat-parse.c" - break; - case 89: -#line 794 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT3; - yygotominor.yy57.args[0] = yymsp[-8].minor.yy72; - yygotominor.yy57.args[1] = yymsp[-6].minor.yy72; - yygotominor.yy57.args[2] = 0; - yygotominor.yy57.args[3] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[4] = yymsp[0].minor.yy72; -} -#line 1851 "xlat-parse.c" - break; - case 90: -#line 803 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT4; - yygotominor.yy57.args[0] = yymsp[-6].minor.yy72; - yygotominor.yy57.args[1] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[2] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = 0; -} -#line 1863 "xlat-parse.c" - break; - case 91: -#line 812 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT4; - yygotominor.yy57.args[0] = yymsp[-8].minor.yy72; - yygotominor.yy57.args[1] = yymsp[-6].minor.yy72; - yygotominor.yy57.args[2] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[3] = 0; - yygotominor.yy57.args[4] = yymsp[0].minor.yy72; -} -#line 1875 "xlat-parse.c" - break; - case 92: -#line 821 "xlat-parse.y" -{ - yygotominor.yy57.addflags = SIMPLE_HASTAGAT5; - yygotominor.yy57.args[0] = yymsp[-8].minor.yy72; - yygotominor.yy57.args[1] = yymsp[-6].minor.yy72; - yygotominor.yy57.args[2] = yymsp[-4].minor.yy72; - yygotominor.yy57.args[3] = yymsp[-2].minor.yy72; - yygotominor.yy57.args[4] = 0; -} -#line 1887 "xlat-parse.c" - break; - }; - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; - yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto); - if( yyact < YYNSTATE ){ -#ifdef NDEBUG - /* If we are not debugging and the reduce action popped at least - ** one element off the stack, then we can push the new element back - ** onto the stack here, and skip the stack overflow test in yy_shift(). - ** That gives a significant speed improvement. */ - if( yysize ){ - yypParser->yyidx++; - yymsp -= yysize-1; - yymsp->stateno = yyact; - yymsp->major = yygoto; - yymsp->minor = yygotominor; - }else -#endif - { - yy_shift(yypParser,yyact,yygoto,&yygotominor); - } - }else{ - assert( yyact == YYNSTATE + YYNRULE + 1 ); - yy_accept(yypParser); - } -} - -/* -** The following code executes when the parse fails -*/ -static void yy_parse_failed( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser fails */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following code executes when a syntax error first occurs. -*/ -static void yy_syntax_error( - yyParser *yypParser, /* The parser */ - int yymajor, /* The major type of the error token */ - YYMINORTYPE yyminor /* The minor type of the error token */ -){ - ParseARG_FETCH; -#define TOKEN (yyminor.yy0) -#line 322 "xlat-parse.y" -yyerror("syntax error"); -#line 1947 "xlat-parse.c" - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* -** The following is executed when the parser accepts -*/ -static void yy_accept( - yyParser *yypParser /* The parser */ -){ - ParseARG_FETCH; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); - } -#endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); - /* Here code is inserted which will be executed whenever the - ** parser accepts */ - ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ -} - -/* The main parser program. -** The first argument is a pointer to a structure obtained from -** "ParseAlloc" which describes the current state of the parser. -** The second argument is the major token number. The third is -** the minor token. The fourth optional argument is whatever the -** user wants (and specified in the grammar) and is available for -** use by the action routines. -** -** Inputs: -**
    -**
  • A pointer to the parser (an opaque structure.) -**
  • The major token number. -**
  • The minor token number. -**
  • An option argument of a grammar-specified type. -**
-** -** Outputs: -** None. -*/ -void Parse( - void *yyp, /* The parser */ - int yymajor, /* The major token code number */ - ParseTOKENTYPE yyminor /* The value for the token */ - ParseARG_PDECL /* Optional %extra_argument parameter */ -){ - YYMINORTYPE yyminorunion; - int yyact; /* The parser action. */ - int yyendofinput; /* True if we are at the end of input */ -#ifdef YYERRORSYMBOL - int yyerrorhit = 0; /* True if yymajor has invoked an error */ -#endif - yyParser *yypParser; /* The parser */ - - /* (re)initialize the parser, if necessary */ - yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - memset(&yyminorunion, 0, sizeof(yyminorunion)); - yyStackOverflow(yypParser, &yyminorunion); - return; - } -#endif - yypParser->yyidx = 0; - yypParser->yyerrcnt = -1; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; - } - yyminorunion.yy0 = yyminor; - yyendofinput = (yymajor==0); - ParseARG_STORE; - -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); - } -#endif - - do{ - yyact = yy_find_shift_action(yypParser,yymajor); - if( yyactyyerrcnt--; - yymajor = YYNOCODE; - /* [RH] If we can reduce the stack now, do it. Otherwise, constructs */ - /* like "include " won't work because the next token after */ - /* the include will be shifted before the include is reduced. Then the */ - /* parser will act as if that token had been the first one in the */ - /* included file. */ - while( yypParser->yyidx>= 0 && (yyact = yy_find_shift_action(yypParser,YYNOCODE)) < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - } - }else if( yyact < YYNSTATE + YYNRULE ){ - yy_reduce(yypParser,yyact-YYNSTATE); - }else{ -#ifdef YYERRORSYMBOL - int yymx; -#endif - assert( yyact == YY_ERROR_ACTION ); -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); - } -#endif -#ifdef YYERRORSYMBOL - /* A syntax error has occurred. - ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". - ** - ** This is what we do if the grammar does define ERROR: - ** - ** * Call the %syntax_error function. - ** - ** * Begin popping the stack until we enter a state where - ** it is legal to shift the error symbol, then shift - ** the error symbol. - ** - ** * Set the error count to three. - ** - ** * Begin accepting and shifting new tokens. No new error - ** processing will occur until three tokens have been - ** shifted successfully. - ** - */ - if( yypParser->yyerrcnt<0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yymx = yypParser->yystack[yypParser->yyidx].major; - if( yymx==YYERRORSYMBOL || yyerrorhit ){ -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sDiscard input token %s\n", - yyTracePrompt,yyTokenName[yymajor]); - } -#endif - yy_destructor(yymajor,&yyminorunion); - yymajor = YYNOCODE; - }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, - YYERRORSYMBOL)) >= YYNSTATE - ){ - yy_pop_parser_stack(yypParser); - } - if( yypParser->yyidx < 0 || yymajor==0 ){ - yy_destructor(yymajor,&yyminorunion); - yy_parse_failed(yypParser); - yymajor = YYNOCODE; - }else if( yymx!=YYERRORSYMBOL ){ - YYMINORTYPE u2; - u2.YYERRSYMDT = 0; - yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); - } - } - yypParser->yyerrcnt = 3; - yyerrorhit = 1; -#else /* YYERRORSYMBOL is not defined */ - /* This is what we do if the grammar does not define ERROR: - ** - ** * Report an error message, and throw away the input token. - ** - ** * If the input token is $, then fail the parse. - ** - ** As before, subsequent error messages are suppressed until - ** three input tokens have been successfully shifted. - */ - if( yypParser->yyerrcnt<=0 ){ - yy_syntax_error(yypParser,yymajor,yyminorunion); - } - yypParser->yyerrcnt = 3; - yy_destructor(yymajor,&yyminorunion); - if( yyendofinput ){ - yy_parse_failed(yypParser); - } - yymajor = YYNOCODE; -#endif - } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); - return; -} +/* Driver template for the LEMON parser generator. +** The author disclaims copyright to this source code. +*/ +/* First off, code is included which follows the "include" declaration +** in the input file. */ +#include +#include +#include +#line 1 "xlat-parse.y" + +#include "xlat.h" +#include "xlat-parse.h" +#include +#include + +int yyerror (char *s); + +typedef struct _Symbol +{ + struct _Symbol *Next; + int Value; + char Sym[1]; +} Symbol; + +static bool FindToken (char *tok, int *type); +static void AddSym (char *sym, int val); +static bool FindSym (char *sym, Symbol **val); + +static int EnumVal; + +struct ListFilter +{ + WORD filter; + BYTE value; +}; + +typedef struct _morefilters +{ + struct _morefilters *next; + struct ListFilter filter; +} MoreFilters; + +typedef struct _morelines +{ + struct _morelines *next; + BoomArg arg; +} MoreLines; + +typedef struct _specialargs +{ + BYTE addflags; + BYTE args[5]; +} SpecialArgs; + +typedef struct _boomarg +{ + BYTE constant; + WORD mask; + MoreFilters *filters; +} ParseBoomArg; + +typedef union YYSTYPE +{ + int val; + char sym[80]; + char string[80]; + Symbol *symval; +} YYSTYPE; + +#include +#include + +int yylex (YYSTYPE *yylval) +{ + char token[80]; + int toksize; + int c; + +loop: + while (Source == NULL) + { + if (!EndFile ()) + return 0; + } + while (isspace (c = fgetc (Source)) && c != EOF) + { + if (c == '\n') + SourceLine++; + } + + if (c == EOF) + { + if (EndFile ()) + goto loop; + return 0; + } + if (isdigit (c)) + { + int buildup = c - '0'; + if (c == '0') + { + c = fgetc (Source); + if (c == 'x' || c == 'X') + { + for (;;) + { + c = fgetc (Source); + if (isdigit (c)) + { + buildup = (buildup<<4) + c - '0'; + } + else if (c >= 'a' && c <= 'f') + { + buildup = (buildup<<4) + c - 'a' + 10; + } + else if (c >= 'A' && c <= 'F') + { + buildup = (buildup<<4) + c - 'A' + 10; + } + else + { + ungetc (c, Source); + yylval->val = buildup; + return NUM; + } + } + } + else + { + ungetc (c, Source); + } + } + while (isdigit (c = fgetc (Source))) + { + buildup = buildup*10 + c - '0'; + } + ungetc (c, Source); + yylval->val = buildup; + return NUM; + } + if (isalpha (c)) + { + int buildup = 0; + + token[0] = c; + toksize = 1; + while (toksize < 79 && (isalnum (c = fgetc (Source)) || c == '_')) + { + token[toksize++] = c; + } + token[toksize] = 0; + if (toksize == 79 && isalnum (c)) + { + while (isalnum (c = fgetc (Source))) + ; + } + ungetc (c, Source); + if (FindToken (token, &buildup)) + { + return buildup; + } + if (FindSym (token, &yylval->symval)) + { + return SYMNUM; + } + strcpy (yylval->sym, token); + return SYM; + } + if (c == '/') + { + c = fgetc (Source); + if (c == '*') + { + for (;;) + { + while ((c = fgetc (Source)) != '*' && c != EOF) + { + if (c == '\n') + SourceLine++; + } + if (c == EOF) + return 0; + if ((c = fgetc (Source)) == '/') + goto loop; + if (c == EOF) + return 0; + ungetc (c, Source); + } + } + else if (c == '/') + { + while ((c = fgetc (Source)) != '\n' && c != EOF) + ; + if (c == '\n') + SourceLine++; + else if (c == EOF) + return 0; + goto loop; + } + else + { + ungetc (c, Source); + return DIVIDE; + } + } + if (c == '"') + { + int tokensize = 0; + while ((c = fgetc (Source)) != '"' && c != EOF) + { + yylval->string[tokensize++] = c; + } + yylval->string[tokensize] = 0; + return STRING; + } + if (c == '|') + { + c = fgetc (Source); + if (c == '=') + return OR_EQUAL; + ungetc (c, Source); + return OR; + } + switch (c) + { + case '^': return XOR; + case '&': return AND; + case '-': return MINUS; + case '+': return PLUS; + case '*': return MULTIPLY; + case '(': return LPAREN; + case ')': return RPAREN; + case ',': return COMMA; + case '{': return LBRACE; + case '}': return RBRACE; + case '=': return EQUALS; + case ';': return SEMICOLON; + case ':': return COLON; + case '[': return LBRACKET; + case ']': return RBRACKET; + default: return 0; + } +} + +void *ParseAlloc(void *(*mallocProc)(size_t)); +void Parse(void *yyp, int yymajor, YYSTYPE yyminor); +void ParseFree(void *p, void (*freeProc)(void*)); +void ParseTrace(FILE *TraceFILE, char *zTracePrompt); + +void yyparse (void) +{ + void *pParser = ParseAlloc (malloc); + YYSTYPE token; + int tokentype; + int include_state = 0; + + while ((tokentype = yylex(&token)) != 0) + { + /* Whenever the sequence INCLUDE STRING is encountered in the token + * stream, feed a dummy NOP token to the parser so that it will + * reduce the include_statement before grabbing any more tokens + * from the current file. + */ + if (tokentype == INCLUDE && include_state == 0) + { + include_state = 1; + } + else if (tokentype == STRING && include_state == 1) + { + include_state = 2; + } + else + { + include_state = 0; + } + Parse (pParser, tokentype, token); + if (include_state == 2) + { + include_state = 0; + Parse (pParser, NOP, token); + } + } + memset (&token, 0, sizeof(token)); + Parse (pParser, 0, token); + ParseFree (pParser, free); +} + +static Symbol *FirstSym; + +static void AddSym (char *sym, int val) +{ + Symbol *syme = malloc (strlen (sym) + sizeof(Symbol)); + syme->Next = FirstSym; + syme->Value = val; + strcpy (syme->Sym, sym); + FirstSym = syme; +} + +static bool FindSym (char *sym, Symbol **val) +{ + Symbol *syme = FirstSym; + + while (syme != NULL) + { + if (strcmp (syme->Sym, sym) == 0) + { + *val = syme; + return 1; + } + syme = syme->Next; + } + return 0; +} + +static bool FindToken (char *tok, int *type) +{ + static const char tokens[][8] = + { + "endl", "print", "include", "special", "define", "enum", + "arg5", "arg4", "arg3", "arg2", "flags", "lineid", "tag" + + }; + static const short types[] = + { + ENDL, PRINT, INCLUDE, SPECIAL, DEFINE, ENUM, + ARG5, ARG4, ARG3, ARG2, FLAGS, LINEID, TAG + }; + int i; + + for (i = sizeof(tokens)/sizeof(tokens[0])-1; i >= 0; i--) + { + if (strcmp (tok, tokens[i]) == 0) + { + *type = types[i]; + return 1; + } + } + return 0; +} + +int yyerror (char *s) +{ + if (SourceName != NULL) + printf ("%s, line %d: %s\n", SourceName, SourceLine, s); + else + printf ("%s\n", s); + return 0; +} + +#line 351 "xlat-parse.c" +/* Next is all token values, in a form suitable for use by makeheaders. +** This section will be null unless lemon is run with the -m switch. +*/ +/* +** These constants (all generated automatically by the parser generator) +** specify the various kinds of tokens (terminals) that the parser +** understands. +** +** Each symbol here is a terminal symbol in the grammar. +*/ +/* Make sure the INTERFACE macro is defined. +*/ +#ifndef INTERFACE +# define INTERFACE 1 +#endif +/* The next thing included is series of defines which control +** various aspects of the generated parser. +** YYCODETYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 terminals +** and nonterminals. "int" is used otherwise. +** YYNOCODE is a number of type YYCODETYPE which corresponds +** to no legal terminal or nonterminal number. This +** number is used to fill in empty slots of the hash +** table. +** YYFALLBACK If defined, this indicates that one or more tokens +** have fall-back values which should be used if the +** original value of the token will not parse. +** YYACTIONTYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 rules and +** states combined. "int" is used otherwise. +** ParseTOKENTYPE is the data type used for minor tokens given +** directly to the parser from the tokenizer. +** YYMINORTYPE is the data type used for all minor tokens. +** This is typically a union of many types, one of +** which is ParseTOKENTYPE. The entry in the union +** for base tokens is called "yy0". +** YYSTACKDEPTH is the maximum depth of the parser's stack. If +** zero the stack is dynamically sized using realloc() +** ParseARG_SDECL A static variable declaration for the %extra_argument +** ParseARG_PDECL A parameter declaration for the %extra_argument +** ParseARG_STORE Code to store %extra_argument into yypParser +** ParseARG_FETCH Code to extract %extra_argument from yypParser +** YYNSTATE the combined number of states. +** YYNRULE the number of rules in the grammar +** YYERRORSYMBOL is the code number of the error symbol. If not +** defined, then do no error processing. +*/ +#define YYCODETYPE unsigned char +#define YYNOCODE 67 +#define YYACTIONTYPE unsigned short int +#define ParseTOKENTYPE YYSTYPE +typedef union { + ParseTOKENTYPE yy0; + struct ListFilter yy20; + MoreFilters * yy39; + MoreLines * yy57; + int yy64; + BoomArg yy65; + ParseBoomArg yy87; + SpecialArgs yy123; +} YYMINORTYPE; +#ifndef YYSTACKDEPTH +#define YYSTACKDEPTH 100 +#endif +#define ParseARG_SDECL +#define ParseARG_PDECL +#define ParseARG_FETCH +#define ParseARG_STORE +#define YYNSTATE 174 +#define YYNRULE 94 +#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) +#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) +#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) + +/* Next are that tables used to determine what action to take based on the +** current state and lookahead token. These tables are used to implement +** functions that take a state number and lookahead value and return an +** action integer. +** +** Suppose the action integer is N. Then the action is determined as +** follows +** +** 0 <= N < YYNSTATE Shift N. That is, push the lookahead +** token onto the stack and goto state N. +** +** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. +** +** N == YYNSTATE+YYNRULE A syntax error has occurred. +** +** N == YYNSTATE+YYNRULE+1 The parser accepts its input. +** +** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused +** slots in the yy_action[] table. +** +** The action table is constructed as a single large table named yy_action[]. +** Given state S and lookahead X, the action is computed as +** +** yy_action[ yy_shift_ofst[S] + X ] +** +** If the index value yy_shift_ofst[S]+X is out of range or if the value +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] +** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table +** and that yy_default[S] should be used instead. +** +** The formula above is for computing the action when the lookahead is +** a terminal symbol. If the lookahead is a non-terminal (as occurs after +** a reduce action) then the yy_reduce_ofst[] array is used in place of +** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of +** YY_SHIFT_USE_DFLT. +** +** The following are the tables generated in this section: +** +** yy_action[] A single table containing all actions. +** yy_lookahead[] A table containing the lookahead for each entry in +** yy_action. Used to detect hash collisions. +** yy_shift_ofst[] For each state, the offset into yy_action for +** shifting terminals. +** yy_reduce_ofst[] For each state, the offset into yy_action for +** shifting non-terminals after a reduce. +** yy_default[] Default action for each state. +*/ +static const YYACTIONTYPE yy_action[] = { + /* 0 */ 174, 30, 71, 123, 30, 70, 157, 152, 26, 157, + /* 10 */ 152, 26, 79, 144, 115, 83, 126, 80, 104, 166, + /* 20 */ 109, 64, 120, 128, 127, 6, 71, 102, 53, 154, + /* 30 */ 150, 164, 149, 148, 147, 146, 145, 100, 140, 16, + /* 40 */ 162, 39, 34, 37, 54, 32, 55, 41, 39, 34, + /* 50 */ 37, 54, 32, 55, 41, 49, 34, 37, 54, 32, + /* 60 */ 55, 41, 51, 11, 39, 34, 37, 54, 32, 55, + /* 70 */ 41, 39, 34, 37, 54, 32, 55, 41, 50, 37, + /* 80 */ 54, 32, 55, 41, 9, 44, 14, 39, 34, 37, + /* 90 */ 54, 32, 55, 41, 39, 34, 37, 54, 32, 55, + /* 100 */ 41, 45, 169, 170, 171, 172, 173, 81, 42, 151, + /* 110 */ 39, 34, 37, 54, 32, 55, 41, 54, 32, 55, + /* 120 */ 41, 136, 79, 39, 34, 37, 54, 32, 55, 41, + /* 130 */ 39, 34, 37, 54, 32, 55, 41, 39, 34, 37, + /* 140 */ 54, 32, 55, 41, 29, 56, 5, 124, 139, 23, + /* 150 */ 163, 20, 155, 39, 34, 37, 54, 32, 55, 41, + /* 160 */ 39, 34, 37, 54, 32, 55, 41, 39, 34, 37, + /* 170 */ 54, 32, 55, 41, 47, 56, 5, 153, 132, 114, + /* 180 */ 7, 19, 39, 34, 37, 54, 32, 55, 41, 39, + /* 190 */ 34, 37, 54, 32, 55, 41, 39, 34, 37, 54, + /* 200 */ 32, 55, 41, 167, 86, 24, 30, 82, 112, 114, + /* 210 */ 36, 157, 152, 26, 168, 101, 110, 39, 34, 37, + /* 220 */ 54, 32, 55, 41, 142, 106, 55, 41, 159, 86, + /* 230 */ 39, 34, 37, 54, 32, 55, 41, 39, 34, 37, + /* 240 */ 54, 32, 55, 41, 52, 64, 98, 128, 165, 108, + /* 250 */ 106, 21, 117, 39, 34, 37, 54, 32, 55, 41, + /* 260 */ 39, 34, 37, 54, 32, 55, 41, 25, 269, 1, + /* 270 */ 10, 82, 39, 34, 37, 54, 32, 55, 41, 4, + /* 280 */ 121, 68, 43, 122, 131, 39, 34, 37, 54, 32, + /* 290 */ 55, 41, 39, 34, 37, 54, 32, 55, 41, 18, + /* 300 */ 94, 130, 78, 27, 57, 35, 17, 60, 39, 34, + /* 310 */ 37, 54, 32, 55, 41, 39, 34, 37, 54, 32, + /* 320 */ 55, 41, 31, 39, 34, 37, 54, 32, 55, 41, + /* 330 */ 39, 34, 37, 54, 32, 55, 41, 33, 59, 30, + /* 340 */ 28, 13, 30, 107, 157, 152, 26, 157, 152, 26, + /* 350 */ 30, 141, 138, 30, 116, 157, 152, 26, 157, 152, + /* 360 */ 26, 30, 12, 125, 30, 84, 157, 152, 26, 157, + /* 370 */ 152, 26, 30, 137, 111, 119, 3, 157, 152, 26, + /* 380 */ 66, 15, 129, 133, 85, 103, 40, 62, 22, 61, + /* 390 */ 93, 135, 161, 158, 134, 87, 118, 143, 95, 38, + /* 400 */ 65, 2, 97, 46, 113, 48, 88, 156, 105, 67, + /* 410 */ 270, 96, 8, 69, 99, 91, 160, 270, 270, 72, + /* 420 */ 90, 74, 77, 76, 270, 270, 75, 270, 270, 270, + /* 430 */ 92, 270, 58, 73, 270, 89, 270, 63, +}; +static const YYCODETYPE yy_lookahead[] = { + /* 0 */ 0, 4, 39, 40, 4, 39, 9, 10, 11, 9, + /* 10 */ 10, 11, 39, 13, 14, 39, 19, 39, 18, 43, + /* 20 */ 20, 39, 22, 41, 42, 25, 39, 40, 28, 51, + /* 30 */ 52, 53, 54, 55, 56, 57, 58, 64, 65, 61, + /* 40 */ 29, 1, 2, 3, 4, 5, 6, 7, 1, 2, + /* 50 */ 3, 4, 5, 6, 7, 15, 2, 3, 4, 5, + /* 60 */ 6, 7, 15, 44, 1, 2, 3, 4, 5, 6, + /* 70 */ 7, 1, 2, 3, 4, 5, 6, 7, 15, 3, + /* 80 */ 4, 5, 6, 7, 11, 15, 11, 1, 2, 3, + /* 90 */ 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, + /* 100 */ 7, 15, 30, 31, 32, 33, 34, 39, 15, 21, + /* 110 */ 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, + /* 120 */ 7, 12, 39, 1, 2, 3, 4, 5, 6, 7, + /* 130 */ 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, + /* 140 */ 4, 5, 6, 7, 15, 45, 46, 47, 65, 27, + /* 150 */ 39, 15, 12, 1, 2, 3, 4, 5, 6, 7, + /* 160 */ 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, + /* 170 */ 4, 5, 6, 7, 15, 45, 46, 47, 62, 63, + /* 180 */ 28, 15, 1, 2, 3, 4, 5, 6, 7, 1, + /* 190 */ 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, + /* 200 */ 5, 6, 7, 24, 39, 24, 4, 39, 62, 63, + /* 210 */ 15, 9, 10, 11, 35, 27, 48, 1, 2, 3, + /* 220 */ 4, 5, 6, 7, 59, 60, 6, 7, 12, 39, + /* 230 */ 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, + /* 240 */ 4, 5, 6, 7, 15, 39, 39, 41, 42, 59, + /* 250 */ 60, 15, 19, 1, 2, 3, 4, 5, 6, 7, + /* 260 */ 1, 2, 3, 4, 5, 6, 7, 15, 49, 50, + /* 270 */ 11, 39, 1, 2, 3, 4, 5, 6, 7, 23, + /* 280 */ 48, 39, 15, 12, 12, 1, 2, 3, 4, 5, + /* 290 */ 6, 7, 1, 2, 3, 4, 5, 6, 7, 15, + /* 300 */ 39, 23, 39, 15, 39, 15, 15, 39, 1, 2, + /* 310 */ 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, + /* 320 */ 6, 7, 15, 1, 2, 3, 4, 5, 6, 7, + /* 330 */ 1, 2, 3, 4, 5, 6, 7, 15, 39, 4, + /* 340 */ 24, 11, 4, 29, 9, 10, 11, 9, 10, 11, + /* 350 */ 4, 16, 17, 4, 10, 9, 10, 11, 9, 10, + /* 360 */ 11, 4, 15, 19, 4, 39, 9, 10, 11, 9, + /* 370 */ 10, 11, 4, 26, 36, 37, 11, 9, 10, 11, + /* 380 */ 39, 15, 36, 21, 39, 36, 15, 39, 15, 39, + /* 390 */ 39, 12, 39, 36, 16, 39, 36, 12, 39, 11, + /* 400 */ 39, 15, 39, 11, 36, 15, 39, 12, 19, 39, + /* 410 */ 66, 39, 15, 39, 39, 39, 39, 66, 66, 39, + /* 420 */ 39, 39, 39, 39, 66, 66, 39, 66, 66, 66, + /* 430 */ 39, 66, 39, 39, 66, 39, 66, 39, +}; +#define YY_SHIFT_USE_DFLT (-4) +#define YY_SHIFT_MAX 129 +static const short yy_shift_ofst[] = { + /* 0 */ -4, 0, 335, 335, 72, 72, 202, 202, 202, 338, + /* 10 */ 338, 202, 202, 202, 202, 233, 233, 346, 349, 368, + /* 20 */ 357, -3, 360, 202, 202, 202, 202, 202, 202, 202, + /* 30 */ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + /* 40 */ 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + /* 50 */ 202, 202, 202, 202, 202, 202, 179, 229, 40, 63, + /* 60 */ 70, 86, 93, 109, 122, 129, 136, 322, 314, 307, + /* 70 */ 291, 284, 271, 259, 252, 236, 47, 216, 195, 188, + /* 80 */ 181, 166, 159, 152, 329, 329, 329, 329, 329, 329, + /* 90 */ 329, 329, 329, 329, 329, 54, 76, 113, 220, 220, + /* 100 */ 347, 344, 395, 390, 389, 392, 386, 388, 385, 378, + /* 110 */ 379, 373, 362, 371, 366, 365, 330, 316, 290, 288, + /* 120 */ 278, 272, 256, 140, 88, 75, 73, 11, 397, 267, +}; +#define YY_REDUCE_USE_DFLT (-38) +#define YY_REDUCE_MAX 56 +static const short yy_reduce_ofst[] = { + /* 0 */ 219, -22, 165, 190, 100, 130, -27, -18, 206, -37, + /* 10 */ -13, -24, 83, 168, 232, 116, 146, 68, -34, 341, + /* 20 */ 396, 394, 393, 391, 387, 384, 383, 382, 381, 380, + /* 30 */ 377, 376, 375, 374, 372, 370, 367, 363, 361, 359, + /* 40 */ 356, 353, 351, 350, 348, 345, 398, 326, 299, 268, + /* 50 */ 265, 263, 261, 242, 207, 111, 19, +}; +static const YYACTIONTYPE yy_default[] = { + /* 0 */ 186, 268, 197, 197, 223, 223, 268, 268, 268, 238, + /* 10 */ 238, 268, 268, 217, 217, 207, 207, 268, 268, 268, + /* 20 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + /* 30 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + /* 40 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + /* 50 */ 268, 268, 268, 268, 268, 268, 268, 260, 240, 259, + /* 60 */ 241, 263, 242, 268, 268, 268, 256, 245, 268, 246, + /* 70 */ 254, 253, 268, 268, 249, 268, 250, 268, 251, 268, + /* 80 */ 268, 255, 218, 233, 219, 264, 201, 266, 252, 257, + /* 90 */ 211, 247, 237, 243, 261, 181, 183, 182, 178, 177, + /* 100 */ 268, 268, 268, 258, 268, 268, 198, 268, 268, 268, + /* 110 */ 268, 239, 268, 265, 208, 268, 268, 210, 244, 248, + /* 120 */ 268, 268, 268, 268, 268, 268, 268, 268, 235, 262, + /* 130 */ 206, 215, 209, 205, 204, 216, 203, 212, 202, 214, + /* 140 */ 213, 200, 199, 196, 195, 194, 193, 192, 191, 190, + /* 150 */ 188, 222, 176, 224, 187, 221, 220, 175, 267, 185, + /* 160 */ 184, 180, 234, 179, 189, 236, 225, 231, 232, 226, + /* 170 */ 227, 228, 229, 230, +}; +#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) + +/* The next table maps tokens into fallback tokens. If a construct +** like the following: +** +** %fallback ID X Y Z. +** +** appears in the grammer, then ID becomes a fallback token for X, Y, +** and Z. Whenever one of the tokens X, Y, or Z is input to the parser +** but it does not parse, the type of the token is changed to ID and +** the parse is retried before an error is thrown. +*/ +#ifdef YYFALLBACK +static const YYCODETYPE yyFallback[] = { +}; +#endif /* YYFALLBACK */ + +/* The following structure represents a single element of the +** parser's stack. Information stored includes: +** +** + The state number for the parser at this level of the stack. +** +** + The value of the token stored at this level of the stack. +** (In other words, the "major" token.) +** +** + The semantic value stored at this level of the stack. This is +** the information used by the action routines in the grammar. +** It is sometimes called the "minor" token. +*/ +struct yyStackEntry { + int stateno; /* The state-number */ + int major; /* The major token value. This is the code + ** number for the token at this stack level */ + YYMINORTYPE minor; /* The user-supplied minor token value. This + ** is the value of the token */ +}; +typedef struct yyStackEntry yyStackEntry; + +/* The state of the parser is completely contained in an instance of +** the following structure */ +struct yyParser { + int yyidx; /* Index of top element in stack */ + int yyerrcnt; /* Shifts left before out of the error */ + ParseARG_SDECL /* A place to hold %extra_argument */ +#if YYSTACKDEPTH<=0 + int yystksz; /* Current side of the stack */ + yyStackEntry *yystack; /* The parser's stack */ +#else + yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ +#endif +}; +typedef struct yyParser yyParser; + +#ifndef NDEBUG +#include +static FILE *yyTraceFILE = 0; +static char *yyTracePrompt = 0; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Turn parser tracing on by giving a stream to which to write the trace +** and a prompt to preface each trace message. Tracing is turned off +** by making either argument NULL +** +** Inputs: +**
    +**
  • A FILE* to which trace output should be written. +** If NULL, then tracing is turned off. +**
  • A prefix string written at the beginning of every +** line of trace output. If NULL, then tracing is +** turned off. +**
+** +** Outputs: +** None. +*/ +void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ + yyTraceFILE = TraceFILE; + yyTracePrompt = zTracePrompt; + if( yyTraceFILE==0 ) yyTracePrompt = 0; + else if( yyTracePrompt==0 ) yyTraceFILE = 0; +} +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* For tracing shifts, the names of all terminals and nonterminals +** are required. The following table supplies these names */ +static const char *const yyTokenName[] = { + "$", "OR", "XOR", "AND", + "MINUS", "PLUS", "MULTIPLY", "DIVIDE", + "NEG", "NUM", "SYMNUM", "LPAREN", + "RPAREN", "NOP", "PRINT", "COMMA", + "STRING", "ENDL", "DEFINE", "SYM", + "INCLUDE", "RBRACE", "ENUM", "LBRACE", + "EQUALS", "SPECIAL", "SEMICOLON", "COLON", + "LBRACKET", "RBRACKET", "FLAGS", "ARG2", + "ARG3", "ARG4", "ARG5", "OR_EQUAL", + "TAG", "LINEID", "error", "exp", + "special_args", "list_val", "arg_list", "boom_args", + "boom_op", "boom_selector", "boom_line", "boom_body", + "maybe_argcount", "main", "translation_unit", "external_declaration", + "define_statement", "include_statement", "print_statement", "enum_statement", + "linetype_declaration", "boom_declaration", "special_declaration", "print_list", + "print_item", "enum_open", "enum_list", "single_enum", + "special_list", "special_def", +}; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* For tracing reduce actions, the names of all rules are required. +*/ +static const char *const yyRuleName[] = { + /* 0 */ "main ::= translation_unit", + /* 1 */ "exp ::= NUM", + /* 2 */ "exp ::= SYMNUM", + /* 3 */ "exp ::= exp PLUS exp", + /* 4 */ "exp ::= exp MINUS exp", + /* 5 */ "exp ::= exp MULTIPLY exp", + /* 6 */ "exp ::= exp DIVIDE exp", + /* 7 */ "exp ::= exp OR exp", + /* 8 */ "exp ::= exp AND exp", + /* 9 */ "exp ::= exp XOR exp", + /* 10 */ "exp ::= MINUS exp", + /* 11 */ "exp ::= LPAREN exp RPAREN", + /* 12 */ "translation_unit ::=", + /* 13 */ "translation_unit ::= translation_unit external_declaration", + /* 14 */ "external_declaration ::= define_statement", + /* 15 */ "external_declaration ::= include_statement", + /* 16 */ "external_declaration ::= print_statement", + /* 17 */ "external_declaration ::= enum_statement", + /* 18 */ "external_declaration ::= linetype_declaration", + /* 19 */ "external_declaration ::= boom_declaration", + /* 20 */ "external_declaration ::= special_declaration", + /* 21 */ "external_declaration ::= NOP", + /* 22 */ "print_statement ::= PRINT LPAREN print_list RPAREN", + /* 23 */ "print_list ::=", + /* 24 */ "print_list ::= print_item", + /* 25 */ "print_list ::= print_item COMMA print_list", + /* 26 */ "print_item ::= STRING", + /* 27 */ "print_item ::= exp", + /* 28 */ "print_item ::= ENDL", + /* 29 */ "define_statement ::= DEFINE SYM LPAREN exp RPAREN", + /* 30 */ "include_statement ::= INCLUDE STRING", + /* 31 */ "enum_statement ::= enum_open enum_list RBRACE", + /* 32 */ "enum_open ::= ENUM LBRACE", + /* 33 */ "enum_list ::=", + /* 34 */ "enum_list ::= single_enum", + /* 35 */ "enum_list ::= single_enum COMMA enum_list", + /* 36 */ "single_enum ::= SYM", + /* 37 */ "single_enum ::= SYM EQUALS exp", + /* 38 */ "special_declaration ::= SPECIAL special_list SEMICOLON", + /* 39 */ "special_list ::= special_def", + /* 40 */ "special_list ::= special_list COMMA special_def", + /* 41 */ "special_def ::= exp COLON SYM LPAREN maybe_argcount RPAREN", + /* 42 */ "special_def ::= exp COLON SYMNUM LPAREN maybe_argcount RPAREN", + /* 43 */ "maybe_argcount ::=", + /* 44 */ "maybe_argcount ::= exp", + /* 45 */ "maybe_argcount ::= exp COMMA exp", + /* 46 */ "linetype_declaration ::= exp EQUALS exp COMMA exp LPAREN special_args RPAREN", + /* 47 */ "linetype_declaration ::= exp EQUALS exp COMMA SYM LPAREN special_args RPAREN", + /* 48 */ "boom_declaration ::= LBRACKET exp RBRACKET LPAREN exp COMMA exp RPAREN LBRACE boom_body RBRACE", + /* 49 */ "boom_body ::=", + /* 50 */ "boom_body ::= boom_line boom_body", + /* 51 */ "boom_line ::= boom_selector boom_op boom_args", + /* 52 */ "boom_selector ::= FLAGS", + /* 53 */ "boom_selector ::= ARG2", + /* 54 */ "boom_selector ::= ARG3", + /* 55 */ "boom_selector ::= ARG4", + /* 56 */ "boom_selector ::= ARG5", + /* 57 */ "boom_op ::= EQUALS", + /* 58 */ "boom_op ::= OR_EQUAL", + /* 59 */ "boom_args ::= exp", + /* 60 */ "boom_args ::= exp LBRACKET arg_list RBRACKET", + /* 61 */ "arg_list ::= list_val", + /* 62 */ "arg_list ::= list_val COMMA arg_list", + /* 63 */ "list_val ::= exp COLON exp", + /* 64 */ "special_args ::=", + /* 65 */ "special_args ::= TAG", + /* 66 */ "special_args ::= TAG COMMA exp", + /* 67 */ "special_args ::= TAG COMMA exp COMMA exp", + /* 68 */ "special_args ::= TAG COMMA exp COMMA exp COMMA exp", + /* 69 */ "special_args ::= TAG COMMA exp COMMA exp COMMA exp COMMA exp", + /* 70 */ "special_args ::= TAG COMMA TAG", + /* 71 */ "special_args ::= TAG COMMA TAG COMMA exp", + /* 72 */ "special_args ::= TAG COMMA TAG COMMA exp COMMA exp", + /* 73 */ "special_args ::= TAG COMMA TAG COMMA exp COMMA exp COMMA exp", + /* 74 */ "special_args ::= LINEID", + /* 75 */ "special_args ::= LINEID COMMA exp", + /* 76 */ "special_args ::= LINEID COMMA exp COMMA exp", + /* 77 */ "special_args ::= LINEID COMMA exp COMMA exp COMMA exp", + /* 78 */ "special_args ::= LINEID COMMA exp COMMA exp COMMA exp COMMA exp", + /* 79 */ "special_args ::= exp", + /* 80 */ "special_args ::= exp COMMA exp", + /* 81 */ "special_args ::= exp COMMA exp COMMA exp", + /* 82 */ "special_args ::= exp COMMA exp COMMA exp COMMA exp", + /* 83 */ "special_args ::= exp COMMA exp COMMA exp COMMA exp COMMA exp", + /* 84 */ "special_args ::= exp COMMA TAG", + /* 85 */ "special_args ::= exp COMMA TAG COMMA exp", + /* 86 */ "special_args ::= exp COMMA TAG COMMA exp COMMA exp", + /* 87 */ "special_args ::= exp COMMA TAG COMMA exp COMMA exp COMMA exp", + /* 88 */ "special_args ::= exp COMMA exp COMMA TAG", + /* 89 */ "special_args ::= exp COMMA exp COMMA TAG COMMA exp", + /* 90 */ "special_args ::= exp COMMA exp COMMA TAG COMMA exp COMMA exp", + /* 91 */ "special_args ::= exp COMMA exp COMMA exp COMMA TAG", + /* 92 */ "special_args ::= exp COMMA exp COMMA exp COMMA TAG COMMA exp", + /* 93 */ "special_args ::= exp COMMA exp COMMA exp COMMA exp COMMA TAG", +}; +#endif /* NDEBUG */ + +#if YYSTACKDEPTH<=0 +/* +** Try to increase the size of the parser stack. +*/ +static void yyGrowStack(yyParser *p){ + int newSize; + yyStackEntry *pNew; + + newSize = p->yystksz*2 + 100; + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + if( pNew ){ + p->yystack = pNew; + p->yystksz = newSize; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", + yyTracePrompt, p->yystksz); + } +#endif + } +} +#endif + +/* +** This function allocates a new parser. +** The only argument is a pointer to a function which works like +** malloc. +** +** Inputs: +** A pointer to the function used to allocate memory. +** +** Outputs: +** A pointer to a parser. This pointer is used in subsequent calls +** to Parse and ParseFree. +*/ +void *ParseAlloc(void *(*mallocProc)(size_t)){ + yyParser *pParser; + pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); + if( pParser ){ + pParser->yyidx = -1; +#if YYSTACKDEPTH<=0 + yyGrowStack(pParser); +#endif + } + return pParser; +} + +/* The following function deletes the value associated with a +** symbol. The symbol can be either a terminal or nonterminal. +** "yymajor" is the symbol code, and "yypminor" is a pointer to +** the value. +*/ +static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ + switch( yymajor ){ + /* Here is inserted the actions which take place when a + ** terminal or non-terminal is destroyed. This can happen + ** when the symbol is popped from the stack during a + ** reduce or during error processing or when a parser is + ** being destroyed before it is finished parsing. + ** + ** Note: during a reduce, the only symbols destroyed are those + ** which appear on the RHS of the rule, but which are not used + ** inside the C code. + */ + default: break; /* If no destructor action specified: do nothing */ + } +} + +/* +** Pop the parser's stack once. +** +** If there is a destructor routine associated with the token which +** is popped from the stack, then call it. +** +** Return the major token number for the symbol popped. +*/ +static int yy_pop_parser_stack(yyParser *pParser){ + YYCODETYPE yymajor; + yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; + + if( pParser->yyidx<0 ) return 0; +#ifndef NDEBUG + if( yyTraceFILE && pParser->yyidx>=0 ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + yymajor = yytos->major; + yy_destructor( yymajor, &yytos->minor); + pParser->yyidx--; + return yymajor; +} + +/* +** Deallocate and destroy a parser. Destructors are all called for +** all stack elements before shutting the parser down. +** +** Inputs: +**
    +**
  • A pointer to the parser. This should be a pointer +** obtained from ParseAlloc. +**
  • A pointer to a function used to reclaim memory obtained +** from malloc. +**
+*/ +void ParseFree( + void *p, /* The parser to be deleted */ + void (*freeProc)(void*) /* Function used to reclaim memory */ +){ + yyParser *pParser = (yyParser*)p; + if( pParser==0 ) return; + while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + free(pParser->yystack); +#endif + (*freeProc)((void*)pParser); +} + +/* +** Find the appropriate action for a parser given the terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_shift_action( + yyParser *pParser, /* The parser */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; + int stateno = pParser->yystack[pParser->yyidx].stateno; + + if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ + return yy_default[stateno]; + } + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + if( iLookAhead>0 ){ +#ifdef YYFALLBACK + int iFallback; /* Fallback token */ + if( iLookAhead %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + } +#endif + return yy_find_shift_action(pParser, iFallback); + } +#endif +#ifdef YYWILDCARD + { + int j = i - iLookAhead + YYWILDCARD; + if( j>=0 && j %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); + } +#endif /* NDEBUG */ + return yy_action[j]; + } + } +#endif /* YYWILDCARD */ + } + return yy_default[stateno]; + }else{ + return yy_action[i]; + } +} + +/* +** Find the appropriate action for a parser given the non-terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_reduce_action( + int stateno, /* Current state number */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; + if( stateno>YY_REDUCE_MAX || + (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){ + return yy_default[stateno]; + } + assert( i!=YY_REDUCE_USE_DFLT ); + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + return yy_default[stateno]; + }else{ + return yy_action[i]; + } + return yy_action[i]; +} + +/* +** The following routine is called if the stack overflows. +*/ +static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){ + ParseARG_FETCH; + yypParser->yyidx--; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will execute if the parser + ** stack every overflows */ + ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ +} + +/* +** Perform a shift action. +*/ +static void yy_shift( + yyParser *yypParser, /* The parser to be shifted */ + int yyNewState, /* The new state to shift in */ + int yyMajor, /* The major token to shift in */ + YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */ +){ + yyStackEntry *yytos; + yypParser->yyidx++; +#if YYSTACKDEPTH>0 + if( yypParser->yyidx>=YYSTACKDEPTH ){ + yyStackOverflow(yypParser, yypMinor); + return; + } +#else + if( yypParser->yyidx>=yypParser->yystksz ){ + yyGrowStack(yypParser); + if( yypParser->yyidx>=yypParser->yystksz ){ + yyStackOverflow(yypParser, yypMinor); + return; + } + } +#endif + yytos = &yypParser->yystack[yypParser->yyidx]; + yytos->stateno = yyNewState; + yytos->major = yyMajor; + yytos->minor = *yypMinor; +#ifndef NDEBUG + if( yyTraceFILE && yypParser->yyidx>0 ){ + int i; + fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); + fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); + for(i=1; i<=yypParser->yyidx; i++) + fprintf(yyTraceFILE," (%d)%s",yypParser->yystack[i].stateno,yyTokenName[yypParser->yystack[i].major]); + fprintf(yyTraceFILE,"\n"); + } +#endif +} + +/* The following table contains information about every rule that +** is used during the reduce. +*/ +static const struct { + YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ + unsigned char nrhs; /* Number of right-hand side symbols in the rule */ +} yyRuleInfo[] = { + { 49, 1 }, + { 39, 1 }, + { 39, 1 }, + { 39, 3 }, + { 39, 3 }, + { 39, 3 }, + { 39, 3 }, + { 39, 3 }, + { 39, 3 }, + { 39, 3 }, + { 39, 2 }, + { 39, 3 }, + { 50, 0 }, + { 50, 2 }, + { 51, 1 }, + { 51, 1 }, + { 51, 1 }, + { 51, 1 }, + { 51, 1 }, + { 51, 1 }, + { 51, 1 }, + { 51, 1 }, + { 54, 4 }, + { 59, 0 }, + { 59, 1 }, + { 59, 3 }, + { 60, 1 }, + { 60, 1 }, + { 60, 1 }, + { 52, 5 }, + { 53, 2 }, + { 55, 3 }, + { 61, 2 }, + { 62, 0 }, + { 62, 1 }, + { 62, 3 }, + { 63, 1 }, + { 63, 3 }, + { 58, 3 }, + { 64, 1 }, + { 64, 3 }, + { 65, 6 }, + { 65, 6 }, + { 48, 0 }, + { 48, 1 }, + { 48, 3 }, + { 56, 8 }, + { 56, 8 }, + { 57, 11 }, + { 47, 0 }, + { 47, 2 }, + { 46, 3 }, + { 45, 1 }, + { 45, 1 }, + { 45, 1 }, + { 45, 1 }, + { 45, 1 }, + { 44, 1 }, + { 44, 1 }, + { 43, 1 }, + { 43, 4 }, + { 42, 1 }, + { 42, 3 }, + { 41, 3 }, + { 40, 0 }, + { 40, 1 }, + { 40, 3 }, + { 40, 5 }, + { 40, 7 }, + { 40, 9 }, + { 40, 3 }, + { 40, 5 }, + { 40, 7 }, + { 40, 9 }, + { 40, 1 }, + { 40, 3 }, + { 40, 5 }, + { 40, 7 }, + { 40, 9 }, + { 40, 1 }, + { 40, 3 }, + { 40, 5 }, + { 40, 7 }, + { 40, 9 }, + { 40, 3 }, + { 40, 5 }, + { 40, 7 }, + { 40, 9 }, + { 40, 5 }, + { 40, 7 }, + { 40, 9 }, + { 40, 7 }, + { 40, 9 }, + { 40, 9 }, +}; + +static void yy_accept(yyParser*); /* Forward Declaration */ + +/* +** Perform a reduce action and the shift that must immediately +** follow the reduce. +*/ +static void yy_reduce( + yyParser *yypParser, /* The parser */ + int yyruleno /* Number of the rule by which to reduce */ +){ + int yygoto; /* The next state */ + int yyact; /* The next action */ + YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ + yyStackEntry *yymsp; /* The top of the parser's stack */ + int yysize; /* Amount to pop the stack */ + ParseARG_FETCH; + yymsp = &yypParser->yystack[yypParser->yyidx]; +#ifndef NDEBUG + if( yyTraceFILE && yyruleno>=0 + && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, + yyRuleName[yyruleno]); + } +#endif /* NDEBUG */ + + /* Silence complaints from purify about yygotominor being uninitialized + ** in some cases when it is copied into the stack after the following + ** switch. yygotominor is uninitialized when a rule reduces that does + ** not set the value of its left-hand side nonterminal. Leaving the + ** value of the nonterminal uninitialized is utterly harmless as long + ** as the value is never used. So really the only thing this code + ** accomplishes is to quieten purify. + ** + ** 2007-01-16: The wireshark project (www.wireshark.org) reports that + ** without this code, their parser segfaults. I'm not sure what there + ** parser is doing to make this happen. This is the second bug report + ** from wireshark this week. Clearly they are stressing Lemon in ways + ** that it has not been previously stressed... (SQLite ticket #2172) + */ + memset(&yygotominor, 0, sizeof(yygotominor)); + + + switch( yyruleno ){ + /* Beginning here are the reduction cases. A typical example + ** follows: + ** case 0: + ** #line + ** { ... } // User supplied code + ** #line + ** break; + */ + case 0: /* main ::= translation_unit */ + case 12: /*translation_unit ::= */ + case 13: /*translation_unit ::= translation_unit external_declaration */ + case 14: /*external_declaration ::= define_statement */ + case 15: /*external_declaration ::= include_statement */ + case 16: /*external_declaration ::= print_statement */ + case 17: /*external_declaration ::= enum_statement */ + case 18: /*external_declaration ::= linetype_declaration */ + case 19: /*external_declaration ::= boom_declaration */ + case 20: /*external_declaration ::= special_declaration */ + case 21: /*external_declaration ::= NOP */ + case 23: /*print_list ::= */ + case 24: /*print_list ::= print_item */ + case 25: /*print_list ::= print_item COMMA print_list */ + case 31: /*enum_statement ::= enum_open enum_list RBRACE */ + case 33: /*enum_list ::= */ + case 34: /*enum_list ::= single_enum */ + case 35: /*enum_list ::= single_enum COMMA enum_list */ + case 38: /*special_declaration ::= SPECIAL special_list SEMICOLON */ + case 39: /*special_list ::= special_def */ + case 40: /*special_list ::= special_list COMMA special_def */ + case 43: /*maybe_argcount ::= */ + case 44: /*maybe_argcount ::= exp */ + case 45: /*maybe_argcount ::= exp COMMA exp */ +#line 365 "xlat-parse.y" +{ +} +#line 1266 "xlat-parse.c" + break; + case 1: /* exp ::= NUM */ +#line 367 "xlat-parse.y" +{ yygotominor.yy64 = yymsp[0].minor.yy0.val; } +#line 1271 "xlat-parse.c" + break; + case 2: /* exp ::= SYMNUM */ +#line 368 "xlat-parse.y" +{ yygotominor.yy64 = yymsp[0].minor.yy0.symval->Value; } +#line 1276 "xlat-parse.c" + break; + case 3: /* exp ::= exp PLUS exp */ +#line 369 "xlat-parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 + yymsp[0].minor.yy64; } +#line 1281 "xlat-parse.c" + break; + case 4: /* exp ::= exp MINUS exp */ +#line 370 "xlat-parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 - yymsp[0].minor.yy64; } +#line 1286 "xlat-parse.c" + break; + case 5: /* exp ::= exp MULTIPLY exp */ +#line 371 "xlat-parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 * yymsp[0].minor.yy64; } +#line 1291 "xlat-parse.c" + break; + case 6: /* exp ::= exp DIVIDE exp */ +#line 372 "xlat-parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 / yymsp[0].minor.yy64; } +#line 1296 "xlat-parse.c" + break; + case 7: /* exp ::= exp OR exp */ +#line 373 "xlat-parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 | yymsp[0].minor.yy64; } +#line 1301 "xlat-parse.c" + break; + case 8: /* exp ::= exp AND exp */ +#line 374 "xlat-parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 & yymsp[0].minor.yy64; } +#line 1306 "xlat-parse.c" + break; + case 9: /* exp ::= exp XOR exp */ +#line 375 "xlat-parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 ^ yymsp[0].minor.yy64; } +#line 1311 "xlat-parse.c" + break; + case 10: /* exp ::= MINUS exp */ +#line 376 "xlat-parse.y" +{ yygotominor.yy64 = -yymsp[0].minor.yy64; } +#line 1316 "xlat-parse.c" + break; + case 11: /* exp ::= LPAREN exp RPAREN */ +#line 377 "xlat-parse.y" +{ yygotominor.yy64 = yymsp[-1].minor.yy64; } +#line 1321 "xlat-parse.c" + break; + case 22: /* print_statement ::= PRINT LPAREN print_list RPAREN */ +#line 392 "xlat-parse.y" +{ + printf ("\n"); +} +#line 1328 "xlat-parse.c" + break; + case 26: /* print_item ::= STRING */ +#line 400 "xlat-parse.y" +{ printf ("%s", yymsp[0].minor.yy0.string); } +#line 1333 "xlat-parse.c" + break; + case 27: /* print_item ::= exp */ +#line 401 "xlat-parse.y" +{ printf ("%d", yymsp[0].minor.yy64); } +#line 1338 "xlat-parse.c" + break; + case 28: /* print_item ::= ENDL */ +#line 402 "xlat-parse.y" +{ printf ("\n"); } +#line 1343 "xlat-parse.c" + break; + case 29: /* define_statement ::= DEFINE SYM LPAREN exp RPAREN */ +#line 405 "xlat-parse.y" +{ + AddSym (yymsp[-3].minor.yy0.sym, yymsp[-1].minor.yy64); +} +#line 1350 "xlat-parse.c" + break; + case 30: /* include_statement ::= INCLUDE STRING */ +#line 410 "xlat-parse.y" +{ + IncludeFile (yymsp[0].minor.yy0.string); +} +#line 1357 "xlat-parse.c" + break; + case 32: /* enum_open ::= ENUM LBRACE */ +#line 417 "xlat-parse.y" +{ + EnumVal = 0; +} +#line 1364 "xlat-parse.c" + break; + case 36: /* single_enum ::= SYM */ +#line 426 "xlat-parse.y" +{ + AddSym (yymsp[0].minor.yy0.sym, EnumVal++); +} +#line 1371 "xlat-parse.c" + break; + case 37: /* single_enum ::= SYM EQUALS exp */ +#line 431 "xlat-parse.y" +{ + AddSym (yymsp[-2].minor.yy0.sym, EnumVal = yymsp[0].minor.yy64); +} +#line 1378 "xlat-parse.c" + break; + case 41: /* special_def ::= exp COLON SYM LPAREN maybe_argcount RPAREN */ +#line 444 "xlat-parse.y" +{ + AddSym (yymsp[-3].minor.yy0.sym, yymsp[-5].minor.yy64); +} +#line 1385 "xlat-parse.c" + break; + case 42: /* special_def ::= exp COLON SYMNUM LPAREN maybe_argcount RPAREN */ +#line 448 "xlat-parse.y" +{ + printf ("%s, line %d: %s is already defined\n", SourceName, SourceLine, yymsp[-3].minor.yy0.symval->Sym); +} +#line 1392 "xlat-parse.c" + break; + case 46: /* linetype_declaration ::= exp EQUALS exp COMMA exp LPAREN special_args RPAREN */ +#line 457 "xlat-parse.y" +{ + Simple[yymsp[-7].minor.yy64].NewSpecial = yymsp[-3].minor.yy64; + Simple[yymsp[-7].minor.yy64].Flags = yymsp[-5].minor.yy64 | yymsp[-1].minor.yy123.addflags; + Simple[yymsp[-7].minor.yy64].Args[0] = yymsp[-1].minor.yy123.args[0]; + Simple[yymsp[-7].minor.yy64].Args[1] = yymsp[-1].minor.yy123.args[1]; + Simple[yymsp[-7].minor.yy64].Args[2] = yymsp[-1].minor.yy123.args[2]; + Simple[yymsp[-7].minor.yy64].Args[3] = yymsp[-1].minor.yy123.args[3]; + Simple[yymsp[-7].minor.yy64].Args[4] = yymsp[-1].minor.yy123.args[4]; +} +#line 1405 "xlat-parse.c" + break; + case 47: /* linetype_declaration ::= exp EQUALS exp COMMA SYM LPAREN special_args RPAREN */ +#line 467 "xlat-parse.y" +{ + printf ("%s, line %d: %s is undefined\n", SourceName, SourceLine, yymsp[-3].minor.yy0.sym); +} +#line 1412 "xlat-parse.c" + break; + case 48: /* boom_declaration ::= LBRACKET exp RBRACKET LPAREN exp COMMA exp RPAREN LBRACE boom_body RBRACE */ +#line 472 "xlat-parse.y" +{ + if (NumBoomish == MAX_BOOMISH) + { + MoreLines *probe = yymsp[-1].minor.yy57; + + while (probe != NULL) + { + MoreLines *next = probe->next; + free (probe); + probe = next; + } + printf ("%s, line %d: Too many BOOM translators\n", SourceName, SourceLine); + } + else + { + int i; + MoreLines *probe; + + Boomish[NumBoomish].FirstLinetype = yymsp[-6].minor.yy64; + Boomish[NumBoomish].LastLinetype = yymsp[-4].minor.yy64; + Boomish[NumBoomish].NewSpecial = yymsp[-9].minor.yy64; + + for (i = 0, probe = yymsp[-1].minor.yy57; probe != NULL; i++) + { + MoreLines *next = probe->next;; + if (i < MAX_BOOMISH_EXEC) + { + Boomish[NumBoomish].Args[i] = probe->arg; + } + else if (i == MAX_BOOMISH_EXEC) + { + printf ("%s, line %d: Too many commands for this BOOM translator\n", SourceName, SourceLine); + } + free (probe); + probe = next; + } + if (i < MAX_BOOMISH_EXEC) + { + Boomish[NumBoomish].Args[i].bDefined = 0; + } + NumBoomish++; + } +} +#line 1459 "xlat-parse.c" + break; + case 49: /* boom_body ::= */ +#line 517 "xlat-parse.y" +{ + yygotominor.yy57 = NULL; +} +#line 1466 "xlat-parse.c" + break; + case 50: /* boom_body ::= boom_line boom_body */ +#line 521 "xlat-parse.y" +{ + yygotominor.yy57 = malloc (sizeof(MoreLines)); + yygotominor.yy57->next = yymsp[0].minor.yy57; + yygotominor.yy57->arg = yymsp[-1].minor.yy65; +} +#line 1475 "xlat-parse.c" + break; + case 51: /* boom_line ::= boom_selector boom_op boom_args */ +#line 528 "xlat-parse.y" +{ + yygotominor.yy65.bDefined = 1; + yygotominor.yy65.bOrExisting = (yymsp[-1].minor.yy64 == OR_EQUAL); + yygotominor.yy65.bUseConstant = (yymsp[0].minor.yy87.filters == NULL); + yygotominor.yy65.ArgNum = yymsp[-2].minor.yy64; + yygotominor.yy65.ConstantValue = yymsp[0].minor.yy87.constant; + yygotominor.yy65.AndValue = yymsp[0].minor.yy87.mask; + + if (yymsp[0].minor.yy87.filters != NULL) + { + int i; + MoreFilters *probe; + + for (i = 0, probe = yymsp[0].minor.yy87.filters; probe != NULL; i++) + { + MoreFilters *next = probe->next; + if (i < 15) + { + yygotominor.yy65.ResultFilter[i] = probe->filter.filter; + yygotominor.yy65.ResultValue[i] = probe->filter.value; + } + else if (i == 15) + { + yyerror ("Lists can only have 15 elements"); + } + free (probe); + probe = next; + } + yygotominor.yy65.ListSize = i > 15 ? 15 : i; + } +} +#line 1510 "xlat-parse.c" + break; + case 52: /* boom_selector ::= FLAGS */ +#line 560 "xlat-parse.y" +{ yygotominor.yy64 = 4; } +#line 1515 "xlat-parse.c" + break; + case 53: /* boom_selector ::= ARG2 */ +#line 561 "xlat-parse.y" +{ yygotominor.yy64 = 0; } +#line 1520 "xlat-parse.c" + break; + case 54: /* boom_selector ::= ARG3 */ +#line 562 "xlat-parse.y" +{ yygotominor.yy64 = 1; } +#line 1525 "xlat-parse.c" + break; + case 55: /* boom_selector ::= ARG4 */ +#line 563 "xlat-parse.y" +{ yygotominor.yy64 = 2; } +#line 1530 "xlat-parse.c" + break; + case 56: /* boom_selector ::= ARG5 */ +#line 564 "xlat-parse.y" +{ yygotominor.yy64 = 3; } +#line 1535 "xlat-parse.c" + break; + case 57: /* boom_op ::= EQUALS */ +#line 566 "xlat-parse.y" +{ yygotominor.yy64 = '='; } +#line 1540 "xlat-parse.c" + break; + case 58: /* boom_op ::= OR_EQUAL */ +#line 567 "xlat-parse.y" +{ yygotominor.yy64 = OR_EQUAL; } +#line 1545 "xlat-parse.c" + break; + case 59: /* boom_args ::= exp */ +#line 570 "xlat-parse.y" +{ + yygotominor.yy87.constant = yymsp[0].minor.yy64; + yygotominor.yy87.filters = NULL; +} +#line 1553 "xlat-parse.c" + break; + case 60: /* boom_args ::= exp LBRACKET arg_list RBRACKET */ +#line 575 "xlat-parse.y" +{ + yygotominor.yy87.mask = yymsp[-3].minor.yy64; + yygotominor.yy87.filters = yymsp[-1].minor.yy39; +} +#line 1561 "xlat-parse.c" + break; + case 61: /* arg_list ::= list_val */ +#line 581 "xlat-parse.y" +{ + yygotominor.yy39 = malloc (sizeof(MoreFilters)); + yygotominor.yy39->next = NULL; + yygotominor.yy39->filter = yymsp[0].minor.yy20; +} +#line 1570 "xlat-parse.c" + break; + case 62: /* arg_list ::= list_val COMMA arg_list */ +#line 587 "xlat-parse.y" +{ + yygotominor.yy39 = malloc (sizeof(MoreFilters)); + yygotominor.yy39->next = yymsp[0].minor.yy39; + yygotominor.yy39->filter = yymsp[-2].minor.yy20; +} +#line 1579 "xlat-parse.c" + break; + case 63: /* list_val ::= exp COLON exp */ +#line 594 "xlat-parse.y" +{ + yygotominor.yy20.filter = yymsp[-2].minor.yy64; + yygotominor.yy20.value = yymsp[0].minor.yy64; +} +#line 1587 "xlat-parse.c" + break; + case 64: /* special_args ::= */ +#line 600 "xlat-parse.y" +{ + yygotominor.yy123.addflags = 0; + memset (yygotominor.yy123.args, 0, 5); +} +#line 1595 "xlat-parse.c" + break; + case 65: /* special_args ::= TAG */ +#line 605 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT1; + memset (yygotominor.yy123.args, 0, 5); +} +#line 1603 "xlat-parse.c" + break; + case 66: /* special_args ::= TAG COMMA exp */ +#line 610 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT1; + yygotominor.yy123.args[0] = 0; + yygotominor.yy123.args[1] = yymsp[0].minor.yy64; + yygotominor.yy123.args[2] = 0; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1615 "xlat-parse.c" + break; + case 67: /* special_args ::= TAG COMMA exp COMMA exp */ +#line 619 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT1; + yygotominor.yy123.args[0] = 0; + yygotominor.yy123.args[1] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[2] = yymsp[0].minor.yy64; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1627 "xlat-parse.c" + break; + case 68: /* special_args ::= TAG COMMA exp COMMA exp COMMA exp */ +#line 628 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT1; + yygotominor.yy123.args[0] = 0; + yygotominor.yy123.args[1] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[2] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[3] = yymsp[0].minor.yy64; + yygotominor.yy123.args[4] = 0; +} +#line 1639 "xlat-parse.c" + break; + case 69: /* special_args ::= TAG COMMA exp COMMA exp COMMA exp COMMA exp */ +#line 637 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT1; + yygotominor.yy123.args[0] = 0; + yygotominor.yy123.args[1] = yymsp[-6].minor.yy64; + yygotominor.yy123.args[2] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[3] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[4] = yymsp[0].minor.yy64; +} +#line 1651 "xlat-parse.c" + break; + case 70: /* special_args ::= TAG COMMA TAG */ +#line 646 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HAS2TAGS; + yygotominor.yy123.args[0] = yygotominor.yy123.args[1] = 0; + yygotominor.yy123.args[2] = 0; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1662 "xlat-parse.c" + break; + case 71: /* special_args ::= TAG COMMA TAG COMMA exp */ +#line 654 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HAS2TAGS; + yygotominor.yy123.args[0] = yygotominor.yy123.args[1] = 0; + yygotominor.yy123.args[2] = yymsp[0].minor.yy64; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1673 "xlat-parse.c" + break; + case 72: /* special_args ::= TAG COMMA TAG COMMA exp COMMA exp */ +#line 662 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HAS2TAGS; + yygotominor.yy123.args[0] = yygotominor.yy123.args[1] = 0; + yygotominor.yy123.args[2] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[3] = yymsp[0].minor.yy64; + yygotominor.yy123.args[4] = 0; +} +#line 1684 "xlat-parse.c" + break; + case 73: /* special_args ::= TAG COMMA TAG COMMA exp COMMA exp COMMA exp */ +#line 670 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HAS2TAGS; + yygotominor.yy123.args[0] = yygotominor.yy123.args[1] = 0; + yygotominor.yy123.args[2] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[3] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[4] = yymsp[0].minor.yy64; +} +#line 1695 "xlat-parse.c" + break; + case 74: /* special_args ::= LINEID */ +#line 678 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASLINEID; + memset (yygotominor.yy123.args, 0, 5); +} +#line 1703 "xlat-parse.c" + break; + case 75: /* special_args ::= LINEID COMMA exp */ +#line 683 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASLINEID; + yygotominor.yy123.args[0] = 0; + yygotominor.yy123.args[1] = yymsp[0].minor.yy64; + yygotominor.yy123.args[2] = 0; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1715 "xlat-parse.c" + break; + case 76: /* special_args ::= LINEID COMMA exp COMMA exp */ +#line 692 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASLINEID; + yygotominor.yy123.args[0] = 0; + yygotominor.yy123.args[1] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[2] = yymsp[0].minor.yy64; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1727 "xlat-parse.c" + break; + case 77: /* special_args ::= LINEID COMMA exp COMMA exp COMMA exp */ +#line 701 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASLINEID; + yygotominor.yy123.args[0] = 0; + yygotominor.yy123.args[1] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[2] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[3] = yymsp[0].minor.yy64; + yygotominor.yy123.args[4] = 0; +} +#line 1739 "xlat-parse.c" + break; + case 78: /* special_args ::= LINEID COMMA exp COMMA exp COMMA exp COMMA exp */ +#line 710 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASLINEID; + yygotominor.yy123.args[0] = 0; + yygotominor.yy123.args[1] = yymsp[-6].minor.yy64; + yygotominor.yy123.args[2] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[3] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[4] = yymsp[0].minor.yy64; +} +#line 1751 "xlat-parse.c" + break; + case 79: /* special_args ::= exp */ +#line 719 "xlat-parse.y" +{ + yygotominor.yy123.addflags = 0; + yygotominor.yy123.args[0] = yymsp[0].minor.yy64; + yygotominor.yy123.args[1] = 0; + yygotominor.yy123.args[2] = 0; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1763 "xlat-parse.c" + break; + case 80: /* special_args ::= exp COMMA exp */ +#line 728 "xlat-parse.y" +{ + yygotominor.yy123.addflags = 0; + yygotominor.yy123.args[0] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[1] = yymsp[0].minor.yy64; + yygotominor.yy123.args[2] = 0; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1775 "xlat-parse.c" + break; + case 81: /* special_args ::= exp COMMA exp COMMA exp */ +#line 737 "xlat-parse.y" +{ + yygotominor.yy123.addflags = 0; + yygotominor.yy123.args[0] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[1] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[2] = yymsp[0].minor.yy64; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1787 "xlat-parse.c" + break; + case 82: /* special_args ::= exp COMMA exp COMMA exp COMMA exp */ +#line 746 "xlat-parse.y" +{ + yygotominor.yy123.addflags = 0; + yygotominor.yy123.args[0] = yymsp[-6].minor.yy64; + yygotominor.yy123.args[1] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[2] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[3] = yymsp[0].minor.yy64; + yygotominor.yy123.args[4] = 0; +} +#line 1799 "xlat-parse.c" + break; + case 83: /* special_args ::= exp COMMA exp COMMA exp COMMA exp COMMA exp */ +#line 755 "xlat-parse.y" +{ + yygotominor.yy123.addflags = 0; + yygotominor.yy123.args[0] = yymsp[-8].minor.yy64; + yygotominor.yy123.args[1] = yymsp[-6].minor.yy64; + yygotominor.yy123.args[2] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[3] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[4] = yymsp[0].minor.yy64; +} +#line 1811 "xlat-parse.c" + break; + case 84: /* special_args ::= exp COMMA TAG */ +#line 764 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT2; + yygotominor.yy123.args[0] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[1] = 0; + yygotominor.yy123.args[2] = 0; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1823 "xlat-parse.c" + break; + case 85: /* special_args ::= exp COMMA TAG COMMA exp */ +#line 773 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT2; + yygotominor.yy123.args[0] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[1] = 0; + yygotominor.yy123.args[2] = yymsp[0].minor.yy64; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1835 "xlat-parse.c" + break; + case 86: /* special_args ::= exp COMMA TAG COMMA exp COMMA exp */ +#line 782 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT2; + yygotominor.yy123.args[0] = yymsp[-6].minor.yy64; + yygotominor.yy123.args[1] = 0; + yygotominor.yy123.args[2] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[3] = yymsp[0].minor.yy64; + yygotominor.yy123.args[4] = 0; +} +#line 1847 "xlat-parse.c" + break; + case 87: /* special_args ::= exp COMMA TAG COMMA exp COMMA exp COMMA exp */ +#line 791 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT2; + yygotominor.yy123.args[0] = yymsp[-8].minor.yy64; + yygotominor.yy123.args[1] = 0; + yygotominor.yy123.args[2] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[3] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[4] = yymsp[0].minor.yy64; +} +#line 1859 "xlat-parse.c" + break; + case 88: /* special_args ::= exp COMMA exp COMMA TAG */ +#line 800 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT3; + yygotominor.yy123.args[0] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[1] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[2] = 0; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1871 "xlat-parse.c" + break; + case 89: /* special_args ::= exp COMMA exp COMMA TAG COMMA exp */ +#line 809 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT3; + yygotominor.yy123.args[0] = yymsp[-6].minor.yy64; + yygotominor.yy123.args[1] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[2] = 0; + yygotominor.yy123.args[3] = yymsp[0].minor.yy64; + yygotominor.yy123.args[4] = 0; +} +#line 1883 "xlat-parse.c" + break; + case 90: /* special_args ::= exp COMMA exp COMMA TAG COMMA exp COMMA exp */ +#line 818 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT3; + yygotominor.yy123.args[0] = yymsp[-8].minor.yy64; + yygotominor.yy123.args[1] = yymsp[-6].minor.yy64; + yygotominor.yy123.args[2] = 0; + yygotominor.yy123.args[3] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[4] = yymsp[0].minor.yy64; +} +#line 1895 "xlat-parse.c" + break; + case 91: /* special_args ::= exp COMMA exp COMMA exp COMMA TAG */ +#line 827 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT4; + yygotominor.yy123.args[0] = yymsp[-6].minor.yy64; + yygotominor.yy123.args[1] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[2] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = 0; +} +#line 1907 "xlat-parse.c" + break; + case 92: /* special_args ::= exp COMMA exp COMMA exp COMMA TAG COMMA exp */ +#line 836 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT4; + yygotominor.yy123.args[0] = yymsp[-8].minor.yy64; + yygotominor.yy123.args[1] = yymsp[-6].minor.yy64; + yygotominor.yy123.args[2] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[3] = 0; + yygotominor.yy123.args[4] = yymsp[0].minor.yy64; +} +#line 1919 "xlat-parse.c" + break; + case 93: /* special_args ::= exp COMMA exp COMMA exp COMMA exp COMMA TAG */ +#line 845 "xlat-parse.y" +{ + yygotominor.yy123.addflags = SIMPLE_HASTAGAT5; + yygotominor.yy123.args[0] = yymsp[-8].minor.yy64; + yygotominor.yy123.args[1] = yymsp[-6].minor.yy64; + yygotominor.yy123.args[2] = yymsp[-4].minor.yy64; + yygotominor.yy123.args[3] = yymsp[-2].minor.yy64; + yygotominor.yy123.args[4] = 0; +} +#line 1931 "xlat-parse.c" + break; + }; + yygoto = yyRuleInfo[yyruleno].lhs; + yysize = yyRuleInfo[yyruleno].nrhs; + yypParser->yyidx -= yysize; + yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto); + if( yyact < YYNSTATE ){ +#ifdef NDEBUG + /* If we are not debugging and the reduce action popped at least + ** one element off the stack, then we can push the new element back + ** onto the stack here, and skip the stack overflow test in yy_shift(). + ** That gives a significant speed improvement. */ + if( yysize ){ + yypParser->yyidx++; + yymsp -= yysize-1; + yymsp->stateno = yyact; + yymsp->major = yygoto; + yymsp->minor = yygotominor; + }else +#endif + { + yy_shift(yypParser,yyact,yygoto,&yygotominor); + } + }else{ + assert( yyact == YYNSTATE + YYNRULE + 1 ); + yy_accept(yypParser); + } +} + +/* +** The following code executes when the parse fails +*/ +static void yy_parse_failed( + yyParser *yypParser /* The parser */ +){ + ParseARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser fails */ + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* +** The following code executes when a syntax error first occurs. +*/ +static void yy_syntax_error( + yyParser *yypParser, /* The parser */ + int yymajor, /* The major type of the error token */ + YYMINORTYPE yyminor /* The minor type of the error token */ +){ + ParseARG_FETCH; +#define TOKEN (yyminor.yy0) +#line 345 "xlat-parse.y" +yyerror("syntax error"); +#line 1991 "xlat-parse.c" + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* +** The following is executed when the parser accepts +*/ +static void yy_accept( + yyParser *yypParser /* The parser */ +){ + ParseARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser accepts */ + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* The main parser program. +** The first argument is a pointer to a structure obtained from +** "ParseAlloc" which describes the current state of the parser. +** The second argument is the major token number. The third is +** the minor token. The fourth optional argument is whatever the +** user wants (and specified in the grammar) and is available for +** use by the action routines. +** +** Inputs: +**
    +**
  • A pointer to the parser (an opaque structure.) +**
  • The major token number. +**
  • The minor token number. +**
  • An option argument of a grammar-specified type. +**
+** +** Outputs: +** None. +*/ +void Parse( + void *yyp, /* The parser */ + int yymajor, /* The major token code number */ + ParseTOKENTYPE yyminor /* The value for the token */ + ParseARG_PDECL /* Optional %extra_argument parameter */ +){ + YYMINORTYPE yyminorunion; + int yyact; /* The parser action. */ + int yyendofinput; /* True if we are at the end of input */ +#ifdef YYERRORSYMBOL + int yyerrorhit = 0; /* True if yymajor has invoked an error */ +#endif + yyParser *yypParser; /* The parser */ + + /* (re)initialize the parser, if necessary */ + yypParser = (yyParser*)yyp; + if( yypParser->yyidx<0 ){ +#if YYSTACKDEPTH<=0 + if( yypParser->yystksz <=0 ){ + memset(&yyminorunion, 0, sizeof(yyminorunion)); + yyStackOverflow(yypParser, &yyminorunion); + return; + } +#endif + yypParser->yyidx = 0; + yypParser->yyerrcnt = -1; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; + } + yyminorunion.yy0 = yyminor; + yyendofinput = (yymajor==0); + ParseARG_STORE; + +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); + } +#endif + + do{ + yyact = yy_find_shift_action(yypParser,yymajor); + if( yyactyyerrcnt--; + yymajor = YYNOCODE; + }else if( yyact < YYNSTATE + YYNRULE ){ + yy_reduce(yypParser,yyact-YYNSTATE); + }else{ +#ifdef YYERRORSYMBOL + int yymx; +#endif + assert( yyact == YY_ERROR_ACTION ); +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); + } +#endif +#ifdef YYERRORSYMBOL + /* A syntax error has occurred. + ** The response to an error depends upon whether or not the + ** grammar defines an error token "ERROR". + ** + ** This is what we do if the grammar does define ERROR: + ** + ** * Call the %syntax_error function. + ** + ** * Begin popping the stack until we enter a state where + ** it is legal to shift the error symbol, then shift + ** the error symbol. + ** + ** * Set the error count to three. + ** + ** * Begin accepting and shifting new tokens. No new error + ** processing will occur until three tokens have been + ** shifted successfully. + ** + */ + if( yypParser->yyerrcnt<0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yymx = yypParser->yystack[yypParser->yyidx].major; + if( yymx==YYERRORSYMBOL || yyerrorhit ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sDiscard input token %s\n", + yyTracePrompt,yyTokenName[yymajor]); + } +#endif + yy_destructor(yymajor,&yyminorunion); + yymajor = YYNOCODE; + }else{ + while( + yypParser->yyidx >= 0 && + yymx != YYERRORSYMBOL && + (yyact = yy_find_reduce_action( + yypParser->yystack[yypParser->yyidx].stateno, + YYERRORSYMBOL)) >= YYNSTATE + ){ + yy_pop_parser_stack(yypParser); + } + if( yypParser->yyidx < 0 || yymajor==0 ){ + yy_destructor(yymajor,&yyminorunion); + yy_parse_failed(yypParser); + yymajor = YYNOCODE; + }else if( yymx!=YYERRORSYMBOL ){ + YYMINORTYPE u2; + u2.YYERRSYMDT = 0; + yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); + } + } + yypParser->yyerrcnt = 3; + yyerrorhit = 1; +#else /* YYERRORSYMBOL is not defined */ + /* This is what we do if the grammar does not define ERROR: + ** + ** * Report an error message, and throw away the input token. + ** + ** * If the input token is $, then fail the parse. + ** + ** As before, subsequent error messages are suppressed until + ** three input tokens have been successfully shifted. + */ + if( yypParser->yyerrcnt<=0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yypParser->yyerrcnt = 3; + yy_destructor(yymajor,&yyminorunion); + if( yyendofinput ){ + yy_parse_failed(yypParser); + } + yymajor = YYNOCODE; +#endif + } + }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); + return; +} diff --git a/tools/xlatcc/xlat-parse.h b/tools/xlatcc/xlat-parse.h index fae813aa32..5d0e3605a5 100644 --- a/tools/xlatcc/xlat-parse.h +++ b/tools/xlatcc/xlat-parse.h @@ -10,27 +10,28 @@ #define SYMNUM 10 #define LPAREN 11 #define RPAREN 12 -#define PRINT 13 -#define COMMA 14 -#define STRING 15 -#define ENDL 16 -#define DEFINE 17 -#define SYM 18 -#define INCLUDE 19 -#define RBRACE 20 -#define ENUM 21 -#define LBRACE 22 -#define EQUALS 23 -#define SPECIAL 24 -#define SEMICOLON 25 -#define COLON 26 -#define LBRACKET 27 -#define RBRACKET 28 -#define FLAGS 29 -#define ARG2 30 -#define ARG3 31 -#define ARG4 32 -#define ARG5 33 -#define OR_EQUAL 34 -#define TAG 35 -#define LINEID 36 +#define NOP 13 +#define PRINT 14 +#define COMMA 15 +#define STRING 16 +#define ENDL 17 +#define DEFINE 18 +#define SYM 19 +#define INCLUDE 20 +#define RBRACE 21 +#define ENUM 22 +#define LBRACE 23 +#define EQUALS 24 +#define SPECIAL 25 +#define SEMICOLON 26 +#define COLON 27 +#define LBRACKET 28 +#define RBRACKET 29 +#define FLAGS 30 +#define ARG2 31 +#define ARG3 32 +#define ARG4 33 +#define ARG5 34 +#define OR_EQUAL 35 +#define TAG 36 +#define LINEID 37 diff --git a/tools/xlatcc/xlat-parse.y b/tools/xlatcc/xlat-parse.y index 203f3ee78c..7cd43b9344 100644 --- a/tools/xlatcc/xlat-parse.y +++ b/tools/xlatcc/xlat-parse.y @@ -243,10 +243,33 @@ void yyparse (void) void *pParser = ParseAlloc (malloc); YYSTYPE token; int tokentype; + int include_state = 0; while ((tokentype = yylex(&token)) != 0) { + /* Whenever the sequence INCLUDE STRING is encountered in the token + * stream, feed a dummy NOP token to the parser so that it will + * reduce the include_statement before grabbing any more tokens + * from the current file. + */ + if (tokentype == INCLUDE && include_state == 0) + { + include_state = 1; + } + else if (tokentype == STRING && include_state == 1) + { + include_state = 2; + } + else + { + include_state = 0; + } Parse (pParser, tokentype, token); + if (include_state == 2) + { + include_state = 0; + Parse (pParser, NOP, token); + } } memset (&token, 0, sizeof(token)); Parse (pParser, 0, token); @@ -354,7 +377,7 @@ exp(A) ::= MINUS exp(B). [NEG] { A = -B; } exp(A) ::= LPAREN exp(B) RPAREN. { A = B; } translation_unit ::= . /* empty */ -translation_unit ::= external_declaration. +translation_unit ::= translation_unit external_declaration. external_declaration ::= define_statement. external_declaration ::= include_statement. @@ -363,6 +386,7 @@ external_declaration ::= enum_statement. external_declaration ::= linetype_declaration. external_declaration ::= boom_declaration. external_declaration ::= special_declaration. +external_declaration ::= NOP. print_statement ::= PRINT LPAREN print_list RPAREN. { diff --git a/wadsrc/dehsupp.lmp b/wadsrc/dehsupp.lmp index 905bbaa43a..97bf44534e 100644 Binary files a/wadsrc/dehsupp.lmp and b/wadsrc/dehsupp.lmp differ diff --git a/wadsrc/doomx.lmp b/wadsrc/doomx.lmp deleted file mode 100644 index 551954c41c..0000000000 Binary files a/wadsrc/doomx.lmp and /dev/null differ diff --git a/wadsrc/foo b/wadsrc/foo deleted file mode 100644 index 00ae07c0c2..0000000000 Binary files a/wadsrc/foo and /dev/null differ diff --git a/wadsrc/hereticx.lmp b/wadsrc/hereticx.lmp deleted file mode 100644 index ebcd8869ad..0000000000 Binary files a/wadsrc/hereticx.lmp and /dev/null differ diff --git a/wadsrc/strifex.lmp b/wadsrc/strifex.lmp deleted file mode 100644 index 8b674a90ed..0000000000 Binary files a/wadsrc/strifex.lmp and /dev/null differ diff --git a/zdoom.vcproj b/zdoom.vcproj index 6bb55164e6..b755abc5f3 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -3696,7 +3696,7 @@ @@ -3716,7 +3716,7 @@