cppparser: Parse nonstandard specifier order like "const static"

This commit is contained in:
rdb 2016-08-09 01:19:35 +02:00
parent 339eb58007
commit db97747981
5 changed files with 3703 additions and 4242 deletions

View File

@ -27,6 +27,7 @@ This issue fixes several bugs that were still found in 1.9.2.
* Support uint8 index buffers in DX9
* Fix occasional frame lag when loading a big model asynchronously
* Fix race condition reading string config var
* Fix interrogate parsing issue with "const static"
------------------------ RELEASE 1.9.2 ------------------------

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 2.7. */
/* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -32,7 +32,7 @@
#ifndef YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
# define YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED
/* Enabling traces. */
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
@ -40,117 +40,116 @@
extern int cppyydebug;
#endif
/* Tokens. */
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
REAL = 258,
INTEGER = 259,
CHAR_TOK = 260,
STRING = 261,
SIMPLE_IDENTIFIER = 262,
IDENTIFIER = 263,
TYPENAME_IDENTIFIER = 264,
SCOPING = 265,
TYPEDEFNAME = 266,
ELLIPSIS = 267,
OROR = 268,
ANDAND = 269,
EQCOMPARE = 270,
NECOMPARE = 271,
LECOMPARE = 272,
GECOMPARE = 273,
LSHIFT = 274,
RSHIFT = 275,
POINTSAT_STAR = 276,
DOT_STAR = 277,
UNARY = 278,
UNARY_NOT = 279,
UNARY_NEGATE = 280,
UNARY_MINUS = 281,
UNARY_STAR = 282,
UNARY_REF = 283,
POINTSAT = 284,
SCOPE = 285,
PLUSPLUS = 286,
MINUSMINUS = 287,
TIMESEQUAL = 288,
DIVIDEEQUAL = 289,
MODEQUAL = 290,
PLUSEQUAL = 291,
MINUSEQUAL = 292,
OREQUAL = 293,
ANDEQUAL = 294,
XOREQUAL = 295,
LSHIFTEQUAL = 296,
RSHIFTEQUAL = 297,
KW_BEGIN_PUBLISH = 298,
KW_BLOCKING = 299,
KW_BOOL = 300,
KW_CATCH = 301,
KW_CHAR = 302,
KW_CHAR16_T = 303,
KW_CHAR32_T = 304,
KW_CLASS = 305,
KW_CONST = 306,
KW_DELETE = 307,
KW_DOUBLE = 308,
KW_DYNAMIC_CAST = 309,
KW_ELSE = 310,
KW_END_PUBLISH = 311,
KW_ENUM = 312,
KW_EXTENSION = 313,
KW_EXTERN = 314,
KW_EXPLICIT = 315,
KW_PUBLISHED = 316,
KW_FALSE = 317,
KW_FLOAT = 318,
KW_FRIEND = 319,
KW_FOR = 320,
KW_GOTO = 321,
KW_IF = 322,
KW_INLINE = 323,
KW_INT = 324,
KW_LONG = 325,
KW_LONGLONG = 326,
KW_MAKE_PROPERTY = 327,
KW_MAKE_SEQ = 328,
KW_MUTABLE = 329,
KW_NAMESPACE = 330,
KW_NEW = 331,
KW_NOEXCEPT = 332,
KW_OPERATOR = 333,
KW_PRIVATE = 334,
KW_PROTECTED = 335,
KW_PUBLIC = 336,
KW_REGISTER = 337,
KW_RETURN = 338,
KW_SHORT = 339,
KW_SIGNED = 340,
KW_SIZEOF = 341,
KW_STATIC = 342,
KW_STATIC_CAST = 343,
KW_STRUCT = 344,
KW_TEMPLATE = 345,
KW_THROW = 346,
KW_TRUE = 347,
KW_TRY = 348,
KW_TYPEDEF = 349,
KW_TYPENAME = 350,
KW_UNION = 351,
KW_UNSIGNED = 352,
KW_USING = 353,
KW_VIRTUAL = 354,
KW_VOID = 355,
KW_VOLATILE = 356,
KW_WCHAR_T = 357,
KW_WHILE = 358,
START_CPP = 359,
START_CONST_EXPR = 360,
START_TYPE = 361
};
enum yytokentype
{
REAL = 258,
INTEGER = 259,
CHAR_TOK = 260,
STRING = 261,
SIMPLE_IDENTIFIER = 262,
IDENTIFIER = 263,
TYPENAME_IDENTIFIER = 264,
SCOPING = 265,
TYPEDEFNAME = 266,
ELLIPSIS = 267,
OROR = 268,
ANDAND = 269,
EQCOMPARE = 270,
NECOMPARE = 271,
LECOMPARE = 272,
GECOMPARE = 273,
LSHIFT = 274,
RSHIFT = 275,
POINTSAT_STAR = 276,
DOT_STAR = 277,
UNARY = 278,
UNARY_NOT = 279,
UNARY_NEGATE = 280,
UNARY_MINUS = 281,
UNARY_STAR = 282,
UNARY_REF = 283,
POINTSAT = 284,
SCOPE = 285,
PLUSPLUS = 286,
MINUSMINUS = 287,
TIMESEQUAL = 288,
DIVIDEEQUAL = 289,
MODEQUAL = 290,
PLUSEQUAL = 291,
MINUSEQUAL = 292,
OREQUAL = 293,
ANDEQUAL = 294,
XOREQUAL = 295,
LSHIFTEQUAL = 296,
RSHIFTEQUAL = 297,
KW_BEGIN_PUBLISH = 298,
KW_BLOCKING = 299,
KW_BOOL = 300,
KW_CATCH = 301,
KW_CHAR = 302,
KW_CHAR16_T = 303,
KW_CHAR32_T = 304,
KW_CLASS = 305,
KW_CONST = 306,
KW_DELETE = 307,
KW_DOUBLE = 308,
KW_DYNAMIC_CAST = 309,
KW_ELSE = 310,
KW_END_PUBLISH = 311,
KW_ENUM = 312,
KW_EXTENSION = 313,
KW_EXTERN = 314,
KW_EXPLICIT = 315,
KW_PUBLISHED = 316,
KW_FALSE = 317,
KW_FLOAT = 318,
KW_FRIEND = 319,
KW_FOR = 320,
KW_GOTO = 321,
KW_IF = 322,
KW_INLINE = 323,
KW_INT = 324,
KW_LONG = 325,
KW_LONGLONG = 326,
KW_MAKE_PROPERTY = 327,
KW_MAKE_SEQ = 328,
KW_MUTABLE = 329,
KW_NAMESPACE = 330,
KW_NEW = 331,
KW_NOEXCEPT = 332,
KW_OPERATOR = 333,
KW_PRIVATE = 334,
KW_PROTECTED = 335,
KW_PUBLIC = 336,
KW_REGISTER = 337,
KW_RETURN = 338,
KW_SHORT = 339,
KW_SIGNED = 340,
KW_SIZEOF = 341,
KW_STATIC = 342,
KW_STATIC_CAST = 343,
KW_STRUCT = 344,
KW_TEMPLATE = 345,
KW_THROW = 346,
KW_TRUE = 347,
KW_TRY = 348,
KW_TYPEDEF = 349,
KW_TYPENAME = 350,
KW_UNION = 351,
KW_UNSIGNED = 352,
KW_USING = 353,
KW_VIRTUAL = 354,
KW_VOID = 355,
KW_VOLATILE = 356,
KW_WCHAR_T = 357,
KW_WHILE = 358,
START_CPP = 359,
START_CONST_EXPR = 360,
START_TYPE = 361
};
#endif
/* Tokens. */
#define REAL 258
@ -258,40 +257,24 @@ extern int cppyydebug;
#define START_CONST_EXPR 360
#define START_TYPE 361
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
/* Location type. */
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE
typedef struct YYLTYPE YYLTYPE;
struct YYLTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
} YYLTYPE;
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
};
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1
#endif
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int cppyyparse (void *YYPARSE_PARAM);
#else
int cppyyparse ();
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
int cppyyparse (void);
#else
int cppyyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_CPPYY_BUILT_TMP_CPPBISON_YXX_H_INCLUDED */

