%token_prefix ZCC_ %token_type { ZCCToken } %token_destructor {} // just to avoid a compiler warning %name ZCCParse %extra_argument { FScanner *sc } %syntax_error { FString unexpected, expecting; int i; int stateno = yypParser->yystack[yypParser->yyidx].stateno; unexpected << "Unexpected " << ZCCTokenName(yymajor); // Determine all the terminals that the parser would have accepted at this point // (see yy_find_shift_action). This list can get quite long. Is it worthwhile to // print it when not debugging the grammar, or would that be too confusing to // the average user? if (stateno < YY_SHIFT_MAX && (i = yy_shift_ofst[stateno])!=YY_SHIFT_USE_DFLT) { for (int j = 1; j < YYERRORSYMBOL; ++j) { int k = i + j; if (k >= 0 && k < YY_SZ_ACTTAB && yy_lookahead[k] == j) { expecting << (expecting.IsEmpty() ? "Expecting " : " or ") << ZCCTokenName(j); } } } sc->ScriptMessage("%s\n%s\n", unexpected.GetChars(), expecting.GetChars()); } %parse_accept { sc->ScriptMessage("input accepted\n"); } %parse_failure { /**failed = true;*/ } %nonassoc EQ MULEQ DIVEQ MODEQ ADDEQ SUBEQ LSHEQ RSHEQ ANDEQ OREQ XOREQ. %right QUESTION COLON. %left OROR. %left ANDAND. %left EQEQ NEQ APPROXEQ. %left LT GT LTEQ GTEQ LTGTEQ IS. %left DOTDOT. %left OR. /* Note that this is like the Ruby precedence for these */ %left XOR. /* three operators and not the C precedence, since */ %left AND. /* they are higher priority than the comparisons. */ %left LSH RSH. %left SUB ADD. %left MUL DIV MOD CROSSPROD DOTPROD. %left POW. %right UNARY ADDADD SUBSUB. %left DOT LPAREN LBRACKET. %left SCOPE. main ::= translation_unit. { sc->ScriptMessage("Parse complete\n"); } translation_unit ::= . translation_unit ::= translation_unit external_declaration. translation_unit ::= translation_unit EOF. translation_unit ::= error. external_declaration ::= class_definition. /* Optional bits. */ opt_semicolon ::= . opt_semicolon ::= SEMICOLON. opt_comma ::= . opt_comma ::= COMMA. opt_expr ::= . opt_expr ::= expr. /* A class definition. Can only occur at global scope. */ class_definition ::= CLASS id_or_string class_ancestry class_flags class_body. id_or_string ::= IDENTIFIER. id_or_string ::= string_constant. class_ancestry ::= . class_ancestry ::= COLON id_or_string. class_flags ::= . class_flags ::= class_flags ABSTRACT. class_flags ::= class_flags NATIVE. class_flags ::= class_flags REPLACES id_or_string. class_body ::= SEMICOLON class_innards EOF. class_body ::= LBRACE class_innards RBRACE. class_innards ::= . class_innards ::= class_innards class_member. /* Classes can define variables, functions, enums, structs, states, constants, and defaults. */ class_member ::= declarator. class_member ::= enum_def. class_member ::= struct_def. class_member ::= states_def. class_member ::= default_def. class_member ::= const_def. /* Structs can define variables, enums, and structs. */ struct_def ::= STRUCT IDENTIFIER LBRACE struct_body RBRACE opt_semicolon. struct_member ::= declarator_no_fun. struct_member ::= enum_def. /* Enumerators are lists of named integers. */ enum_def ::= ENUM IDENTIFIER enum_type LBRACE enum_list opt_comma RBRACE opt_semicolon. enum_type ::= . enum_type ::= COLON int_type. enum_list ::= enumerator. enum_list ::= enum_list COMMA enumerator. enumerator ::= IDENTIFIER. enumerator ::= IDENTIFIER EQ expr. /* Expression must be constant. */ /* States */ states_def ::= STATES scanner_mode LBRACE states_body RBRACE. /* We use a special scanner mode to allow for sprite names and frame characters * to not be quoted even if they contain special characters. The scanner_mode * nonterminal is used to enter this mode. The scanner automatically leaves it * upon pre-defined conditions. See the comments by FScanner::SetStateMode(). * * Note that rules are reduced *after* one token of lookahead has been * consumed, so this nonterminal must be placed one token before we want it to * take effect. For example, in states_def above, the scanner mode will be * set immediately after LBRACE is consumed, rather than immediately after * STATES is consumed. */ scanner_mode ::= . { sc->SetStateMode(true); } states_body ::= . states_body ::= error. states_body ::= states_body LABELID. states_body ::= states_body state_line. states_body ::= states_body state_label. states_body ::= states_body state_flow. state_label ::= NWS COLON. state_flow ::= state_flow_type scanner_mode SEMICOLON. state_flow_type ::= STOP. state_flow_type ::= WAIT. state_flow_type ::= FAIL. state_flow_type ::= LOOP. state_flow_type ::= GOTO dotted_identifier state_goto_offset. state_goto_offset ::= . state_goto_offset ::= PLUS expr. /* Must evaluate to an integer constant. */ state_line ::= NWS NWS expr state_opts state_action. state_opts ::= . state_opts ::= state_opts BRIGHT. state_opts ::= state_opts OFFSET LPAREN expr COMMA expr RPAREN. state_opts ::= state_opts LIGHT LPAREN light_list RPAREN. light_list ::= STRCONST. light_list ::= light_list COMMA STRCONST. /* A state action can be either a compound statement or a single action function call. */ state_action ::= LBRACE statement_list scanner_mode RBRACE. state_action ::= LBRACE error scanner_mode RBRACE. state_action ::= state_call scanner_mode SEMICOLON. state_call ::= . state_call ::= IDENTIFIER state_call_parms. state_call_parms ::= . state_call_parms ::= LPAREN opt_expr_list RPAREN. state_call_parms ::= LPAREN error RPAREN. dotted_identifier ::= IDENTIFIER. dotted_identifier ::= dotted_identifier DOT IDENTIFIER. /* Definition of a default class instance. */ default_def ::= DEFAULT compound_statement. /* Type names */ int_type ::= SBYTE. int_type ::= BYTE. int_type ::= SHORT. int_type ::= USHORT. int_type ::= INT. int_type ::= UINT. type_name ::= BOOL. type_name ::= int_type. type_name ::= FLOAT. type_name ::= DOUBLE. type_name ::= STRING. type_name ::= VECTOR vector_size. type_name ::= NAME. type_name ::= IDENTIFIER. /* User-defined type (struct, enum, or class) */ vector_size ::= . vector_size ::= LT INTCONST GT. /* Type names can also be used as identifiers in contexts where type names * are not normally allowed. */ %fallback IDENTIFIER SBYTE BYTE SHORT USHORT INT UINT BOOL FLOAT DOUBLE STRING VECTOR NAME. /* Aggregate types */ aggregate_type ::= MAP LT type array_size COMMA type array_size GT. /* Hash table */ aggregate_type ::= ARRAY LT type array_size GT. /* TArray */ aggregate_type ::= CLASS class_restrictor. /* class */ class_restrictor ::= . class_restrictor ::= LT IDENTIFIER GT. type ::= type_name. type ::= aggregate_type. type_list ::= type array_size. /* A comma-separated list of types */ type_list ::= type_list COMMA type array_size. type_list_or_void ::= VOID. type_list_or_void ::= type_list. array_size ::= . array_size ::= array_size LBRACKET opt_expr RBRACKET. declarator ::= decl_flags type_list_or_void variables_or_function. /* Multiple type names are only valid for functions. */ declarator_no_fun ::= decl_flags type variable_list. variables_or_function ::= IDENTIFIER LPAREN func_params RPAREN func_const opt_func_body. /* Function */ variables_or_function ::= variable_list SEMICOLON. variables_or_function ::= error SEMICOLON. variable_list ::= IDENTIFIER array_size. variable_list ::= variable_list COMMA IDENTIFIER array_size. decl_flags ::= . decl_flags ::= decl_flags NATIVE. decl_flags ::= decl_flags STATIC. decl_flags ::= decl_flags PRIVATE. decl_flags ::= decl_flags PROTECTED. decl_flags ::= decl_flags LATENT. decl_flags ::= decl_flags FINAL. decl_flags ::= decl_flags META. decl_flags ::= decl_flags ACTION. decl_flags ::= decl_flags DEPRECATED LPAREN string_constant RPAREN. func_const ::= . func_const ::= CONST. opt_func_body ::= SEMICOLON. opt_func_body ::= function_body. func_params ::= . /* empty */ func_params ::= VOID. func_params ::= func_param_list. func_param_list ::= func_param. func_param_list ::= func_param COMMA func_param_list. func_param ::= func_param_flags type IDENTIFIER array_size. func_param_flags ::= . func_param_flags ::= func_param_flags IN. func_param_flags ::= func_param_flags OUT. func_param_flags ::= func_param_flags OPTIONAL. struct_body ::= struct_member. struct_body ::= struct_member struct_body. /* Like UnrealScript, a constant's type is implied by its value's type. */ const_def ::= CONST IDENTIFIER EQ expr SEMICOLON. /* Expressions */ /* We use default to access a class's default instance. */ %fallback IDENTIFIER DEFAULT. primary ::= IDENTIFIER. primary ::= SUPER. primary ::= constant. primary ::= SELF. primary ::= LPAREN expr RPAREN. primary ::= LPAREN error RPAREN. primary ::= primary LPAREN func_expr_list RPAREN. [DOT] // Function call primary ::= primary LBRACKET expr RBRACKET. [DOT] // Array access primary ::= primary DOT IDENTIFIER. // Member access primary ::= primary ADDADD. /* postfix++ */ primary ::= primary SUBSUB. /* postfix-- */ primary ::= SCOPE primary. unary_expr ::= primary. unary_expr ::= SUB unary_expr. [UNARY] unary_expr ::= ADD unary_expr. [UNARY] unary_expr ::= SUBSUB unary_expr. [UNARY] unary_expr ::= ADDADD unary_expr. [UNARY] unary_expr ::= TILDE unary_expr. [UNARY] unary_expr ::= BANG unary_expr. [UNARY] unary_expr ::= SIZEOF unary_expr. [UNARY] unary_expr ::= ALIGNOF unary_expr. [UNARY] /* Due to parsing conflicts, C-style casting is not supported. You * must use C++ function call-style casting instead. */ expr ::= unary_expr. expr ::= expr ADD expr. /* a + b */ expr ::= expr SUB expr. /* a - b */ expr ::= expr MUL expr. /* a * b */ expr ::= expr DIV expr. /* a / b */ expr ::= expr MOD expr. /* a % b */ expr ::= expr POW expr. /* a ** b */ expr ::= expr CROSSPROD expr. /* a cross b */ expr ::= expr DOTPROD expr. /* a dot b */ expr ::= expr LSH expr. /* a << b */ expr ::= expr RSH expr. /* a >> b */ expr ::= expr DOTDOT expr. /* a .. b */ expr ::= expr LT expr. /* a < b */ expr ::= expr GT expr. /* a > b */ expr ::= expr LTEQ expr. /* a <= b */ expr ::= expr GTEQ expr. /* a >= b */ expr ::= expr LTGTEQ expr. /* a <>= b */ expr ::= expr IS expr. /* a is b */ expr ::= expr EQEQ expr. /* a == b */ expr ::= expr NEQ expr. /* a != b */ expr ::= expr APPROXEQ expr. /* a ~== b */ expr ::= expr AND expr. /* a & b */ expr ::= expr XOR expr. /* a ^ b */ expr ::= expr OR expr. /* a | b */ expr ::= expr ANDAND expr. /* a && b */ expr ::= expr OROR expr. /* a || b */ expr ::= expr SCOPE expr. expr ::= expr QUESTION expr COLON expr. opt_expr_list ::= . opt_expr_list ::= expr_list. expr_list ::= expr. expr_list ::= expr_list COMMA expr. /* A function expression list can also specify a parameter's name, * but once you do that, all remaining parameters must also be named. */ func_expr_list ::= . func_expr_list ::= expr_list. func_expr_list ::= expr_list COMMA named_expr_list. func_expr_list ::= named_expr_list. named_expr_list ::= named_expr. named_expr_list ::= named_expr_list COMMA named_expr. named_expr ::= IDENTIFIER COLON expr. /* Allow C-like concatenation of adjacent string constants. */ string_constant ::= STRCONST. string_constant ::= string_constant STRCONST. constant ::= string_constant. constant ::= INTCONST. constant ::= FLOATCONST. function_body ::= compound_statement. statement ::= labeled_statement. statement ::= compound_statement. statement ::= expression_statement. statement ::= selection_statement. statement ::= iteration_statement. statement ::= jump_statement. statement ::= assign_statement. statement ::= local_var. statement ::= error SEMICOLON. jump_statement ::= CONTINUE SEMICOLON. jump_statement ::= BREAK SEMICOLON. jump_statement ::= RETURN SEMICOLON. jump_statement ::= RETURN expr_list SEMICOLON. compound_statement ::= LBRACE RBRACE. compound_statement ::= LBRACE statement_list RBRACE. compound_statement ::= LBRACE error RBRACE. statement_list ::= statement. statement_list ::= statement_list statement. expression_statement ::= SEMICOLON. expression_statement ::= expr SEMICOLON. iteration_statement ::= while_or_until LPAREN expr RPAREN statement. iteration_statement ::= DO statement while_or_until LPAREN expr RPAREN. iteration_statement ::= FOR LPAREN for_init_expr SEMICOLON opt_expr SEMICOLON for_bump_expr RPAREN statement. while_or_until ::= WHILE. while_or_until ::= UNTIL. for_init_expr ::= . for_init_expr ::= expr. for_init_expr ::= type variable_list EQ expr_list. for_init_expr ::= assign_expr. for_bump_expr ::= . for_bump_expr ::= expr. for_bump_expr ::= assign_expr. /* Resolve the shift-reduce conflict here in favor of the shift. * This is the default behavior, but using precedence symbols * lets us do it without warnings. */ %left IF. %left ELSE. selection_statement ::= if_front. [IF] selection_statement ::= if_front ELSE statement. [ELSE] selection_statement ::= SWITCH LPAREN expr RPAREN statement. if_front ::= IF LPAREN expr RPAREN statement. labeled_statement ::= CASE expr COLON. labeled_statement ::= DEFAULT COLON. assign_statement ::= assign_expr SEMICOLON. [EQ] assign_expr ::= expr_list assign_op expr_list. assign_op ::= EQ. assign_op ::= MULEQ. assign_op ::= DIVEQ. assign_op ::= MODEQ. assign_op ::= ADDEQ. assign_op ::= SUBEQ. assign_op ::= LSHEQ. assign_op ::= RSHEQ. assign_op ::= ANDEQ. assign_op ::= OREQ. assign_op ::= XOREQ. local_var ::= type variable_list var_init SEMICOLON. var_init ::= . var_init ::= EQ expr_list.