%{ /* * parser.y -- parser specification */ #include #include #include #include "common.h" #include "utils.h" #include "scanner.h" #include "parser.h" %} %union { NoVal noVal; IntVal intVal; StringVal stringVal; } %token BREAK CASE CONST CONTINUE DEFAULT DO ELSE %token FOR IF LAMBDA NEW NIL RECORD RETURN SIZEOF %token SWITCH TYPE VAR WHILE %token LPAREN RPAREN LCURL RCURL LBRACK RBRACK %token ASGNADD ASGNSUB ASGNMUL ASGNDIV ASGNMOD %token ASGNOR ASGNXOR ASGNAND ASGNSHL ASGNSHR %token ASGN COMMA SEMIC DOT COLON QMARK %token LOGOR LOGAND LOGNOT %token BITOR BITXOR BITAND BITNOT BITSHL BITSHR %token EQ NE LT LE GT GE %token PLUS MINUS STAR SLASH PERCENT %token INTEGERLIT %token CHARACTERLIT %token BOOLEANLIT %token STRINGLIT %token IDENT %start module %% module : glob_dec_list ; glob_dec_list : %empty | glob_dec glob_dec_list ; glob_dec : const_dec | type_dec | gvar_dec | func_dec ; ident_list : IDENT | IDENT COMMA ident_list ; type : IDENT | LBRACK RBRACK type | RECORD LCURL memb_dec_list RCURL | LAMBDA LPAREN par_dec_list RPAREN | LAMBDA LPAREN par_dec_list RPAREN COLON type ; memb_dec_list : %empty | memb_dec memb_dec_list ; memb_dec : ident_list COLON type SEMIC ; par_dec_list : %empty | non_empty_par_dec_list ; non_empty_par_dec_list : par_dec | par_dec SEMIC non_empty_par_dec_list ; par_dec : ident_list COLON type ; const_dec : CONST IDENT ASGN literal_exp SEMIC ; type_dec : TYPE IDENT ASGN type SEMIC ; gvar_dec : VAR ident_list COLON type SEMIC ; func_dec : IDENT LPAREN par_dec_list RPAREN LCURL lvar_dec_list stm_list RCURL | IDENT LPAREN par_dec_list RPAREN COLON type LCURL lvar_dec_list stm_list RCURL ; lvar_dec_list : %empty | lvar_dec lvar_dec_list ; lvar_dec : VAR ident_list COLON type SEMIC ; stm_list : %empty | stm stm_list ; stm : empty_stm | compound_stm | assign_stm | if_stm | switch_stm | while_stm | do_stm | for_stm | break_stm | continue_stm | call_stm | return_stm ; empty_stm : SEMIC ; compound_stm : LCURL stm_list RCURL ; assign_stm : postfix_exp ASGN exp SEMIC | postfix_exp ASGNADD exp SEMIC | postfix_exp ASGNSUB exp SEMIC | postfix_exp ASGNMUL exp SEMIC | postfix_exp ASGNDIV exp SEMIC | postfix_exp ASGNMOD exp SEMIC | postfix_exp ASGNOR exp SEMIC | postfix_exp ASGNXOR exp SEMIC | postfix_exp ASGNAND exp SEMIC | postfix_exp ASGNSHL exp SEMIC | postfix_exp ASGNSHR exp SEMIC ; if_stm : IF LPAREN exp RPAREN stm | IF LPAREN exp RPAREN stm ELSE stm ; switch_stm : SWITCH LPAREN exp RPAREN LCURL switch_cases switch_default RCURL ; switch_cases : %empty | switch_case switch_cases ; switch_case : CASE case_labels COLON stm ; case_labels : exp | exp COMMA case_labels ; switch_default : %empty | DEFAULT COLON stm ; while_stm : WHILE LPAREN exp RPAREN stm ; do_stm : DO stm WHILE LPAREN exp RPAREN SEMIC ; for_stm : FOR LPAREN stm exp SEMIC stm RPAREN stm ; break_stm : BREAK SEMIC ; continue_stm : CONTINUE SEMIC ; call_stm : postfix_exp SEMIC ; return_stm : RETURN SEMIC | RETURN exp SEMIC ; exp : cond_exp ; cond_exp : log_or_exp | log_or_exp QMARK cond_exp COLON cond_exp ; log_or_exp : log_and_exp | log_or_exp LOGOR log_and_exp ; log_and_exp : bit_or_exp | log_and_exp LOGAND bit_or_exp ; bit_or_exp : bit_xor_exp | bit_or_exp BITOR bit_xor_exp ; bit_xor_exp : bit_and_exp | bit_xor_exp BITXOR bit_and_exp ; bit_and_exp : rel_exp | bit_and_exp BITAND rel_exp ; rel_exp : bit_shift_exp | bit_shift_exp EQ bit_shift_exp | bit_shift_exp NE bit_shift_exp | bit_shift_exp LT bit_shift_exp | bit_shift_exp LE bit_shift_exp | bit_shift_exp GT bit_shift_exp | bit_shift_exp GE bit_shift_exp ; bit_shift_exp : add_exp | bit_shift_exp BITSHL add_exp | bit_shift_exp BITSHR add_exp ; add_exp : mul_exp | add_exp PLUS mul_exp | add_exp MINUS mul_exp ; mul_exp : unary_exp | mul_exp STAR unary_exp | mul_exp SLASH unary_exp | mul_exp PERCENT unary_exp ; unary_exp : postfix_exp | PLUS unary_exp | MINUS unary_exp | LOGNOT unary_exp | BITNOT unary_exp ; postfix_exp : primary_exp | postfix_exp LBRACK exp RBRACK | postfix_exp DOT IDENT | postfix_exp LPAREN arg_list RPAREN ; arg_list : %empty | non_empty_arg_list ; non_empty_arg_list : exp | exp COMMA non_empty_arg_list ; primary_exp : literal_exp | NEW LPAREN new_obj_spec RPAREN | SIZEOF LPAREN exp RPAREN | LPAREN exp RPAREN | IDENT ; literal_exp : NIL | INTEGERLIT | CHARACTERLIT | BOOLEANLIT | STRINGLIT ; new_obj_spec : IDENT | LBRACK exp RBRACK type | RECORD LCURL memb_dec_list RCURL ; %% void yyerror(char *msg) { error("%s in line %d", msg, yylval.noVal.line); }