View File

@ -537,6 +537,11 @@ storage_class:
empty
{
$$ = 0;
}
| storage_class KW_CONST
{
// This isn't really a storage class, but it helps with parsing.
$$ = $1 | (int)CPPInstance::SC_const;
}
| storage_class KW_EXTERN
{
@ -592,9 +597,20 @@ storage_class:
;
type_like_declaration:
multiple_var_declaration
storage_class type_decl
{
/* multiple_var_declaration adds itself to the scope. */
// We don't need to push/pop type, because we can't nest
// multiple_var_declarations.
if ($2->as_type_declaration()) {
current_type = $2->as_type_declaration()->_type;
} else {
current_type = $2->as_type();
}
push_storage_class($1);
}
multiple_instance_identifiers
{
pop_storage_class();
}
| storage_class type_decl ';'
{
@ -613,36 +629,6 @@ type_like_declaration:
$2->set_initializer($3);
}
}
;
multiple_var_declaration:
storage_class type_decl
{
// We don't need to push/pop type, because we can't nest
// multiple_var_declarations.
if ($2->as_type_declaration()) {
current_type = $2->as_type_declaration()->_type;
} else {
current_type = $2->as_type();
}
push_storage_class($1);
}
multiple_instance_identifiers
{
pop_storage_class();
}
| storage_class KW_CONST type
{
// We don't need to push/pop type, because we can't nest
// multiple_var_declarations.
current_type = $3;
push_storage_class($1);
}
multiple_const_instance_identifiers
{
pop_storage_class();
}
/* We don't need to include a rule for variables that point to
functions, because we get those from the function_prototype
definition. */
@ -651,6 +637,9 @@ multiple_var_declaration:
multiple_instance_identifiers:
instance_identifier maybe_initialize_or_function_body
{
if (current_storage_class & CPPInstance::SC_const) {
$1->add_modifier(IIT_const);
}
CPPInstance *inst = new CPPInstance(current_type, $1,
current_storage_class,
@1.file);
@ -659,6 +648,9 @@ multiple_instance_identifiers:
}
| instance_identifier maybe_initialize ',' multiple_instance_identifiers
{
if (current_storage_class & CPPInstance::SC_const) {
$1->add_modifier(IIT_const);
}
CPPInstance *inst = new CPPInstance(current_type, $1,
current_storage_class,
@1.file);
@ -667,28 +659,6 @@ multiple_instance_identifiers:
}
;
multiple_const_instance_identifiers:
instance_identifier maybe_initialize_or_function_body
{
$1->add_modifier(IIT_const);
CPPInstance *inst = new CPPInstance(current_type, $1,
current_storage_class,
@1.file);
inst->set_initializer($2);
current_scope->add_declaration(inst, global_scope, current_lexer, @1);
}
| instance_identifier maybe_initialize ',' multiple_const_instance_identifiers
{
$1->add_modifier(IIT_const);
CPPInstance *inst = new CPPInstance(current_type, $1,
current_storage_class,
@1.file);
inst->set_initializer($2);
current_scope->add_declaration(inst, global_scope, current_lexer, @1);
}
;
typedef_declaration:
storage_class type_decl
{
@ -704,17 +674,6 @@ typedef_declaration:
typedef_instance_identifiers
{
pop_storage_class();
}
| storage_class KW_CONST type
{
// We don't need to push/pop type, because we can't nest
// multiple_var_declarations.
current_type = $3;
push_storage_class($1);
}
typedef_const_instance_identifiers
{
pop_storage_class();
}
| storage_class function_prototype maybe_initialize_or_function_body
{
@ -733,29 +692,18 @@ typedef_declaration:
typedef_instance_identifiers:
instance_identifier maybe_initialize_or_function_body
{
if (current_storage_class & CPPInstance::SC_const) {
$1->add_modifier(IIT_const);
}
CPPType *target_type = current_type;
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);
}
| instance_identifier maybe_initialize ',' typedef_instance_identifiers
{
CPPType *target_type = current_type;
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);
}
;
typedef_const_instance_identifiers:
instance_identifier maybe_initialize_or_function_body
{
$1->add_modifier(IIT_const);
CPPType *target_type = current_type;
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);
}
| instance_identifier maybe_initialize ',' typedef_const_instance_identifiers
{
$1->add_modifier(IIT_const);
if (current_storage_class & CPPInstance::SC_const) {
$1->add_modifier(IIT_const);
}
CPPType *target_type = current_type;
CPPTypedefType *typedef_type = new CPPTypedefType(target_type, $1, current_scope, @1.file);
current_scope->add_declaration(typedef_type, global_scope, current_lexer, @1);

View File

@ -60,6 +60,10 @@ public:
// And this is for methods tagged with __extension, which declares
// extension methods defined separately from the source code.
SC_extension = 0x1000,
// This isn't really a storage class. It's only used temporarily by the
// parser, to make parsing specifier sequences a bit easier.
SC_const = 0x20000,
};
CPPInstance(CPPType *type, const string &name, int storage_class = 0);