aboutsummaryrefslogblamecommitdiff
path: root/cibic.y
blob: daeb35ab734f3a7e9cc53c434200c9ab7b2c9c92 (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
%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
%%
debug_top
    : expression { ast_root = $1; }
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 '|' exclusive_or_expression { $$ = cnode_create_exp('|', 2, $1, $3); }

exclusive_or_expression
    : and_expression
    | exclusive_or_expression '^' and_expression { $$ = cnode_create_exp('^', 2, $1, $3); }

and_expression
    : equality_expression
    | and_expression '&' equality_expression { $$ = cnode_create_exp('&', 2, $1, $3); }

equality_expression
    : relational_expression 
    | equality_expression equality_operator relational_expression { $$ = cnode_create_exp($2, 2, $1, $3); }

equality_operator
    : OPT_EQ { $$ = OPT_EQ; }
    | OPT_NE { $$ = OPT_NE; }

relational_expression
    : shift_expression
    | relational_expression relational_operator shift_expression { $$ = cnode_create_exp($2, 2, $1, $3); }

relational_operator
    : '<' { $$ = '<'; }
    | '>' { $$ = '>'; }
    | OPT_LE { $$ = OPT_LE; }
    | OPT_GE { $$ = OPT_GE; }

shift_expression
    : additive_expression
    | shift_expression shift_operator additive_expression { $$ = cnode_create_exp($2, 2, $1, $3); }

shift_operator
    : OPT_SHL { $$ = OPT_SHL; }
    | OPT_SHR { $$ = OPT_SHR; }

additive_expression
    : multiplicative_expression
    | additive_expression additive_operator multiplicative_expression { $$ = cnode_create_exp($2, 2, $1, $3); }

additive_operator
    : '+' { $$ = '+'; }
    | '-' { $$ = '-'; }

multiplicative_expression
    : cast_expression
    | multiplicative_expression multiplicative_operator cast_expression { $$ = cnode_create_exp($2, 2, $1, $3); }

multiplicative_operator
    : '*' { $$ = '*'; }
    | '/' { $$ = '/'; }
    | '%' { $$ = '%'; }

cast_expression
    : unary_expression
    | '(' type_name ')' cast_expression { $$ = cnode_create_exp(EXP_CAST, 2, $2, $4); }

type_name
    : type_specifier
    | type_name '*' { $$ = cnode_create_exp('*', 1, $1); }

unary_expression
    : postfix_expression
    | OPT_INC unary_expression { $$ = cnode_create_exp(OPT_INC, 1, $2); }
    | OPT_DEC unary_expression { $$ = cnode_create_exp(OPT_DEC, 1, $2); }
    | unary_operator cast_expression { $$ = cnode_create_exp($1, 1, $2); }
    | KW_SIZEOF unary_expression { $$ = cnode_create_exp(KW_SIZEOF, 1, $2); }
    | KW_SIZEOF '(' type_name ')' { $$ = cnode_create_exp(KW_SIZEOF, 1, $3); }

unary_operator
    : '&' { $$ = '&'; }
    | '*' { $$ = '*'; }
    | '+' { $$ = '+'; }
    | '-' { $$ = '-'; }
    | '~' { $$ = '~'; }
    | '!' { $$ = '!'; }

postfix_expression
    : primary_expression
    | postfix_expression postfix { $$ = cnode_create_exp(EXP_POSTFIX, 2, $1, $2); }

postfix
    : '[' expression ']' { $$ = cnode_create_exp(POSTFIX_ARR, 1, $2); }
    | '(' arguments ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, $2); }
    | '(' ')' { $$ = cnode_create_exp(POSTFIX_CALL, 1, NULL); }
    | '.' identifier { $$ = cnode_create_exp(POSTFIX_DOT, 1, $2); }
    | OPT_PTR identifier { $$ = cnode_create_exp(POSTFIX_PTR, 1, $2); }
    | OPT_INC { $$ = cnode_create_exp(OPT_INC, 0); }
    | OPT_DEC { $$ = cnode_create_exp(OPT_DEC, 0); }

arguments
    : assignment_expression
    | arguments ',' assignment_expression { $$ = cnode_append($1, $3); }

primary_expression
    : identifier
    | INT_CONST   { $$ = cnode_create_int_const($1); }
    | CHAR_CONST { $$ = cnode_create_char_const($1); }
    | STR_CONST  { $$ = cnode_create_str_const($1); }
    | '(' expression ')' { $$ = $2; }

identifier
    : IDENTIFIER { $$ = cnode_create_identifier($1); }

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); } 
    /* to be continue */


%%
int yywrap() { 
    return 1; 
}

int yyerror(char *s) {
}

extern FILE *yyin;
void test_ast() {
    yyparse();
    if (ast_root)
        cnode_debug_print(ast_root);
    else
        fprintf(stderr, "Syntax Error\n");
}

int main() {
    int ret;
    yyin = fopen("in", "r");
    test_ast();
    return 0;
}