C Declaration

Here the declaration grammar:

        translation_unit = [
            @ignore("C/C++")
            [
                __scope__:current_block
                #new_root(_, current_block)
                [
                    declaration
                ]*
            ]
            Base.eof
        ]

        declaration = [
            ';' // garbage single comma
            |
            c_decl
            |
            preproc_decl
            |
            asm_decl
        ]

        preproc_decl = [
            ['#' preproc_directive ]:decl
            #raw_decl(decl)
            #end_decl(current_block, decl)
        ]

        asm_decl = [
            [
            Base.id:i
            #check_asm(i)
            [
                Base.id:i
                #check_quali(i)
            ]?
            attr_asm_decl_follow
            ';'?
            ]:decl
            #raw_decl(decl)
            #end_decl(current_block, decl)
        ]

        attr_asm_decl = [
            [
                Base.id:i
                #check_asmattr(i)
                attr_asm_decl_follow
            ]
        ]

        attr_asm_decl_follow = [
            '(' dummy_with_paren* ')'
            | '{' dummy_with_brace* '}'
            | '__extension__'
        ]

        c_decl = [
            __scope__:local_specifier
            #create_ctype(local_specifier)
            declaration_specifier*:dsp
            init_declarator:decl
            #not_empty(current_block, dsp, decl)
            #end_decl(current_block, decl)
            [
                ','
                #copy_ctype(local_specifier, decl)
                init_declarator:decl
                #end_decl(current_block, decl)
            ]*
            [
                ';'
                |
                Statement.compound_statement:b
                #add_body(decl, b)
            ]
        ]

        declaration_specifier = [
            Base.id:i
            #new_decl_spec(local_specifier, i, current_block)
            [
                #is_composed(local_specifier)
                composed_type_specifier
                |
                #is_enum(local_specifier)
                enum_specifier
                |
                #is_typeof(i)
                typeof_expr
            ]?
            |
            attr_asm_decl:attr
            #add_attr_specifier(local_specifier, attr)
        ]

        type_qualifier = [
            Base.id:i
            #add_qual(local_specifier, i)
            |
            attr_asm_decl:attr
            #add_attr_specifier(local_specifier, attr)
        ]

        name_of_composed_type = [ Base.id ]
        composed_type_specifier = [
            [
                attr_asm_decl:attr
                #add_attr_composed(local_specifier, attr)
            ]?
            name_of_composed_type?:n
            composed_fields?:body
            #add_composed(local_specifier, n, body)
        ]

        composed_fields = [
            '{'
                __scope__:current_block
                #new_composed(_, current_block)
                declaration*
            '}'
        ]

        enum_name = [ Base.id ]
        enum_specifier = [
            enum_name?:n
            enumerator_list?:body
            #add_enum(local_specifier, n, body)
        ]

        enumerator_list = [
            '{'
                enumerator:e
                #add_enumerator(_, e)
                [
                    ',' enumerator:e
                    #add_enumerator(_, e)
                ]*
                ','? // trailing comma
            '}'
        ]

        enumerator = [
            identifier:i
            __scope__:c
            ['=' constant_expression:>c]?
            #new_enumerator(_, i, c)
        ]

        typeof_expr = [
            // TODO: split inside typeof
            ['('
                [
                    type_name !!')'
                    | expression
                ]
            ')']:tof
            #add_typeof(local_specifier, tof)
        ]

        init_declarator = [
            declarator:>_
            [
                ':'
                constant_expression:cexpr
                #colon_expr(_, cexpr)
            ]?
            [
                attr_asm_decl:attr
                #add_attr_decl(_, attr)
            ]*
            [
                '='
                initializer:aexpr
                #assign_expr(_, aexpr)
            ]?
            !![','|';'|'{']
        ]

        declarator = [
            [
                "*"
                #first_pointer(local_specifier)
                declarator_recurs:>_
                |
                absolute_declarator:>_
            ]
            #commit_declarator(_, local_specifier)
        ]

        declarator_recurs = [
            pointer absolute_declarator:>_
        ]

        pointer = [
            [
                "*" #add_pointer(local_specifier)
                | type_qualifier
            ]*
        ]

        f_or_v_id = [ identifier ]
        absolute_declarator = [
                [
                    '('
                        #add_paren(local_specifier)
                        type_qualifier?
                        declarator_recurs:>_
                        #close_paren(local_specifier)
                    ')'
                    |
                    f_or_v_id?:name
                    #name_absdecl(local_specifier, name)
                ]
                direct_absolute_declarator?
        ]

        direct_absolute_declarator = [
            [
                '['
                    // TODO: handle c99 qual for trees
                    "static"?
                    ["const"|"volatile"]?
                    "static"?
                    __scope__:expr
                    [
                        assignement_expression:>expr
                        | '*':star #new_raw(expr, star)
                    ]?
                    #add_ary(local_specifier, expr)
                ']'
            ]+
            |
                '('
                #open_params(local_specifier)
                [
                    //kr_parameter_type_list
                    //|
                    parameter_type_list
                ]?
                ')'
            /*
            [ // K&R STYLE
                !![';'|','|'{'|'('|')']
                | declaration*
            ]
            */
        ]

        kr_parameter_type_list = [
            identifier [',' identifier]* !!')'
        ]

        parameter_type_list = [
            [type_name ';']*
            [
                parameter_list
            ]?
            ','?
            ["..." #add_ellipsis(local_specifier)]?
        ]

        parameter_list = [
            parameter_declaration:p
            #add_param(local_specifier, p)
            [','
                parameter_declaration:p
                #add_param(local_specifier, p)
            ]*
        ]

        parameter_declaration = [ type_name:>_ ]

        initializer = [ [ initializer_block | assignement_expression ]:>_ ]

        initializer_block = [
            '{'
                __scope__:init_list
                #new_blockinit(init_list)
                [initializer_list]?
                ','? // trailing comma
                #bind('_', init_list)
            '}'
        ]

        initializer_list = [
            designation?:dsign
            initializer:init
            #add_init(init_list, init, dsign)
            [
                ','
                designation?:dsign
                initializer:init
                #add_init(init_list, init, dsign)
            ]*
        ]

        designation = [
            designation_list+ '='?
            | identifier ':'
        ]

        designation_list = [
            '['
                range_expression
            ']'
            | dot identifier
        ]

        type_name = [
            __scope__:local_specifier
            #create_ctype(local_specifier)
            declaration_specifier+ declarator:>_
        ]

        ///////// OVERLOAD OF STATEMENT
        // add declaration in block
        line_of_code = [
                    declaration
                |
                    single_statement:line
                    #end_loc(current_block, line)
        ]

        for_statement = [
            '('
                __scope__:init
                [
                    expression_statement:>init
                |
                    __scope__:current_block
                    #for_decl_begin(current_block)
                    declaration
                    #for_decl_end(init, current_block)
                ]
                expression_statement:cond
                expression?:inc
            ')'
            single_statement:body
            #new_for(_, init, cond, inc, body)
        ]

        ///////// OVERLOAD OF EXPRESSION
        // add cast / sizeof
        unary_expression = [
            // CAST
            '(' type_name:t ')'
            [
                // simple cast
                unary_expression
                |
                // compound literal
                initializer_block
            ]:>_
            #to_cast(_, t)
            | // SIZEOF
            Base.id:i #sizeof(i)
            __scope__:n
            [
                '(' type_name:>n ')'
                | Expression.unary_expression:>n
            ]
            #new_sizeof(_, i, n)
            | Expression.unary_expression:>_
        ]

        // ({}) and __builtin_offsetof
        primary_expression = [
            "({"
                __scope__:current_block
                #new_blockexpr(_, current_block)
                [
                    line_of_code
                ]*
            "})"
            | // TODO: create special node for that
                "__builtin_offsetof"
                '(' [type_name ',' postfix_expression]:bof ')'
                #new_builtoffset(_, bof)
            |
            Expression.primary_expression:>_
        ]
class cnorm.parsing.declaration.Declaration(content: str='', stream_name: str=None, raise_diagnostic=True)[source]

Bases: pyrser.grammar.Grammar

interaction with other CNORM PART:

entry = 'translation_unit'

entry point for C programming language

add_ary(self, lspec, expr)
add_attr_composed(self, lspec, attrspec)
add_attr_decl(self, lspec, attrspec)
add_attr_specifier(self, lspec, attrspec)
add_body(self, ast, body)
add_composed(self, lspec, n, block)
add_ellipsis(self, lspec)
add_enum(self, lspec, n, block)
add_enumerator(self, ast, enum)
add_init(self, ast, expr, designation)
add_param(self, lspec, param)
add_paren(self, lspec)
add_pointer(self, lspec)
add_qual(self, lspec, qualspec)
add_typeof(self, lspec, tof)
assign_expr(self, ast, expr)
check_asm(self, ident)
check_asmattr(self, ident)
check_quali(self, ident)
close_paren(self, lspec)
colon_expr(self, ast, expr)
commit_declarator(self, ast, lspec)
copy_ctype(self, lspec, previous)
create_ctype(self, lspec)
end_decl(self, current_block, ast)
first_pointer(self, lspec)
for_decl_begin(self, current_block)
for_decl_end(self, init, current_block)
is_composed(self, lspec)
is_enum(self, lspec)
is_typeof(self, i)
name_absdecl(self, ast, ident)
new_blockexpr(self, ast, current_block)
new_blockinit(self, init_list)
new_builtoffset(self, ast, bof)
new_composed(self, ast, current_block)
new_decl_spec(self, lspec, i, current_block)
new_enumerator(self, ast, ident, constexpr)
new_root(self, ast, current_block)
new_sizeof(self, ast, i, n)
not_empty(self, current_block, dsp, decl)
open_params(self, lspec)
preproc_directive(self) → bool

Consume a preproc directive.

raw_decl(self, decl)
sizeof(self, ident)
to_cast(self, ast, typename)
cnorm.parsing.declaration.check_asm(self, ident)[source]
cnorm.parsing.declaration.check_quali(self, ident)[source]
cnorm.parsing.declaration.check_asmattr(self, ident)[source]
cnorm.parsing.declaration.new_root(self, ast, current_block)[source]
cnorm.parsing.declaration.preproc_directive(self) → bool[source]

Consume a preproc directive.

cnorm.parsing.declaration.raw_decl(self, decl)[source]
cnorm.parsing.declaration.create_ctype(self, lspec)[source]
cnorm.parsing.declaration.copy_ctype(self, lspec, previous)[source]
cnorm.parsing.declaration.new_decl_spec(self, lspec, i, current_block)[source]
cnorm.parsing.declaration.add_body(self, ast, body)[source]
cnorm.parsing.declaration.end_decl(self, current_block, ast)[source]
cnorm.parsing.declaration.not_empty(self, current_block, dsp, decl)[source]
cnorm.parsing.declaration.colon_expr(self, ast, expr)[source]
cnorm.parsing.declaration.assign_expr(self, ast, expr)[source]
cnorm.parsing.declaration.is_composed(self, lspec)[source]
cnorm.parsing.declaration.is_enum(self, lspec)[source]
cnorm.parsing.declaration.is_typeof(self, i)[source]
cnorm.parsing.declaration.add_typeof(self, lspec, tof)[source]
cnorm.parsing.declaration.add_qual(self, lspec, qualspec)[source]
cnorm.parsing.declaration.add_attr_specifier(self, lspec, attrspec)[source]
cnorm.parsing.declaration.add_attr_composed(self, lspec, attrspec)[source]
cnorm.parsing.declaration.add_attr_decl(self, lspec, attrspec)[source]
cnorm.parsing.declaration.add_composed(self, lspec, n, block)[source]
cnorm.parsing.declaration.add_enum(self, lspec, n, block)[source]
cnorm.parsing.declaration.add_enumerator(self, ast, enum)[source]
cnorm.parsing.declaration.new_enumerator(self, ast, ident, constexpr)[source]
cnorm.parsing.declaration.new_composed(self, ast, current_block)[source]
cnorm.parsing.declaration.first_pointer(self, lspec)[source]
cnorm.parsing.declaration.commit_declarator(self, ast, lspec)[source]
cnorm.parsing.declaration.add_pointer(self, lspec)[source]
cnorm.parsing.declaration.add_paren(self, lspec)[source]
cnorm.parsing.declaration.add_ary(self, lspec, expr)[source]
cnorm.parsing.declaration.name_absdecl(self, ast, ident)[source]
cnorm.parsing.declaration.close_paren(self, lspec)[source]
cnorm.parsing.declaration.open_params(self, lspec)[source]
cnorm.parsing.declaration.add_param(self, lspec, param)[source]
cnorm.parsing.declaration.add_ellipsis(self, lspec)[source]
cnorm.parsing.declaration.new_blockinit(self, init_list)[source]
cnorm.parsing.declaration.new_blockexpr(self, ast, current_block)[source]
cnorm.parsing.declaration.add_init(self, ast, expr, designation)[source]
cnorm.parsing.declaration.for_decl_begin(self, current_block)[source]
cnorm.parsing.declaration.for_decl_end(self, init, current_block)[source]
cnorm.parsing.declaration.to_cast(self, ast, typename)[source]
cnorm.parsing.declaration.sizeof(self, ident)[source]
cnorm.parsing.declaration.new_sizeof(self, ast, i, n)[source]
cnorm.parsing.declaration.new_builtoffset(self, ast, bof)[source]