mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-15 06:51:36 +00:00
444 lines
14 KiB
Text
444 lines
14 KiB
Text
|
%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<type> */
|
||
|
aggregate_type ::= CLASS class_restrictor. /* class<type> */
|
||
|
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.
|