📄 cpp5.y
字号:
deallocation_expression
| point_member_expression DOTstar deallocation_expression
| point_member_expression ARROWstar deallocation_expression
;
multiplicative_expression:
point_member_expression
| multiplicative_expression '*' point_member_expression
| multiplicative_expression '/' point_member_expression
| multiplicative_expression '%' point_member_expression
;
additive_expression:
multiplicative_expression
| additive_expression '+' multiplicative_expression
| additive_expression '-' multiplicative_expression
;
shift_expression:
additive_expression
| shift_expression LS additive_expression
| shift_expression RS 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 ANDAND inclusive_OR_expression
;
logical_OR_expression:
logical_AND_expression
| logical_OR_expression OROR logical_AND_expression
;
conditional_expression:
logical_OR_expression
| logical_OR_expression '?' comma_expression ':'
conditional_expression
;
assignment_expression:
conditional_expression
| unary_expression assignment_operator assignment_expression
;
assignment_operator:
'='
| MULTassign
| DIVassign
| MODassign
| PLUSassign
| MINUSassign
| LSassign
| RSassign
| ANDassign
| ERassign
| ORassign
;
comma_expression:
assignment_expression
| comma_expression ',' assignment_expression
;
constant_expression:
conditional_expression
;
/* The following was used for clarity */
comma_expression_opt:
/* Nothing */
| comma_expression
;
/******************************* DECLARATIONS *********************************/
/* The following are notably different from the ANSI C Standard
specified grammar, but are present in my ANSI C compatible
grammar. The changes were made to disambiguate typedefs presence
in declaration_specifiers (vs. in the declarator for
redefinition); to allow struct/union/enum/class tag declarations
without declarators, and to better reflect the parsing of
declarations (declarators must be combined with
declaration_specifiers ASAP, so that they can immediately become
visible in the current scope). */
declaration:
declaring_list ';'
| default_declaring_list ';'
| sue_declaration_specifier ';' { /* this is constraint error, as it
includes a storage class!?!*/ }
| sue_type_specifier ';'
| sue_type_specifier_elaboration ';'
;
/* Note that if a typedef were redeclared, then a declaration
specifier must be supplied (re: ANSI C spec). The following are
declarations wherein no declaration_specifier is supplied, and
hence the 'default' must be used. An example of this is
const a;
which by default, is the same as:
const int a;
`a' must NOT be a typedef in the above example. */
/* The presence of `{}' in the following rules indicates points
at which the symbol table MUST be updated so that the tokenizer
can IMMEDIATELY continue to maintain the proper distinction
between a TYPEDEFname and an IDENTIFIER. */
default_declaring_list: /* Can't redeclare typedef names */
declaration_qualifier_list identifier_declarator {} initializer_opt
| type_qualifier_list identifier_declarator {} initializer_opt
| default_declaring_list ',' identifier_declarator {} initializer_opt
| declaration_qualifier_list constructed_identifier_declarator
| type_qualifier_list constructed_identifier_declarator
| default_declaring_list ',' constructed_identifier_declarator
;
/* Note how type_qualifier_list is NOT used in the following
productions. Qualifiers are NOT sufficient to redefine
typedef-names (as prescribed by the ANSI C standard).*/
declaring_list:
declaration_specifier declarator {} initializer_opt
| type_specifier declarator {} initializer_opt
| basic_type_name declarator {} initializer_opt
| TYPEDEFname declarator {} initializer_opt
| global_or_scoped_typedefname declarator {} initializer_opt
| declaring_list ',' declarator {} initializer_opt
| declaration_specifier constructed_declarator
| type_specifier constructed_declarator
| basic_type_name constructed_declarator
| TYPEDEFname constructed_declarator
| global_or_scoped_typedefname constructed_declarator
| declaring_list ',' constructed_declarator
;
/* Declarators with parenthesized initializers present a big
problem. Typically a declarator that looks like: "*a(...)" is
supposed to bind FIRST to the "(...)", and then to the "*". This
binding presumes that the "(...)" stuff is a prototype. With
constructed declarators, we must (officially) finish the binding
to the "*" (finishing forming a good declarator) and THEN connect
with the argument list. Unfortunately, by the time we realize it
is an argument list (and not a prototype) we have pushed the
separate declarator tokens "*" and "a" onto the yacc stack
WITHOUT combining them. The solution is to use odd productions to
carry the incomplete declarator along with the "argument
expression list" back up the yacc stack. We would then actually
instantiate the symbol table after we have fully decorated the
symbol with all the leading "*" stuff. Actually, since we don't
have all the type information in one spot till we reduce to a
declaring_list, this delay is not a problem. Note that ordinary
initializers REQUIRE (ANSI C Standard) that the symbol be placed
into the symbol table BEFORE its initializer is read, but in the
case of parenthesized initializers, this is not possible (we
don't even know we have an initializer till have passed the
opening "(". ) */
constructed_declarator:
nonunary_constructed_identifier_declarator
| constructed_paren_typedef_declarator
| simple_paren_typedef_declarator '(' argument_expression_list ')'
| simple_paren_typedef_declarator postfixing_abstract_declarator
'(' argument_expression_list ')' /* constraint error */
| constructed_parameter_typedef_declarator
| asterisk_or_ampersand constructed_declarator
| unary_modifier constructed_declarator
;
constructed_paren_typedef_declarator:
'(' paren_typedef_declarator ')'
'(' argument_expression_list ')'
| '(' paren_typedef_declarator ')' postfixing_abstract_declarator
'(' argument_expression_list ')'
| '(' simple_paren_typedef_declarator postfixing_abstract_declarator ')'
'(' argument_expression_list ')'
| '(' TYPEDEFname postfixing_abstract_declarator ')'
'(' argument_expression_list ')'
;
constructed_parameter_typedef_declarator:
TYPEDEFname '(' argument_expression_list ')'
| TYPEDEFname postfixing_abstract_declarator
'(' argument_expression_list ')' /* constraint error */
| '(' clean_typedef_declarator ')'
'(' argument_expression_list ')'
| '(' clean_typedef_declarator ')' postfixing_abstract_declarator
'(' argument_expression_list ')'
;
constructed_identifier_declarator:
nonunary_constructed_identifier_declarator
| asterisk_or_ampersand constructed_identifier_declarator
| unary_modifier constructed_identifier_declarator
;
/* The following are restricted to NOT begin with any pointer
operators. This includes both "*" and "T::*" modifiers. Aside
from this restriction, the following would have been:
identifier_declarator '(' argument_expression_list ')' */
nonunary_constructed_identifier_declarator:
paren_identifier_declarator '(' argument_expression_list ')'
| paren_identifier_declarator postfixing_abstract_declarator
'(' argument_expression_list ')' /* constraint error*/
| '(' unary_identifier_declarator ')'
'(' argument_expression_list ')'
| '(' unary_identifier_declarator ')' postfixing_abstract_declarator
'(' argument_expression_list ')'
;
declaration_specifier:
basic_declaration_specifier /* Arithmetic or void */
| sue_declaration_specifier /* struct/union/enum/class */
| typedef_declaration_specifier /* typedef*/
;
type_specifier:
basic_type_specifier /* Arithmetic or void */
| sue_type_specifier /* Struct/Union/Enum/Class */
| sue_type_specifier_elaboration /* elaborated Struct/Union/Enum/Class */
| typedef_type_specifier /* Typedef */
;
declaration_qualifier_list: /* storage class and optional const/volatile */
storage_class
| type_qualifier_list storage_class
| declaration_qualifier_list declaration_qualifier
;
type_qualifier_list:
type_qualifier
| type_qualifier_list type_qualifier
;
declaration_qualifier:
storage_class
| type_qualifier /* const or volatile */
;
type_qualifier:
CONST
| VOLATILE
;
basic_declaration_specifier: /*Storage Class+Arithmetic or void*/
declaration_qualifier_list basic_type_name
| basic_type_specifier storage_class
| basic_type_name storage_class
| basic_declaration_specifier declaration_qualifier
| basic_declaration_specifier basic_type_name
;
basic_type_specifier:
type_qualifier_list basic_type_name /* Arithmetic or void */
| basic_type_name basic_type_name
| basic_type_name type_qualifier
| basic_type_specifier type_qualifier
| basic_type_specifier basic_type_name
;
sue_declaration_specifier: /* Storage Class + struct/union/enum/class */
declaration_qualifier_list elaborated_type_name
| declaration_qualifier_list elaborated_type_name_elaboration
| sue_type_specifier storage_class
| sue_type_specifier_elaboration storage_class
| sue_declaration_specifier declaration_qualifier
;
sue_type_specifier_elaboration:
elaborated_type_name_elaboration /* elaborated struct/union/enum/class */
| type_qualifier_list elaborated_type_name_elaboration
| sue_type_specifier_elaboration type_qualifier
;
sue_type_specifier:
elaborated_type_name /* struct/union/enum/class */
| type_qualifier_list elaborated_type_name
| sue_type_specifier type_qualifier
;
typedef_declaration_specifier: /*Storage Class + typedef types */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -