aboutsummaryrefslogblamecommitdiff
path: root/cibic.y
blob: 0a9809771d8677320d4a4d83591bf293dbfd3a69 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                  
                
  





                        



                                                                                         
                                                                                     
              

                                  

                                                                                                                                                               
                                                                                                                                                                                                                                                           
                                                                                                                                                                                                                                                                                                                                                                               

                                                                                                                           
  
       
                                                                           





                                                                       

           


                                                                                     


                                                                      


                                                                             
                                                                        

                                                                  
                                                                                        



                       
                                                                          


                
                                                                    


                     
                                                                              










                                                                           
                                                                           










                                                                                                                      
                                                                    
            


                                                                        








                                                                         





                                                                                                






















                                                                                                     

                                                                               



                                  
                                                                


                                  
                                                              

























                                                                               























                                                                                                          


                                                           


                             


                                                              


                             


                                                           


                       


                                                  


                         


                                              

                   



                                                                   






                             


                                                                  








                             


                                                           






                               


                                                                       






                         


                                                                         







                       


                                                   


























                                                                                   



                                                                           
                                                                                          
     






                                                                       
                                                                             









                                                      
  

              





                      

                 
                 
                 
                                       



                                          

            
                              
               

             
%{
#include <stdio.h>
#include "ast.h"
%}
%union {
    int intval;
    char *strval;
    struct CNode *cnode;
}

%token IDENTIFIER INT_CONST CHAR_CONST STR_CONST
%token KW_VOID KW_CHAR KW_INT KW_STRUCT KW_UNION KW_IF KW_ELSE KW_WHILE
%token KW_FOR KW_CONT KW_BREAK KW_RET KW_SIZEOF
%token OPT_OR OPT_AND OPT_EQ OPT_NE OPT_LE OPT_GE OPT_SHL OPT_SHR OPT_INC OPT_DEC OPT_PTR
%token ASS_MUL ASS_DIV ASS_MOD ASS_ADD ASS_SUB ASS_SHL ASS_SHR ASS_AND ASS_XOR ASS_OR
%token UNKNOWN
%type<intval> INT_CONST CHAR_CONST
%type<strval> IDENTIFIER STR_CONST
%type<intval> assignment_operator equality_operator relational_operator shift_operator additive_operator multiplicative_operator unary_operator struct_or_union
%type<cnode> expression assignment_expression constant_expression
%type<cnode> logical_or_expression logical_and_expression inclusive_or_expression exclusive_or_expression and_expression equality_expression relational_expression shift_expression additive_expression multiplicative_expression cast_expression type_name
%type<cnode> unary_expression postfix_expression identifier primary_expression arguments postfix type_specifier program declaration function_definition parameters declarators init_declarators init_declarator initializer array_initializer struct_fields struct_field plain_declaration  declarator_array plain_declarator expression_statement compound_statement statement
%type<cnode> comp_decls comp_stmts selection_statement iteration_statement jump_statement optional_exp declarator prog_list
%start program
%%
program
    : prog_list { ast_root = cnode_create_ast(cnode_list_wrap(PROG, $1)); }

prog_list
    : declaration
    | function_definition
    | prog_list declaration         { $$ = cnode_list_append($1, $2); }
    | prog_list function_definition { $$ = cnode_list_append($1, $2); }

declaration
    : type_specifier ';' {
        $$ = cnode_create_decl($1, cnode_list_wrap(INIT_DECLRS, cnode_create_nop()));
    }
    | type_specifier init_declarators ';' { 
        $$ = cnode_create_decl($1, cnode_list_wrap(INIT_DECLRS, $2)); 
    }

function_definition
    : type_specifier plain_declarator '(' parameters ')' compound_statement {
        $$ = cnode_create_func($1, $2, cnode_list_wrap(PARAMS, $4), $6);
    }
    | type_specifier plain_declarator '(' ')' compound_statement {
        $$ = cnode_create_func($1, $2, cnode_list_wrap(PARAMS, cnode_create_nop()), $5);
    }

parameters
    : plain_declaration
    | parameters ',' plain_declaration { $$ = cnode_list_append($1, $3); }

declarators
    : declarator
    | declarators ',' declarator { $$ = cnode_list_append($1, $3); }

init_declarators
    : init_declarator
    | init_declarators ',' init_declarator { $$ = cnode_list_append($1, $3); }

init_declarator
    : declarator { $$ = cnode_create_init_declr($1, cnode_create_nop()); }
    | declarator '=' initializer { $$ = cnode_create_init_declr($1, $3); }

initializer
    : assignment_expression { $$ = cnode_create_initr(INITR_NORM, $1); }
    | '{' array_initializer '}' { $$ = cnode_create_initr(INITR_ARR, $2); }

array_initializer
    : initializer
    | array_initializer ',' initializer { $$ = cnode_list_append($1, $3); }

type_specifier
    : KW_VOID { $$ = cnode_create_type_spec(KW_VOID, 0); }
    | KW_CHAR { $$ = cnode_create_type_spec(KW_CHAR, 0); }
    | KW_INT { $$ = cnode_create_type_spec(KW_INT, 0); }
    | struct_or_union identifier '{' struct_fields '}' { $$ = cnode_create_type_spec($1, 2, $2, $4); }
    | struct_or_union '{' struct_fields '}'            { $$ = cnode_create_type_spec($1, 2, cnode_create_nop(), $3); }
    | struct_or_union identifier                { $$ = cnode_create_type_spec($1, 2, $2, cnode_create_nop()); }

struct_fields
    : struct_field
    | struct_fields struct_field { $$ = cnode_list_append($1, $2); }
struct_field
    : type_specifier declarators ';' { 
        $$ = cnode_create_struct_field($1, cnode_list_wrap(DECLRS, $2));
    }

struct_or_union
    : KW_STRUCT { $$ = KW_STRUCT; }
    | KW_UNION { $$ = KW_UNION; }

plain_declaration
    : type_specifier declarator { $$ = cnode_create_plain_decl($1, $2); }

declarator
    : plain_declarator '(' ')' { 
        $$ = cnode_create_declr(DECLR_FUNC, 2, $1, cnode_list_wrap(PARAMS, cnode_create_nop()));
    }
    | plain_declarator '(' parameters ')' {
        $$ = cnode_create_declr(DECLR_FUNC, 2, $1, cnode_list_wrap(PARAMS, $3));
    }
    | declarator_array

declarator_array
    : plain_declarator
    | declarator_array '[' constant_expression ']' { $$ = cnode_create_declr(DECLR_ARR, 2, $1, $3); }

plain_declarator
    : identifier
    | '*' plain_declarator { $$ = cnode_create_declr('*', 1, $2); }

statement
    : expression_statement
    | compound_statement
    | selection_statement
    | iteration_statement
    | jump_statement

expression_statement
    : ';'               { $$ = cnode_create_stmt(STMT_EXP, 1, cnode_create_nop()); }
    | expression ';'    { $$ = cnode_create_stmt(STMT_EXP, 1, $1); }

compound_statement
    : '{' comp_decls comp_stmts '}' { 
        $$ = cnode_create_stmt(STMT_COMP, 2, cnode_list_wrap(COMP_DECLS, $2), 
                                             cnode_list_wrap(COMP_STMTS, $3)); 
    }

comp_decls
    : { $$ = cnode_create_nop(); }
    | comp_decls declaration { $$ = cnode_list_append($1, $2); }

comp_stmts
    : { $$ = cnode_create_nop(); }
    | comp_stmts statement { $$ = cnode_list_append($1, $2); }

selection_statement
    : KW_IF '(' expression ')' statement { 
        $$ = cnode_create_stmt(STMT_IF, 3, $3, $5, cnode_create_nop()); 
    }
    | KW_IF '(' expression ')' statement KW_ELSE statement { 
        $$ = cnode_create_stmt(STMT_IF, 3, $3, $5, $7);
    }

iteration_statement
    : KW_WHILE '(' expression ')' statement {
        $$ = cnode_create_stmt(STMT_WHILE, 2, $3, $5);
    }
    | KW_FOR '(' optional_exp ';' optional_exp ';' optional_exp ')' statement {
        $$ = cnode_create_stmt(STMT_FOR, 4, $3, $5, $7, $9);
    }

optional_exp
    : { $$ = cnode_create_nop(); }
    | expression

jump_statement
    : KW_CONT ';'   { $$ = cnode_create_stmt(STMT_CONT, 0); }
    | KW_BREAK ';'  { $$ = cnode_create_stmt(STMT_BREAK, 0); }
    | KW_RET optional_exp ';' { $$ = cnode_create_stmt(STMT_RET, 1, $2); }

expression
    : assignment_expression
    | expression ',' assignment_expression { $$ = cnode_create_exp(',', 2, $1, $3); }

assignment_expression
    : logical_or_expression
    | unary_expression assignment_operator assignment_expression { $$ = cnode_create_exp($2, 2, $1, $3); }

assignment_operator
    : '='           { $$ = '='; }
    | ASS_MUL       { $$ = ASS_MUL; }
    | ASS_DIV       { $$ = ASS_DIV; }
    | ASS_MOD       { $$ = ASS_MOD; }
    | ASS_ADD       { $$ = ASS_ADD; }
    | ASS_SUB       { $$ = ASS_SUB; }
    | ASS_SHL       { $$ = ASS_SHL; }
    | ASS_SHR       { $$ = ASS_SHR; }
    | ASS_AND       { $$ = ASS_AND; }
    | ASS_XOR       { $$ = ASS_XOR; }
    | ASS_OR        { $$ = ASS_OR; }

constant_expression: logical_or_expression
logical_or_expression
    : logical_and_expression
    | logical_or_expression OPT_OR logical_and_expression {
        $$ = cnode_create_exp(OPT_OR, 2, $1, $3);
    }

logical_and_expression
    : inclusive_or_expression
    | logical_and_expression OPT_AND inclusive_or_expression {
        $$ = cnode_create_exp(OPT_AND, 2, $1, $3);
    }

inclusive_or_expression
    : exclusive_or_expression
    | inclusive_or_expression