-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
I'm curious about this tool, I used in the past "Lzz, The Lazy C++ Compiler (https://github.com/mjspncr/lzz3)" and just found your project indirectly through https://github.com/AthrunArthur/cxxparser .
Are you still activelly using it ?
I've done a experimental tool to convert bison grammars to a kind of EBNF understood by https://www.bottlecaps.de/rr/ui to generate railroad diagrams see bellow the converted src/Fog/FogParser.y and with some hand made changes to allow view it at https://www.bottlecaps.de/rr/ui the order of the rules could be changed to a better view of the railroad diagrams. Copy and paste the EBNF bellow on https://www.bottlecaps.de/rr/ui tab Edit Grammar then switch to the tab View Diagram.
/*
* The // %prec resolves a conflict in identifier_word : which is forced to be a shift of a label for
* a labeled-statement rather than a reduction for the name of a bit-field or generalised constructor.
* This is pretty dubious syntactically but correct for all semantic possibilities.
* The shift is only activated when the ambiguity exists at the start of a statement. In this context
* a bit-field declaration or constructor definition are not allowed.
/*/
identifier_word::= Identifier
| MetaType
| DERIVED | FILE | GUARD | IMPLEMENTATION
| INCLUDE | INTERFACE | NOGUARD | NOIMPLEMENTATION
| OVERLOAD | PATH | PREFIX | PURE | SUFFIX
| ALL | PLACEHOLDER | PLACEMENT | NOAUTO
| segment
| utility
identifier::= identifier_word // %prec SHIFT_THERE
| TreeLiteral
/*
* The // %prec resolves the $014.2-3 ambiguity:
* Identifier '<' is forced to go through the is-it-a-template-name test
* All names absorb TEMPLATE with the name, so that no template_test is performed for them.
* This requires all potential declarations within an expression to perpetuate this policy
* and thereby guarantee the ultimate coverage of explicit_instantiation.
/*/
id::= identifier // %prec SHIFT_THERE /* Force < through test /*/
| identifier template_test '+' template_argument_list '>'
| identifier template_test '+' '>'
| identifier template_test '-' /* requeued < follows /*/
| template_id
template_test::= '<' /* Queue '+' or '-' < as follow on /*/
global_scope::= SCOPE
| TEMPLATE global_scope
id_scope::= id SCOPE
/*
* A :: B :: C; is ambiguous How much is type and how much name ?
* The // %prec maximises the (type) length which is the $07.1-2 semantic constraint.
/*/
nested_id::= id // %prec SHIFT_THERE /* Maximise length /*/
| id_scope nested_id
scoped_id::= nested_id
| global_scope nested_id
/*
* destructor_id has to be held back to avoid a conflict with a one's complement as per $05.3.1-9,
* It gets put back only when scoped or in a declarator_id, which is only used as an explicit member name.
* Declarations of an unscoped destructor are always parsed as a one's complement.
/*/
destructor_id::= '~' id
| TEMPLATE destructor_id
special_function_id::= conversion_function_id
| operator_function_id
| TEMPLATE special_function_id
nested_special_function_id::= special_function_id
| id_scope destructor_id
| id_scope nested_special_function_id
scoped_special_function_id::= nested_special_function_id
| global_scope nested_special_function_id
/* declarator-id is all names in all scopes, except reserved words /*/
declarator_id::= scoped_id
| scoped_special_function_id
| destructor_id
/* The standard defines pseudo-destructors in terms of type-name, which is class/enum/typedef, of which
* class-name is covered by a normal destructor. pseudo-destructors are supposed to support ~int() in
* templates, so the grammar here covers built-in names. Other names are covered by the lack of
* identifier/type discrimination.
/*/
built_in_type_id::= built_in_type_specifier
| built_in_type_id built_in_type_specifier
pseudo_destructor_id::= built_in_type_id SCOPE '~' built_in_type_id
| '~' built_in_type_id
| TEMPLATE pseudo_destructor_id
nested_pseudo_destructor_id::= pseudo_destructor_id
| id_scope nested_pseudo_destructor_id
scoped_pseudo_destructor_id::= nested_pseudo_destructor_id
| global_scope scoped_pseudo_destructor_id
/*---------------------------------------------------------------------------------------------------
* A.2 Lexical conventions
*---------------------------------------------------------------------------------------------------/*/
/*
* String concatenation is a phase 6, not phase 7 activity so does not really belong in the grammar.
* However it may be convenient to have it here to make this grammar fully functional.
* Unfortunately it introduces a conflict with the generalised parsing of extern "C" which
* is correctly resolved to maximise the string length as the token source should do anyway.
/*/
string::= StringLiteral
/*string::= StringLiteral // %prec SHIFT_THERE /*/
/* | StringLiteral string -- Perverse order avoids conflicts -- /*/
literal::= IntegerLiteral
| CharacterLiteral
| FloatingLiteral
| string
| boolean_literal
| NumberLiteral
string_expr::= string
| TreeLiteral
boolean_literal::= FALSE
| TRUE
/*---------------------------------------------------------------------------------------------------
* A.3 Basic concepts
*---------------------------------------------------------------------------------------------------/*/
translation_unit::= declaration_seq.opt
| declaration_seq.opt util looping_declaration '#' bang error '#'
/* $-expression grammar /*/
| '$' tree_expression
| '$' '{' tree_expression ecarb
| '$' bang error
| '$' '{' bang error ecarb
/*---------------------------------------------------------------------------------------------------
* A.4 Expressions
*---------------------------------------------------------------------------------------------------
* primary_expression covers an arbitrary sequence of all names with the exception of an unscoped destructor,
* which is parsed as its unary expression which is the correct disambiguation (when ambiguous).
* This eliminates the traditional A(B) meaning A B ambiguity, since we never have to tack an A onto
* the front of something that might start with (. The name length got maximised ab initio. The downside
* is that semantic interpretation must split the names up again.
*
* Unification of the declaration and expression syntax means that unary and binary pointer declarator operators:
* int * * name
* are parsed as binary and unary arithmetic operators (int) * (*name). Since type information is not used
* ambiguities resulting from a cast
* (cast)*(value)
* are resolved to favour the binary rather than the cast unary to ease AST clean-up.
* The cast-call ambiguity must be resolved to the cast to ensure that (a)(b)c can be parsed.
*
* The problem of the functional cast ambiguity
* name(arg)
* as call or declaration is avoided by maximising the name within the parsing kernel. So
* primary_id_expression picks up
* extern long int const var = 5
* as an assignment to the syntax parsed as "extern long int const var". The presence of two names is
* parsed so that "extern long into const" is distinguished from "var" considerably simplifying subsequent
* semantic resolution.
*
* The generalised name is a concatenation of potential type-names (scoped identifiers or built-in sequences)
* plus optionally one of the special names such as an operator-function-id, conversion-function-id or
* destructor as the final name.
/*/
primary_expression::= literal
| THIS
| suffix_decl_specified_ids
/* | SCOPE identifier -- covered by suffix_decl_specified_ids /*/
/* | SCOPE operator_function_id -- covered by suffix_decl_specified_ids /*/
/* | SCOPE qualified_id -- covered by suffix_decl_specified_ids /*/
| abstract_expression // %prec REDUCE_HERE_MOSTLY /* Prefer binary to unary ops, cast to call /*/
/* | id_expression -- covered by suffix_decl_specified_ids /*/
/*
* Abstract-expression covers the () and [] of abstract-declarators.
/*/
abstract_expression::= parenthesis_clause
| '[' expression.opt ']'
| TEMPLATE parenthesis_clause
/* Type I function parameters are ambiguous with respect to the generalised name, so we have to do a lookahead following
* any function-like parentheses. This unfortunately hits normal code, so kill the -- lines and add the ++ lines for efficiency.
* Supporting Type I code under the superset causes perhaps 25% of lookahead parsing. Sometimes complete class definitions
* get traversed since they are valid generalised type I parameters!
/*/
type1_parameters::= /*----/*/ parameter_declaration_list ';'
| /*----/*/ type1_parameters parameter_declaration_list ';'
mark_type1::= /* empty /*/
postfix_expression::= primary_expression
/* | /++++++/ postfix_expression parenthesis_clause /*/
| /*----/*/ postfix_expression parenthesis_clause mark_type1 '-'
| /*----/*/ postfix_expression parenthesis_clause mark_type1 '+' type1_parameters mark '{' error
/*----/*/
| /*----/*/ postfix_expression parenthesis_clause mark_type1 '+' type1_parameters mark error
/*----/*/
| /*----/*/ postfix_expression parenthesis_clause mark_type1 '+' error
/*----/*/
| postfix_expression '[' expression.opt ']'
/* | destructor_id '[' expression.opt ']' -- not semantically valid /*/
/* | destructor_id parenthesis_clause -- omitted to resolve known ambiguity /*/
/* | simple_type_specifier '(' expression_list.opt ')' -- simple_type_specifier is a primary_expression /*/
| postfix_expression '.' declarator_id
/* | postfix_expression '.' TEMPLATE declarator_id -- TEMPLATE absorbed into declarator_id. /*/
| postfix_expression '.' scoped_pseudo_destructor_id
| postfix_expression ARROW declarator_id
/* | postfix_expression ARROW TEMPLATE declarator_id -- TEMPLATE absorbed into declarator_id. /*/
| postfix_expression ARROW scoped_pseudo_destructor_id
| postfix_expression INC
| postfix_expression DEC
| DYNAMIC_CAST '<' type_id '>' '(' expression ')'
| STATIC_CAST '<' type_id '>' '(' expression ')'
| REINTERPRET_CAST '<' type_id '>' '(' expression ')'
| CONST_CAST '<' type_id '>' '(' expression ')'
| TYPEID parameters_clause
/* | TYPEID '(' expression ')' -- covered by parameters_clause /*/
/* | TYPEID '(' type_id ')' -- covered by parameters_clause /*/
expression_list.opt::= /* empty /*/
| expression_list
expression_list::= assignment_expression
| expression_list ',' assignment_expression
unary_expression::= postfix_expression
| INC cast_expression
| DEC cast_expression
| ptr_operator cast_expression
/* | '*' cast_expression -- covered by ptr_operator /*/
/* | '&' cast_expression -- covered by ptr_operator /*/
/* | decl_specifier_seq '*' cast_expression -- covered by binary operator /*/
/* | decl_specifier_seq '&' cast_expression -- covered by binary operator /*/
| suffix_decl_specified_scope star_ptr_operator cast_expression /* covers e.g int ::type::* const t = 4 /*/
| '+' cast_expression
| '-' cast_expression
| '!' cast_expression
| '~' cast_expression
| SIZEOF unary_expression
/* | SIZEOF '(' type_id ')' -- covered by unary_expression /*/
| new_expression
| global_scope new_expression
| delete_expression
| global_scope delete_expression
/* | DELETE '[' ']' cast_expression -- covered by DELETE cast_expression since cast_expression covers ... /*/
/* | SCOPE DELETE '[' ']' cast_expression // ... abstract_expression cast_expression and so [] cast_expression /*/
delete_expression::= DELETE cast_expression /* also covers DELETE[] cast_expression /*/
new_expression::= NEW new_type_id new_initializer.opt
| NEW parameters_clause new_type_id new_initializer.opt
| NEW parameters_clause
/* | NEW '(' type-id ')' -- covered by parameters_clause /*/
| NEW parameters_clause parameters_clause new_initializer.opt
/* | NEW '(' type-id ')' new_initializer -- covered by parameters_clause parameters_clause /*/
/* | NEW parameters_clause '(' type-id ')' -- covered by parameters_clause parameters_clause /*/
/* ptr_operator_seq.opt production reused to save a // %prec /*/
new_type_id::= type_specifier ptr_operator_seq.opt
| type_specifier new_declarator
| type_specifier new_type_id
new_declarator::= ptr_operator new_declarator
| direct_new_declarator
direct_new_declarator::= '[' expression ']'
| direct_new_declarator '[' constant_expression ']'
new_initializer.opt::= /* empty /*/
| '(' expression_list.opt ')'
/* cast-expression is generalised to support a [] as well as a () prefix. This covers the omission of DELETE[] which when
* followed by a parenthesised expression was ambiguous. It also covers the gcc indexed array initialisation for free.
/*/
cast_expression::= unary_expression
| abstract_expression cast_expression
/* | '(' type_id ')' cast_expression -- covered by abstract_expression /*/
pm_expression::= cast_expression
| pm_expression DOT_STAR cast_expression
| pm_expression ARROW_STAR cast_expression
multiplicative_expression::= pm_expression
| multiplicative_expression star_ptr_operator pm_expression
| multiplicative_expression '/' pm_expression
| multiplicative_expression '%' pm_expression
additive_expression::= multiplicative_expression
| additive_expression '+' multiplicative_expression
| additive_expression '-' multiplicative_expression
shift_expression::= additive_expression
| shift_expression SHL additive_expression
| shift_expression SHR additive_expression
relational_expression::= shift_expression
| relational_expression '<' shift_expression
| relational_expression '>' shift_expression
| relational_expression LE shift_expression
| relational_expression GE shift_expression
equality_expression::= relational_expression
| equality_expression EQ relational_expression
| equality_expression NE relational_expression
and_expression::= equality_expression
| and_expression '&' equality_expression
exclusive_or_expression::= and_expression
| exclusive_or_expression '^' and_expression
inclusive_or_expression::= exclusive_or_expression
| inclusive_or_expression '|' exclusive_or_expression
logical_and_expression::= inclusive_or_expression
| logical_and_expression LOG_AND inclusive_or_expression
logical_or_expression::= logical_and_expression
| logical_or_expression LOG_OR logical_and_expression
conditional_expression::= logical_or_expression
| logical_or_expression '?' expression ':' assignment_expression
/* assignment-expression is generalised to cover the simple assignment of a braced initializer in order to contribute to the
* coverage of parameter-declaration and init-declaration.
/*/
assignment_expression::= conditional_expression
| logical_or_expression assignment_operator assignment_expression
| logical_or_expression '=' braced_initializer
| throw_expression
assignment_operator::= '=' | ASS_ADD | ASS_AND | ASS_DIV | ASS_MOD | ASS_MUL | ASS_OR | ASS_SHL | ASS_SHR | ASS_SUB | ASS_XOR
/* expression is widely used and usually single-element, so the reductions are arranged so that a
* single-element expression is returned as is. Multi-element expressions are parsed as a list that
* may then behave polymorphically as an element or be compacted to an element. /*/
expression.opt::= /* empty /*/
| expression
expression::= assignment_expression
| expression_list ',' assignment_expression
constant_expression::= conditional_expression
/* The grammar is repeated for when the parser stack knows that the next > must end a template.
/*/
templated_relational_expression::= shift_expression
| templated_relational_expression '<' shift_expression
| templated_relational_expression LE shift_expression
| templated_relational_expression GE shift_expression
templated_equality_expression::= templated_relational_expression
| templated_equality_expression EQ templated_relational_expression
| templated_equality_expression NE templated_relational_expression
templated_and_expression::= templated_equality_expression
| templated_and_expression '&' templated_equality_expression
templated_exclusive_or_expression::= templated_and_expression
| templated_exclusive_or_expression '^' templated_and_expression
templated_inclusive_or_expression::= templated_exclusive_or_expression
| templated_inclusive_or_expression '|' templated_exclusive_or_expression
templated_logical_and_expression::= templated_inclusive_or_expression
| templated_logical_and_expression LOG_AND templated_inclusive_or_expression
templated_logical_or_expression::= templated_logical_and_expression
| templated_logical_or_expression LOG_OR templated_logical_and_expression
templated_conditional_expression::= templated_logical_or_expression
| templated_logical_or_expression '?' templated_expression ':' templated_assignment_expression
templated_assignment_expression::= templated_conditional_expression
| templated_logical_or_expression assignment_operator templated_assignment_expression
| templated_throw_expression
templated_expression::= templated_assignment_expression
| templated_expression_list ',' templated_assignment_expression
templated_expression_list::= templated_assignment_expression
| templated_expression_list ',' templated_assignment_expression
/*---------------------------------------------------------------------------------------------------
* A.5 Statements
*---------------------------------------------------------------------------------------------------
* Parsing statements is easy once simple_declaration has been generalised to cover expression_statement.
/*/
looping_statement::= start_search looped_statement
looped_statement::= statement
| advance_search '+' looped_statement
| advance_search '-'
statement::= control_statement
/* | expression_statement -- covered by declaration_statement /*/
| compound_statement
| declaration_statement
| try_block
| AUTO control_statement
| AUTO meta_expression_statement
control_statement::= labeled_statement
| selection_statement
| iteration_statement
| jump_statement
labeled_statement::= identifier_word ':' looping_statement
| CASE constant_expression ':' looping_statement
| DEFAULT ':' looping_statement
/*expression_statement::= expression.opt ';' -- covered by declaration_statement /*/
compound_statement::= '{' statement_seq.opt '}'
| '{' statement_seq.opt looping_statement '#' bang error_ecarb
statement_seq.opt::= /* empty /*/
| statement_seq.opt looping_statement
| statement_seq.opt looping_statement '#' bang error ';'
/*
* The dangling else conflict is resolved to the innermost if.
/*/
selection_statement::= IF '(' condition ')' looping_statement // %prec SHIFT_THERE
| IF '(' condition ')' looping_statement ELSE looping_statement
| SWITCH '(' condition ')' looping_statement
condition.opt::= /* empty /*/
| condition
condition::= parameter_declaration_list
/* | expression -- covered by parameter_declaration_list /*/
/* | type_specifier_seq declarator '=' assignment_expression -- covered by parameter_declaration_list /*/
iteration_statement::= WHILE '(' condition ')' looping_statement
| DO looping_statement WHILE '(' expression ')' ';'
| FOR '(' for_init_statement condition.opt ';' expression.opt ')' looping_statement
for_init_statement::= simple_declaration
/* | expression_statement -- covered by simple_declaration /*/
jump_statement::= BREAK ';'
| CONTINUE ';'
| RETURN expression.opt ';'
| GOTO identifier ';'
declaration_statement::= block_declaration
/*---------------------------------------------------------------------------------------------------
* A.6 Declarations
*---------------------------------------------------------------------------------------------------/*/
compound_declaration::= '{' nest declaration_seq.opt '}'
| '{' nest declaration_seq.opt util looping_declaration '#' bang error_ecarb
declaration_seq.opt::= /* empty /*/
| declaration_seq.opt util looping_declaration
| declaration_seq.opt util looping_declaration '#' bang error ';'
looping_declaration::= start_search1 looped_declaration
looped_declaration::= declaration
| advance_search '+' looped_declaration
| advance_search '-'
lined_declaration::= line declaration
declaration::= block_declaration
| function_definition
| template_declaration
/* | explicit_instantiation -- covered by relevant declarations /*/
| explicit_specialization
| specialised_declaration
| accessibility_specifier
| compound_declaration
| meta_control_statement
| AUTO meta_control_statement
| AUTO meta_class_specifier semi
| AUTO meta_expression_statement
| AUTO meta_function_definition
| syntax_macro_definition
| include_declaration semi
| file_dependency_declaration
| file_placement_declaration
| filespace_specifier semi
specialised_declaration::= linkage_specification
| namespace_declaration
| namespace_definition
| TEMPLATE specialised_declaration
block_declaration::= simple_declaration
| specialised_block_declaration
specialised_block_declaration::= asm_definition
| namespace_alias_definition
/* | using_declaration -- covered by simple_declaration /*/
| using_directive
| TEMPLATE specialised_block_declaration
simple_declaration::= ';'
| init_declaration ';'
| constructor_head ',' assignment_expression ';'
| init_declarations ';'
| decl_specifier_prefix simple_declaration
/* A decl-specifier following a ptr_operator provokes a shift-reduce conflict for
* * const name
* which is resolved in favour of the pointer, and implemented by providing versions
* of decl-specifier guaranteed not to start with a cv_qualifier.
*
* decl-specifiers are implemented type-centrically. That is the semantic constraint
* that there must be a type is exploited to impose structure, but actually eliminate
* very little syntax. built-in types are multi-name and so need a different policy.
*
* non-type decl-specifiers are bound to the left-most type in a decl-specifier-seq,
* by parsing from the right and attaching suffixes to the right-hand type. Finally
* residual prefixes attach to the left.
/*/
suffix_built_in_decl_specifier.raw::= built_in_type_specifier
| suffix_built_in_decl_specifier.raw built_in_type_specifier
| suffix_built_in_decl_specifier.raw decl_specifier_suffix
suffix_built_in_decl_specifier::= suffix_built_in_decl_specifier.raw
| TEMPLATE suffix_built_in_decl_specifier
suffix_named_decl_specifier::= scoped_id
| elaborate_type_specifier
| suffix_named_decl_specifier decl_specifier_suffix
suffix_named_decl_specifier.bi::= suffix_named_decl_specifier
| suffix_named_decl_specifier suffix_built_in_decl_specifier.raw
suffix_named_decl_specifiers::= suffix_named_decl_specifier.bi
| suffix_named_decl_specifiers suffix_named_decl_specifier.bi
suffix_named_decl_specifiers.sf::= scoped_special_function_id /* operators etc /*/
| suffix_named_decl_specifiers
| suffix_named_decl_specifiers scoped_special_function_id
suffix_decl_specified_ids::= suffix_built_in_decl_specifier
| suffix_built_in_decl_specifier suffix_named_decl_specifiers.sf
| suffix_named_decl_specifiers.sf
suffix_decl_specified_scope::= suffix_named_decl_specifiers SCOPE
| suffix_built_in_decl_specifier suffix_named_decl_specifiers SCOPE
| suffix_built_in_decl_specifier SCOPE
decl_specifier_affix::= storage_class_specifier
| function_specifier
| FRIEND
| TYPEDEF
| cv_qualifier
/* The bogus conflict between public: as an anonymous bit-field and member-specification is resolved to the member-specification./*/
| access_specifier // %prec SHIFT_THERE
/* using-declaration is generalised to cover a much more general concept of re-use, so using treated like typedef.
* Unfortunately this gives the same conflict on string as for linkage_specification, so the // %prec forces using followed
* by a string to be treated as an include rather than a declaration. /*/
| USING // %prec SHIFT_THERE
decl_specifier_suffix::= decl_specifier_affix
| AUTO
decl_specifier_prefix::= decl_specifier_affix
| TEMPLATE decl_specifier_prefix
storage_class_specifier::= REGISTER | STATIC | MUTABLE
| EXTERN // %prec SHIFT_THERE /* Prefer linkage specification /*/
| '!' STATIC
function_specifier::= EXPLICIT
| INLINE // %prec SHIFT_THERE /* Prefer INLINE / IMPLEMENTATION /*/
| VIRTUAL // %prec SHIFT_THERE /* Prefer VIRTUAL / PURE /*/
| '!' INLINE
| INLINE '/' IMPLEMENTATION
| INLINE '/' INTERFACE
| '!' VIRTUAL
| VIRTUAL '/' PURE
type_specifier::= simple_type_specifier
| elaborate_type_specifier
| cv_qualifier
/* The following augment type_specifier rather than cv_qualifier to avoid a conflict on ! between
* a * ! const b and a * ! b which requires a 2-token lookahead to resolve. /*/
| '!' CONST
| '!' VOLATILE
elaborate_type_specifier::= class_specifier
| enum_specifier
| elaborated_type_specifier
| TEMPLATE elaborate_type_specifier
simple_type_specifier::= scoped_id
| built_in_type_specifier
built_in_type_specifier::= BuiltInTypeSpecifier
/*
* The over-general use of declaration_expression to cover decl-specifier-seq.opt declarator in a function-definition means that
* class X
* could be a function-definition or a class-specifier.
* enum X
* could be a function-definition or an enum-specifier.
* The function-definition is not syntactically valid so resolving the false conflict in favour of the
* elaborated_type_specifier is correct.
/*/
elaborated_type_specifier::= elaborated_class_specifier
| elaborated_enum_specifier
| TYPENAME scoped_id
elaborated_enum_specifier::= ENUM scoped_id // %prec SHIFT_THERE
enum_specifier::= ENUM scoped_id enumerator_clause
| ENUM enumerator_clause
enumerator_clause::= '{' enumerator_list_ecarb
| '{' enumerator_list enumerator_list_ecarb
| '{' enumerator_list ',' enumerator_definition_ecarb
enumerator_list_ecarb::= '}'
| bang error_ecarb
enumerator_definition_ecarb::= '}'
| bang error_ecarb
enumerator_definition_filler::= /* empty /*/
| bang error ','
enumerator_list_head::= enumerator_definition_filler
| enumerator_list ',' enumerator_definition_filler
enumerator_list::= enumerator_list_head enumerator_definition
enumerator_definition::= enumerator
| enumerator '=' constant_expression
enumerator::= identifier
namespace_definition::= NAMESPACE scoped_id compound_declaration
| NAMESPACE compound_declaration
namespace_alias_definition::= NAMESPACE scoped_id '=' scoped_id ';'
namespace_declaration::= NAMESPACE scoped_id ';'
using_directive::= USING NAMESPACE scoped_id ';'
asm_definition::= ASM '(' string ')' ';'
linkage_specification::= EXTERN string looping_declaration
/* | EXTERN string compound_declaration -- covered by declaration /*/
/*---------------------------------------------------------------------------------------------------
* A.7 Declarators
*---------------------------------------------------------------------------------------------------/*/
/*init-declarator is named init_declaration to reflect the embedded decl-specifier-seq.opt/*/
init_declarations::= assignment_expression ',' init_declaration
| init_declarations ',' init_declaration
| init_object_declaration ',' init_declaration
| constructor_head ',' bit_field_init_declaration
| constructor_head ',' init_object_declaration
init_declaration::= assignment_expression
/* | assignment_expression '=' initializer_clause -- covered by assignment_expression /*/
/* | assignment_expression '(' expression_list ')' -- covered by another set of call arguments /*/
| bit_field_init_declaration
| init_object_declaration
init_object_declaration::= assignment_expression object_statements_clause
| bit_field_init_declaration object_statements_clause
/*declarator::= -- covered by assignment_expression /*/
/*direct_declarator::= -- covered by postfix_expression /*/
star_ptr_operator::= '*'
| star_ptr_operator cv_qualifier
nested_ptr_operator::= star_ptr_operator
| id_scope nested_ptr_operator
ptr_operator::= '&'
| nested_ptr_operator
| global_scope nested_ptr_operator
ptr_operator_seq::= ptr_operator
| ptr_operator ptr_operator_seq
/* Independently coded to localise the shift-reduce conflict: sharing just needs another // %prec /*/
ptr_operator_seq.opt::= /* empty /*/ // %prec SHIFT_THERE /* Maximise type length /*/
| ptr_operator ptr_operator_seq.opt
cv_qualifier_seq.opt::= /* empty /*/
| cv_qualifier_seq.opt cv_qualifier
cv_qualifier::= CONST | VOLATILE /* | CvQualifier /*/
/*type_id -- also covered by parameter declaration /*/
type_id::= type_specifier abstract_declarator.opt
| type_specifier type_id
/*abstract_declarator::= -- also covered by parameter declaration /*/
abstract_declarator.opt::= /* empty /*/
| ptr_operator abstract_declarator.opt
| direct_abstract_declarator
direct_abstract_declarator.opt::= /* empty /*/
| direct_abstract_declarator
direct_abstract_declarator::= direct_abstract_declarator.opt parenthesis_clause
| direct_abstract_declarator.opt '[' ']'
| direct_abstract_declarator.opt '[' constant_expression ']'
/* | '(' abstract_declarator ')' -- covered by parenthesis_clause /*/
parenthesis_clause::= parameters_clause cv_qualifier_seq.opt
| parameters_clause cv_qualifier_seq.opt exception_specification
parameters_clause::= '(' parameter_declaration_clause ')'
/* parameter_declaration_clause also covers init_declaration, type_id, declarator and abstract_declarator. /*/
parameter_declaration_clause::= /* empty /*/
| parameter_declaration_list
| parameter_declaration_list ELLIPSIS
parameter_declaration_list::= parameter_declaration
| parameter_declaration_list ',' parameter_declaration
/* A typed abstract qualifier such as
* Class * ...
* looks like a multiply, so pointers are parsed as their binary operation equivalents that
* ultimately terminate with a degenerate right hand term.
/*/
abstract_pointer_declaration::= ptr_operator_seq
| multiplicative_expression star_ptr_operator ptr_operator_seq.opt
abstract_parameter_declaration::= abstract_pointer_declaration
| and_expression '&'
| and_expression '&' abstract_pointer_declaration
special_parameter_declaration::= abstract_parameter_declaration
| abstract_parameter_declaration '=' assignment_expression
| ELLIPSIS
parameter_declaration::= assignment_expression
| special_parameter_declaration
| decl_specifier_prefix parameter_declaration
/* The grammar is repeated for use within template <>
/*/
templated_parameter_declaration::= templated_assignment_expression
| templated_abstract_declaration
| templated_abstract_declaration '=' templated_assignment_expression
| decl_specifier_prefix templated_parameter_declaration
templated_abstract_declaration::= abstract_pointer_declaration
| templated_and_expression '&'
| templated_and_expression '&' abstract_pointer_declaration
/* function_definition includes constructor, destructor, implicit int definitions too.
* A local destructor is successfully parsed as a function-declaration but the ~ was treated as a unary operator.
* constructor_head is the prefix ambiguity between a constructor and a member-init-list starting with a bit-field.
/*/
function_definition::= ctor_definition
| func_definition
func_definition::= assignment_expression function_try_block
| assignment_expression function_body
| decl_specifier_prefix func_definition
ctor_definition::= constructor_head function_try_block
| constructor_head function_body
| decl_specifier_prefix ctor_definition
constructor_head::= bit_field_init_declaration
| constructor_head ',' assignment_expression
function_try_block::= TRY function_block handler_seq
function_block::= ctor_initializer.opt function_body
function_body::= compound_statement
/* An = initializer looks like an extended assignment_expression.
* An () initializer looks like a function call.
* initializer is therefore flattened into its generalised customers.
*initializer: '=' initializer_clause -- flattened into caller
* | '(' expression_list ')' -- flattened into caller /*/
initializer_clause::= assignment_expression
| braced_initializer
braced_initializer::= '{' initializer_list '}'
| '{' initializer_list ',' '}'
| '{' '}'
| '{' looping_initializer_clause '#' bang error_ecarb
| '{' initializer_list ',' looping_initializer_clause '#' bang error_ecarb
initializer_list::= looping_initializer_clause
| initializer_list ',' looping_initializer_clause
looping_initializer_clause::= start_search looped_initializer_clause
looped_initializer_clause::= initializer_clause
| advance_search '+' looped_initializer_clause
| advance_search '-'
/*---------------------------------------------------------------------------------------------------
* A.8 Classes
*---------------------------------------------------------------------------------------------------
*
* An anonymous bit-field declaration may look very like inheritance:
* class A : B = 3
* class A : B
* The two usages are too distant to try to create and enforce a common prefix so we have to resort to
* a parser hack by backtracking. Inheritance is much the most likely so we mark the input stream context
* and try to parse a base-clause. If we successfully reach a { the base-clause is ok and inheritance was
* the correct choice so we unmark and continue. If we fail to find the { an error token causes back-tracking
* to the alternative parse in elaborated_class_specifier which regenerates the : and declares unconditional success.
/*/
colon_mark::= ':'
elaborated_class_specifier::= class_key scoped_id // %prec SHIFT_THERE
| class_key scoped_id colon_mark error
class_specifier_head::= class_key scoped_id colon_mark base_specifier_list '{'
| class_key ':' base_specifier_list '{'
| class_key scoped_id '{'
| class_key '{'
class_key::= CLASS | STRUCT | UNION
class_specifier::= class_specifier_head nest declaration_seq.opt '}'
| class_specifier_head nest declaration_seq.opt util looping_declaration '#' bang error_ecarb
accessibility_specifier::= access_specifier ':'
bit_field_declaration::= assignment_expression ':' bit_field_width
| ':' bit_field_width
bit_field_width::= logical_or_expression
/* | logical_or_expression '?' expression ':' assignment_expression -- has SR conflict w.r.t later = /*/
| logical_or_expression '?' bit_field_width ':' bit_field_width
bit_field_init_declaration::= bit_field_declaration
| bit_field_declaration '=' initializer_clause
/*---------------------------------------------------------------------------------------------------
* A.9 Derived classes
*---------------------------------------------------------------------------------------------------/*/
/*base_clause::= ':' base_specifier_list -- flattened /*/
base_specifier_list::= base_specifier
| base_specifier_list ',' base_specifier
base_specifier::= scoped_id
| access_specifier base_specifier
| VIRTUAL base_specifier
| '!' VIRTUAL base_specifier
| AUTO base_specifier
| built_in_type_id
access_specifier::= PRIVATE | PROTECTED | PUBLIC
/*---------------------------------------------------------------------------------------------------
* A.10 Special member functions
*---------------------------------------------------------------------------------------------------/*/
conversion_function_id::= OPERATOR conversion_type_id
conversion_type_id::= type_specifier ptr_operator_seq.opt
| type_specifier conversion_type_id
/*
* Ctor-initialisers can look like a bit field declaration, given the generalisation of names:
* Class(Type) : m1(1), m2(2)
* NonClass(bit_field) : int(2), second_variable, ...
* The grammar below is used within a function_try_block or function_definition.
* See simple_member_declaration for use in normal member function_definition.
/*/
ctor_initializer.opt::= /* empty /*/
| ctor_initializer
ctor_initializer::= ':' mem_initializer_list
| ':' mem_initializer_list bang error
mem_initializer_list::= mem_initializer
| mem_initializer_list_head mem_initializer
mem_initializer_list_head::= mem_initializer_list ','
| mem_initializer_list bang error ','
| mem_initializer_list bang error '#'
mem_initializer::= mem_initializer_id '(' expression_list.opt ')'
mem_initializer_id::= scoped_id
/*---------------------------------------------------------------------------------------------------
* A.11 Overloading
*---------------------------------------------------------------------------------------------------/*/
operator_function_id::= OPERATOR operator
/*
* It is not clear from the ANSI standard whether spaces are permitted in delete[]. If not then it can
* be recognised and returned as DELETE_ARRAY by the lexer. Assuming spaces are permitted there is an
* ambiguity created by the over generalised nature of expressions. operator new is a valid delarator-id
* which we may have an undimensioned array of. Semantic rubbish, but syntactically valid. Since the
* array form is covered by the declarator consideration we can exclude the operator here. The need
* for a semantic rescue can be eliminated at the expense of a couple of shift-reduce conflicts by
* removing the comments on the next four lines.
/*/
operator::= /*++++/*/ NEW
| /*++++/*/ DELETE
/* | / ---- / NEW // %prec SHIFT_THERE
/* | / ---- / DELETE // %prec SHIFT_THERE
/* | / ---- / NEW '[' ']' -- Covered by array of OPERATOR NEW /*/
/* | / ---- / DELETE '[' ']' -- Covered by array of OPERATOR DELETE /*/
| '+'
| '-'
| '*'
| '/'
| '%'
| '^'
| '&'
| '|'
| '~'
| '!'
| '='
| '<'
| '>'
| ASS_ADD
| ASS_SUB
| ASS_MUL
| ASS_DIV
| ASS_MOD
| ASS_XOR
| ASS_AND
| ASS_OR
| SHL
| SHR
| ASS_SHR
| ASS_SHL
| EQ
| NE
| LE
| GE
| LOG_AND
| LOG_OR
| INC
| DEC
| ','
| ARROW_STAR
| ARROW
| '(' ')'
| '[' ']'
/*---------------------------------------------------------------------------------------------------
* A.12 Templates
*---------------------------------------------------------------------------------------------------/*/
template_declaration::= template_parameter_clause declaration
| EXPORT template_declaration
/* This extension is only defined for USING, but we need to use decl_specifier_prefix to avoid conflicts. /*/
| decl_specifier_prefix template_declaration
template_parameter_clause::= TEMPLATE '<' template_parameter_list '>'
template_parameter_list::= template_parameter
| template_parameter_list ',' template_parameter
template_parameter::= simple_type_parameter
| simple_type_parameter '=' type_id
| templated_type_parameter
| templated_type_parameter '=' identifier
| templated_parameter_declaration
| bang error
simple_type_parameter::= CLASS
/* | CLASS identifier -- covered by parameter_declaration /*/
| TYPENAME
/* | TYPENAME identifier -- covered by parameter_declaration /*/
templated_type_parameter::= template_parameter_clause CLASS
| template_parameter_clause CLASS identifier
template_id::= TEMPLATE identifier '<' template_argument_list '>'
| TEMPLATE template_id
/*
* template-argument is evaluated using a templated...expression so that > resolves to end of template.
/*/
template_argument_list::= template_argument
| template_argument_list ',' template_argument
template_argument::= templated_parameter_declaration
/* | type_id -- covered by templated_parameter_declaration /*/
/* | template_name -- covered by templated_parameter_declaration /*/
/* | error -- must allow template failure to re-search /*/
/*
* Generalised naming makes identifier a valid declaration, so TEMPLATE identifier is too.
* The TEMPLATE prefix is therefore folded into all names, parenthesis_clause and decl_specifier_prefix.
/*/
/*explicit_instantiation::= TEMPLATE declaration /*/
explicit_specialization::= TEMPLATE '<' '>' declaration
/* This extension is only defined for USING, but we need to use decl_specifier_prefix to avoid conflicts. /*/
| decl_specifier_prefix explicit_specialization
/*---------------------------------------------------------------------------------------------------
* A.13 Exception Handling
*---------------------------------------------------------------------------------------------------/*/
try_block::= TRY compound_statement handler_seq
/*function_try_block::= -- moved near function_block /*/
/* A handler_seq may follow a try_block in a compound_tree_statement such as:
* if (a) try catch(a) catch(b) catch(c) ...
* we resolve the conflict by maximising the handler sequence. /*/
handler_seq::= handler // %prec SHIFT_THERE /* Maximise length /*/
| handler handler_seq
handler::= CATCH '(' exception_declaration ')' compound_statement
exception_declaration::= parameter_declaration
/* ELLIPSIS -- covered by parameter_declaration /*/
throw_expression::= THROW
| THROW assignment_expression
templated_throw_expression::= THROW
| THROW templated_assignment_expression
exception_specification::= THROW '(' ')'
| THROW '(' type_id_list ')'
type_id_list::= type_id
| type_id_list ',' type_id
/*---------------------------------------------------------------------------------------------------
* A.14 Tree literals
*---------------------------------------------------------------------------------------------------/*/
primary_tree_expression::= meta_scoped_id
| '(' tree_expression ')'
postfix_tree_expression::= primary_tree_expression
| postfix_tree_expression '[' ']'
| postfix_tree_expression '[' constant_expression ']'
| postfix_tree_expression '(' tree_argument_list.opt ')'
| postfix_tree_expression '.' scoped_id
| postfix_tree_expression ARROW scoped_id
tree_expression::= postfix_tree_expression
| '*' tree_expression
/* tree_argument_list.opt are carefully coded to avoid conflicts between the components of a constructor_head at the start of a function_definition
* and the equivalent discrete elements. There is no need to resolve a conflict on ","!, which is fortunate because it couldn't work. /*/
tree_argument_list.opt::= tree_arguments.head
| tree_arguments.head ',' tree_argument_list.opt
| tree_argument.ctors
tree_argument.ctors::= constructor_head
| decl_specifier_prefix tree_argument.ctors
tree_arguments.head::= /* empty /*/
| tree_argument.most
| assignment_expression
| func_definition
| tree_argument.ctors_comma_most
tree_argument.ctors_comma_most::= constructor_head ',' tree_argument.most
| decl_specifier_prefix tree_argument.ctors_comma_most
tree_argument.most::= terminated_tree_argument
| ctor_definition
| unterminated_tree_argument.most
| unterminated_tree_argument.most ';'
| tree_argument.misc
| tree_argument.misc ';'
tree_argument.misc::= decl_specifier_prefix
/* | assignment_expression -- separated out /*/
/* | bit_field_init_declaration -- separated out into tree_argument.ctors /*/
/* | function_definition -- split into ctor/func_definition /*/
| init_object_declaration
| special_parameter_declaration
| decl_specifier_prefix assignment_expression
| decl_specifier_prefix tree_argument.misc
looping_unterminated_tree_argument::= start_search looped_unterminated_tree_argument
looped_unterminated_tree_argument::= unterminated_tree_argument
| advance_search '+' looped_unterminated_tree_argument
/* | advance_search '-' /*/
/* Omission of the preceding line which causes two reduce/reduce conflicts is justified provided the
* looped_unterminated_tree_argument rules are only used within a compound_tree_statement, where the alternate
* looping search for a tree_statement precedes and dominates this search. Since the cascaded advance_search '-'
* is only used to terminate a total failure of the search for a plausible template/arithmetic syntax, it doesn't
* matter, apart from minor error reporting niceties, whether it is the statement or unterminated argument search
* that is deemed to have failed.
/*/
looping_tree_statement::= start_search looped_tree_statement
looped_tree_statement::= tree_statement
| advance_search '+' looped_tree_statement
| advance_search '-'
tree_statement::= ';'
| terminated_tree_argument
| unterminated_tree_argument ';'
| function_definition
compound_tree_statement::= '{' tree_statement_seq.opt '}'
| '{' tree_statement_seq.opt looping_unterminated_tree_argument '}'
| '{' tree_statement_seq.opt looping_unterminated_tree_argument '#' bang error_ecarb
| '{' tree_statement_seq.opt looping_tree_statement '#' bang error_ecarb
tree_statement_seq.opt::= /* empty /*/
| tree_statement_seq.opt looping_tree_statement
| tree_statement_seq.opt looping_tree_statement '#' bang error ';'
/* Terminated syntax has an unambiguous end and does not need a ; as a meta-variable initializer. /*/
terminated_tree_argument::= asm_definition
| compound_tree_statement
/* | declaration_statement ';' -- covered by simple_tree_declaration ; /*/
/* | explicit_instantiation -- covered by simple_tree_declaration ; /*/
| explicit_specialization
/* | expression_statement ';' -- covered by simple_tree_declaration ; /*/
| file_dependency_declaration
| file_placement_declaration
| include_declaration semi
| iteration_statement
/* | jump_statement -- covered by BREAK ; /*/
| labeled_statement
| linkage_specification
| namespace_alias_definition
| namespace_declaration
| namespace_definition
/* | parameter_declaration ';' -- covered by simple_tree_declaration ; /*/
| selection_statement
| template_declaration
| using_directive
| AUTO meta_control_statement
| AUTO meta_expression_statement
| AUTO meta_function_definition
| OPERATOR ';'
/* Unterminated syntax has no obvious end and/or must have a ; as a meta-variable initializer. /*/
unterminated_tree_argument::= unterminated_tree_argument.most
| simple_tree_declaration
unterminated_tree_argument.most::= accessibility_specifier
/* | access_specifier -- covered by decl_specifier_affix /*/
/* | base_specifier -- covered by simple_tree_declaration /*/
/* | built_in_type_specifier -- covered by simple_tree_declaration /*/
/* | class_specifier -- covered by simple_tree_declaration /*/
/* | condition -- covered by simple_tree_declaration /*/
/* | cv_qualifier -- covered by simple_tree_declaration /*/
/* | decl_specifier -- covered by simple_tree_declaration /*/
/* | enum_specifier -- covered by simple_tree_declaration /*/
/* | enumerator_definition -- covered by simple_tree_declaration /*/
/* | exception_declaration -- covered by simple_tree_declaration /*/
/* | exception_specification -- covered by simple_tree_declaration /*/
| filespace_specifier
/* | function_definition -- not part of .most /*/
| function_try_block
| handler_seq
/* | initializer_clause -- covered by simple_tree_declaration, compound_statement /*/
/* | mem_initializer -- covered by simple_tree_declaration /*/
| AUTO meta_class_specifier
/* | operator -- mostly covered by token.punct /*/
/* | parameter_declaration -- not part of .most /*/
/* | simple_tree_declaration -- not part of .most /*/
| simple_type_parameter
/* | storage_class_specifier -- covered by simple_tree_declaration /*/
/* | template_argument -- covered by simple_tree_declaration /*/
/* | template_parameter -- covered by simple_tree_declaration /*/
/* | try_block -- covered by function_try_block /*/
/* | type_id -- covered by simple_tree_declaration /*/
/* | type_parameter -- covered by simple_tree_declaration, template_declaration /*/
| reserved_id
| token.punct
| AUTO
/* | CATCH -- awkward function-definition at end of terminated /*/
/* | CLASS -- covered by simple_type_parameter /*/
/* | DO -- DO ; awkward /*/
| ENUM
| NAMESPACE
/* | OPERATOR -- OPERATOR , awkward /*/
| STRUCT
| TEMPLATE
/* | THROW -- covered by throw-expression /*/
/* | TYPENAME -- covered by simple_type_parameter /*/
| UNION
/* | '*' | '&' | ELLIPSIS -- covered by simple_tree_declaration /*/
/* | '#' -- used as error iteration flag /*/
/* | ',' | '{' | '}' | '(' | ')' | ';' -- awkward - major punctuation /*/
/* | '/' -- awkward looks like switch /*/
reserved_id::= ASM | BREAK | CASE | CONST_CAST | CONTINUE | DEFAULT | DELETE | DYNAMIC_CAST | ELSE | FOR
| GOTO | IF | NEW | REINTERPRET_CAST | RETURN | SIZEOF | STATIC_CAST | SWITCH | TRY | TYPEID | WHILE
| EXPORT
token.punct::= SCOPE | SHL | SHR | EQ | NE | LE | GE | LOG_AND | LOG_OR | INC | DEC | ARROW | ARROW_STAR | DOT_STAR
| ASS_ADD | ASS_AND | ASS_DIV | ASS_MOD | ASS_MUL | ASS_OR | ASS_SHL | ASS_SHR | ASS_SUB | ASS_XOR
| '[' | ']' | ':' | '?' | '.'
| '+' | '-' | '%' | '^' | '|' | '~' | '!' | '=' | '<' | '>'
| "'" | '"' | '\\'
| '@' | '$'
simple_tree_declaration::= decl_specifier_prefix
| init_declaration
| constructor_head ',' assignment_expression
| init_declarations
| special_parameter_declaration
| decl_specifier_prefix simple_tree_declaration
/*---------------------------------------------------------------------------------------------------
* A.15 Object statements
*---------------------------------------------------------------------------------------------------/*/
object_statements_clause::= ':' '{' object_statement_seq.opt '}'
| ':' '{' object_statement_seq.opt looping_object_statement '#' bang error_ecarb
object_statement_seq.opt::= /* empty /*/
| object_statement_seq.opt looping_object_statement
| object_statement_seq.opt looping_object_statement '#' bang error ';'
looping_object_statement::= start_search looped_object_statement
looped_object_statement::= object_statement
| advance_search '+' looped_object_statement
| advance_search '-'
object_statement::= ';'
| function_used_block
| '=' initializer_clause ';'
| '(' expression_list ')' ';'
| file_dependency_declaration
| file_placement_declaration
| filespace_specifier semi
| meta_control_statement
| AUTO meta_control_statement
| AUTO meta_expression_statement
| AUTO meta_function_definition
| derived_clause object_statement
| derived_clause ':' '{' object_statement_seq.opt '}'
| derived_clause ':' '{' object_statement_seq.opt looping_object_statement '#' bang error '#'
function_used_block::= function_block
| function_try_block
| ctor_initializer ';'
| USING file_id_list function_used_block
| segment function_used_block
segment::= BODY
| ENTRY
| EXIT
| POST
| PRE
/*---------------------------------------------------------------------------------------------------
* A.16 Derivation rules
*---------------------------------------------------------------------------------------------------/*/
derived_clause::= DERIVED '(' meta_conditional_expression ')'
/*---------------------------------------------------------------------------------------------------
* A 17.1 meta-names
*---------------------------------------------------------------------------------------------------/*/
meta_id::= id
| meta_simple_type
| AUTO
meta_scope::= meta_id SCOPE
meta_nested_id::= meta_id
| meta_scope '~' meta_id
| meta_scope meta_nested_id
meta_scoped_id::= meta_nested_id
| global_scope meta_nested_id
/*---------------------------------------------------------------------------------------------------
* A 17.2 meta-classes
*---------------------------------------------------------------------------------------------------/*/
meta_class_specifier::= meta_class_key meta_nested_id compound_declaration
| meta_class_key meta_nested_id ':' base_specifier_list compound_declaration
/*---------------------------------------------------------------------------------------------------
* A 17.3 meta-types
*---------------------------------------------------------------------------------------------------
* The MetaType names are not reserved words so form part of identifier and consequently scoped_id /*/
/* The // %prec maximises the length of e.g. unsigned int when followed by e.g int::a /*/
meta_class_key::= class_key
| NAMESPACE
meta_non_class_key::= ENUM
| TYPEDEF
| TYPENAME
| USING
| built_in_type_id // %prec SHIFT_THERE
meta_simple_type::= meta_class_key
| meta_non_class_key
meta_type::= MetaType
| meta_simple_type
/*---------------------------------------------------------------------------------------------------
* A 17.4 meta-variables
*---------------------------------------------------------------------------------------------------/*/
/*meta_variable_declaration::= -- covered by meta_expression_statement /*/
/*---------------------------------------------------------------------------------------------------
* A 17.5 meta-functions, meta-constructors and meta-destructors
*---------------------------------------------------------------------------------------------------/*/
/* meta_postfix_expression covers the function name, tree_argument_list.opt covers the parameter list /*/
/* meta_postfix_expression also covers the function name(tree_argument_list.opt) for exposed list /*/
meta_function_definition::= meta_fn_postfix_expression compound_tree_statement
| '~' meta_fn_postfix_expression compound_tree_statement
| CONST meta_function_definition
| STATIC meta_function_definition
| '!' STATIC meta_function_definition
/* | meta_postfix_expression '(' tree_argument_list.opt ')' object_statements_clause
-- covered by meta_expression_statement /*/
/*---------------------------------------------------------------------------------------------------
* A 17.6 meta-statements
*---------------------------------------------------------------------------------------------------/*/
meta_control_statement::= line meta_control_statement1
meta_control_statement1::= CASE constant_expression ':' lined_declaration
| DEFAULT ':' lined_declaration
| DO lined_declaration WHILE '(' expression ')' semi
| IF '(' condition ')' lined_declaration // %prec SHIFT_THERE
| IF '(' condition ')' lined_declaration ELSE lined_declaration
| SWITCH '(' expression ')' lined_declaration
| WHILE '(' condition ')' lined_declaration
| FOR '(' for_init_statement condition.opt ';' expression.opt ')' lined_declaration
| jump_statement
/*---------------------------------------------------------------------------------------------------
* A 17.7 meta-expressions
*---------------------------------------------------------------------------------------------------/*/
meta_primary_head::= meta_scoped_id
| MetaType meta_nested_id
| meta_non_class_key meta_nested_id
meta_primary_id::= meta_primary_head
| meta_class_key meta_nested_id
meta_primary_expression::= literal
| THIS
| meta_primary_id
| '(' tree_argument_list.opt ')'
meta_fn_postfix_expression::= meta_postfix_expression '(' tree_argument_list.opt ')'
| meta_postfix_expression '[' ']'
meta_postfix_expression::= meta_primary_expression
| meta_fn_postfix_expression
| meta_postfix_expression '[' expression ']'
| meta_postfix_expression '.' declarator_id
| meta_postfix_expression ARROW declarator_id
| meta_postfix_expression INC
| meta_postfix_expression DEC
meta_unary_expression::= meta_postfix_expression
| INC meta_cast_expression
| DEC meta_cast_expression
| star_ptr_operator meta_cast_expression
| '&' meta_cast_expression
| '+' meta_cast_expression
| '-' meta_cast_expression
| '!' meta_cast_expression
| '~' meta_cast_expression
| SIZEOF unary_expression
meta_cast_expression::= meta_unary_expression
meta_pm_expression::= meta_cast_expression
meta_multiplicative_expression::= meta_pm_expression
| meta_multiplicative_expression star_ptr_operator meta_pm_expression
| meta_multiplicative_expression '/' meta_pm_expression
| meta_multiplicative_expression '%' meta_pm_expression
meta_additive_expression::= meta_multiplicative_expression
| meta_additive_expression '+' meta_multiplicative_expression
| meta_additive_expression '-' meta_multiplicative_expression
meta_shift_expression::= meta_additive_expression
| meta_shift_expression SHL meta_additive_expression
| meta_shift_expression SHR meta_additive_expression
meta_relational_expression::= meta_shift_expression
| meta_relational_expression '<' meta_shift_expression
| meta_relational_expression '>' meta_shift_expression
| meta_relational_expression LE meta_shift_expression
| meta_relational_expression GE meta_shift_expression
meta_equality_expression::= meta_relational_expression
| meta_equality_expression EQ meta_relational_expression
| meta_equality_expression NE meta_relational_expression
meta_and_expression::= meta_equality_expression
| meta_and_expression '&' meta_equality_expression
meta_exclusive_or_expression::= meta_and_expression
| meta_exclusive_or_expression '^' meta_and_expression
meta_inclusive_or_expression::= meta_exclusive_or_expression
| meta_inclusive_or_expression '|' meta_exclusive_or_expression
meta_logical_and_expression::= meta_inclusive_or_expression
| meta_logical_and_expression LOG_AND meta_inclusive_or_expression
meta_logical_or_expression::= meta_logical_and_expression
| meta_logical_or_expression LOG_OR meta_logical_and_expression
meta_conditional_expression::= meta_logical_or_expression
| meta_logical_or_expression '?' meta_conditional_expression ':' meta_conditional_expression
meta_expression_statement::= meta_conditional_expression semi
| meta_primary_head object_statements_clause semi
| meta_class_key meta_nested_id object_statements_clause semi
| meta_postfix_expression '(' tree_argument_list.opt ')' object_statements_clause semi
| meta_postfix_expression '[' ']' object_statements_clause semi
| meta_postfix_expression '[' expression ']' object_statements_clause semi
| meta_logical_or_expression assignment_operator line tree_statement
| CONST meta_expression_statement
| STATIC meta_expression_statement
| '!' STATIC meta_expression_statement
/*---------------------------------------------------------------------------------------------------
* A 18 Syntax macros
*---------------------------------------------------------------------------------------------------/*/
syntax_macro_definition::= EXPLICIT AUTO meta_type identifier '(' syntax_macro_parameter_list ')' compound_tree_statement
| EXPLICIT AUTO meta_type identifier '(' syntax_macro_parameter_list ')' '[' ']' compound_tree_statement
| EXPLICIT AUTO meta_type identifier '(' ')' compound_tree_statement
| EXPLICIT AUTO meta_type identifier '(' ')' '[' ']' compound_tree_statement
syntax_macro_parameter_list::= syntax_macro_parameter
| syntax_macro_parameter_list ',' syntax_macro_parameter
syntax_macro_parameter::= meta_type identifier
| meta_type identifier '[' ']'
| identifier
| reserved_id
| token.punct
| ';'
| ','
| '{'
| '}'
| '('
| ')'
| bang error
/*---------------------------------------------------------------------------------------------------
* A 19 files
*---------------------------------------------------------------------------------------------------/*/
include_declaration::= USING string
| USING '/' INCLUDE string_expr
| USING '/' INCLUDE '/' utility string_expr
| USING '/' utility string_expr
utility::= EMIT
| FROZEN
| POOL
| UTILITY
file_dependency_declaration::= using_implementation semi
| using_interface semi
using_implementation::= USING '/' IMPLEMENTATION file_use
| USING '/' IMPLEMENTATION '=' file_use
using_interface::= USING '/' INTERFACE file_use
| USING '/' INTERFACE '=' file_use
file_use::= file_id
| file_entity
file_placement_declaration::= export_implementation semi
| export_interface semi
| export_all semi
| EXPORT '/' NOIMPLEMENTATION semi
| EXPORT '/' UTILITY semi
export_implementation::= EXPORT '/' IMPLEMENTATION implementation_file
| EXPORT '/' IMPLEMENTATION '=' implementation_file
export_interface::= EXPORT '/' INTERFACE interface_file
| EXPORT '/' INTERFACE '=' interface_file
export_all::= EXPORT '/' ALL interface_file
| EXPORT '/' ALL '=' interface_file
implementation_file::= file_id
| file_entity
interface_file::= file_id
| file_entity
file_name::= string
| file_name '/' INTERFACE
| file_name '/' IMPLEMENTATION
| file_name '/' TEMPLATE
| file_name '/' utility
| file_name '/' GUARD '=' string_expr
| file_name '/' NOGUARD
| file_name '/' PATH '=' string_expr
| file_name '/' PREFIX '=' string_expr
| file_name '/' SUFFIX '=' string_expr
file_entity::= declarator_id
| elaborated_type_specifier
| NAMESPACE scoped_id
file_id::= file_name
| file_entity '/' IMPLEMENTATION
| file_entity '/' INTERFACE
file_id_list::= file_id
| file_id_list ',' file_id
filespace_specifier::= NAMESPACE '/' FILE file_name compound_declaration
/*---------------------------------------------------------------------------------------------------
* Error handling aids
*---------------------------------------------------------------------------------------------------/*/
ecarb::= '}'
| '#'
| bang error '}'
| bang error ')'
| bang error '#'
semi::= ';'
| '#'
| bang error_semi
error_ecarb::= error '}'
| error '#'
error_semi::= error ';'
| error '#'
/*---------------------------------------------------------------------------------------------------
* Back-tracking and context support
*---------------------------------------------------------------------------------------------------/*/
advance_search::= error /* Rewind and queue '+' or '-' '#' /*/
bang::= /* empty /*/ /* set flag to suppress "parse error" /*/
line::= /* empty /*/ /* Get current line context /*/
mark::= /* empty /*/ /* Push lookahead and input token stream context onto a stack /*/
nest::= /* empty /*/ /* Push a declaration nesting depth onto the parse stack /*/
start_search::= /* empty /*/ /* Create/reset binary search context /*/
start_search1::= /* empty /*/ /* Create/reset binary search context /*/
util::= /* empty /*/ /* Get current utility mode /*/
/*StartDiscard/*/
// Tokens
SCOPE ::= "::"
ELLIPSIS ::= "..."
SHL ::= "<<"
SHR ::= ">>"
EQ ::= "=="
NE ::= "!="
LE ::= "<="
GE ::= ">="
LOG_AND ::= "&&"
LOG_OR ::= "||"
INC ::= "++"
DEC ::= "--"
ARROW_STAR ::= "->*"
ARROW ::= "->"
DOT_STAR ::= ".*"
ASS_ADD ::= "+="
ASS_SUB ::= "-="
ASS_MUL ::= "*="
ASS_DIV ::= "/="
ASS_MOD ::= "%="
ASS_XOR ::= "^="
ASS_AND ::= "&="
ASS_OR ::= "|="
ASS_SHR ::= ">>="
ASS_SHL ::= "<<="
HASH_BLANK ::= "# "
HASH_DEFINE ::= "#define"
HASH_ELIF ::= "#elif"
HASH_ELSE ::= "#else"
HASH_ENDIF ::= "#endif"
HASH_ERROR ::= "#error"
HASH_IF ::= "#if"
HASH_IFDEF ::= "#ifdef"
HASH_IFNDEF ::= "#ifndef"
HASH_INCLUDE ::= "#include"
HASH_LINE ::= "#line"
HASH_PRAGMA ::= "#pragma"
HASH_UNDEF ::= "#undef"
//
HASH_HASH ::= "##"
DI_HASH_HASH ::= "%:%:"
DI_HASH ::= "%:"
DI_SQUARE ::= "<:"
DI_ERAUQS ::= ":>"
DI_ECARB ::= "%>"
//
DEFINED ::= "-DEFINED-"
DO_FUNCTION ::= "-DO_FUNCTION-"
//
// BANG ::= "-BANG-"
ERROR ::= "-ERROR-"
NIL ::= "-NIL-"
// RAMMARG ::= "-RAMMARG-"
//
ASM ::= "asm"
BREAK ::= "break"
CASE ::= "case"
CATCH ::= "catch"
CONST_CAST ::= "const_cast"
CONTINUE ::= "continue"
DEFAULT ::= "default"
DELETE ::= "delete"
DO ::= "do"
DYNAMIC_CAST ::= "dynamic_cast"
ELSE ::= "else"
FALSE ::= "false"
FOR ::= "for"
GOTO ::= "goto"
IF ::= "if"
NEW ::= "new"
OPERATOR ::= "operator"
REINTERPRET_CAST ::= "reinterpret_cast"
RETURN ::= "return"
SIZEOF ::= "sizeof"
STATIC_CAST ::= "static_cast"
SWITCH ::= "switch"
THIS ::= "this"
THROW ::= "throw"
TRUE ::= "true"
TRY ::= "try"
TYPEID ::= "typeid"
WHILE ::= "while"
//
LOG_AND ::= "and"
ASS_AND ::= "and_eq"
NE ::= "not_eq"
LOG_OR ::= "or"
ASS_OR ::= "or_eq"
ASS_XOR ::= "xor_eq"
//
//character('&') ::= "bitand"
//character('|') ::= "bitor"
//character('~') ::= "compl"
//character('!') ::= "not"
//character('^') ::= "xor"
DERIVED ::= "derived"
FILE ::= "file"
GUARD ::= "guard"
ALL ::= "all"
IMPLEMENTATION ::= "implementation"
INCLUDE ::= "include"
INTERFACE ::= "interface"
NOGUARD ::= "noguard"
NOIMPLEMENTATION ::= "noimplementation"
PATH ::= "path"
PREFIX ::= "prefix"
PURE ::= "pure"
SUFFIX ::= "suffix"
AUTO ::= "auto"
PRIVATE ::= "private"
PROTECTED ::= "protected"
PUBLIC ::= "public"
CONST ::= "const"
VOLATILE ::= "volatile"
EXPLICIT ::= "explicit"
EXPORT ::= "export"
EXTERN ::= "extern"
FRIEND ::= "friend"
MUTABLE ::= "mutable"
REGISTER ::= "register"
TEMPLATE ::= "template"
TYPEDEF ::= "typedef"
USING ::= "using"
INLINE ::= "inline"
ENTRY ::= "entry"
PRE ::= "pre"
// CONSTRUCT ::= "construct"
BODY ::= "body"
// DESTRUCT ::= "destruct"
POST ::= "post"
EXIT ::= "exit"
STATIC ::= "static"
CLASS ::= "class"
ENUM ::= "enum"
NAMESPACE ::= "namespace"
STRUCT ::= "struct"
TYPENAME ::= "typename"
UNION ::= "union"
EMIT ::= "emit"
FROZEN ::= "frozen"
POOL ::= "pool"
UTILITY ::= "utility"
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels