%define api.prefix {ccmmc_parser_} %define api.pure full %lex-param {yyscan_t scanner} %parse-param {yyscan_t scanner} {CcmmcState *state} %{ #ifdef HAVE_CONFIG_H # include "config.h" #endif typedef void* yyscan_t; #include "ast.h" #include "state.h" #include #include #include %} %union{ char *lexeme; CcmmcAst *node; CcmmcValueConst value_const; }; %{ extern int ccmmc_parser_lex(CCMMC_PARSER_STYPE *yylval, yyscan_t scanner); extern char *ccmmc_parser_get_text(yyscan_t scanner); static void ccmmc_parser_error(yyscan_t scanner, CcmmcState *state, const char *mesg); %} %token ID %token CONST %token VOID %token INT %token FLOAT %token TYPEDEF %token IF %token ELSE %token WHILE %token FOR %token RETURN %token OP_ASSIGN %token OP_OR %token OP_AND %token OP_NOT %token OP_ADD %token OP_SUB %token OP_MUL %token OP_DIV %token OP_GT %token OP_LT %token OP_GE %token OP_LE %token OP_NE %token OP_EQ %token DL_LPAREN %token DL_RPAREN %token DL_LBRACK %token DL_RBRACK %token DL_LBRACE %token DL_RBRACE %token DL_COMMA %token DL_SEMICOL %token DL_DOT %token ERROR %right DL_RPAREN ELSE %type program %type global_decl_list global_decl %type function_decl param_list param dim_fn expr_null block %type decl_list decl type_decl var_decl type %type id_list dim_decl cexpr mcexpr cfactor %type init_id_list init_id stmt_list stmt %type assign_expr_list nonempty_assign_expr_list assign_expr %type relop_expr relop_term relop_factor rel_op %type relop_expr_list nonempty_relop_expr_list %type expr add_op term mul_op factor var_ref dim_list %start program %% /* ==== Grammar Section ==== */ program : global_decl_list { $$ = ccmmc_ast_new( CCMMC_AST_NODE_PROGRAM, state->line_number); ccmmc_ast_append_child($$, $1); state->ast = $$; } | { $$ = ccmmc_ast_new( CCMMC_AST_NODE_PROGRAM, state->line_number); state->ast = $$; } ; global_decl_list: global_decl_list global_decl { $$ = ccmmc_ast_append_sibling($1, $2); } | global_decl { $$ = $1; } ; global_decl : type_decl { $$ = $1; } | var_decl { $$ = $1; } | function_decl { $$ = $1; } ; function_decl : type ID DL_LPAREN param_list DL_RPAREN DL_LBRACE block DL_RBRACE { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_FUNCTION, state->line_number); CcmmcAst *param_list = ccmmc_ast_new( CCMMC_AST_NODE_PARAM_LIST, state->line_number); ccmmc_ast_append_child(param_list, $4); ccmmc_ast_append_children($$, 4, $1, ccmmc_ast_new_id($2, CCMMC_KIND_ID_NORMAL, state->line_number), param_list, $7); } | VOID ID DL_LPAREN param_list DL_RPAREN DL_LBRACE block DL_RBRACE { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_FUNCTION, state->line_number); CcmmcAst *param_list = ccmmc_ast_new( CCMMC_AST_NODE_PARAM_LIST, state->line_number); ccmmc_ast_append_child(param_list, $4); ccmmc_ast_append_children($$, 4, ccmmc_ast_new_id("void", CCMMC_KIND_ID_NORMAL, state->line_number), ccmmc_ast_new_id($2, CCMMC_KIND_ID_NORMAL, state->line_number), param_list, $7); } | type ID DL_LPAREN VOID DL_RPAREN DL_LBRACE block DL_RBRACE { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_FUNCTION, state->line_number); CcmmcAst *empty_param_list = ccmmc_ast_new( CCMMC_AST_NODE_PARAM_LIST, state->line_number); ccmmc_ast_append_children($$, 4, $1, ccmmc_ast_new_id($2, CCMMC_KIND_ID_NORMAL, state->line_number), empty_param_list, $7); } | VOID ID DL_LPAREN VOID DL_RPAREN DL_LBRACE block DL_RBRACE { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_FUNCTION, state->line_number); CcmmcAst *empty_param_list = ccmmc_ast_new( CCMMC_AST_NODE_PARAM_LIST, state->line_number); ccmmc_ast_append_children($$, 4, ccmmc_ast_new_id("void", CCMMC_KIND_ID_NORMAL, state->line_number), ccmmc_ast_new_id($2, CCMMC_KIND_ID_NORMAL, state->line_number), empty_param_list, $7); } | type ID DL_LPAREN DL_RPAREN DL_LBRACE block DL_RBRACE { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_FUNCTION, state->line_number); CcmmcAst *empty_param_list = ccmmc_ast_new( CCMMC_AST_NODE_PARAM_LIST, state->line_number); ccmmc_ast_append_children($$, 4, $1, ccmmc_ast_new_id($2, CCMMC_KIND_ID_NORMAL, state->line_number), empty_param_list, $6); } | VOID ID DL_LPAREN DL_RPAREN DL_LBRACE block DL_RBRACE { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_FUNCTION, state->line_number); CcmmcAst *empty_param_list = ccmmc_ast_new( CCMMC_AST_NODE_PARAM_LIST, state->line_number); ccmmc_ast_append_children($$, 4, ccmmc_ast_new_id("void", CCMMC_KIND_ID_NORMAL, state->line_number), ccmmc_ast_new_id($2, CCMMC_KIND_ID_NORMAL, state->line_number), empty_param_list, $6); } ; param_list : param_list DL_COMMA param { $$ = ccmmc_ast_append_sibling($1, $3); } | param { $$ = $1; } ; param : type ID { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_FUNCTION_PARAMETER, state->line_number); ccmmc_ast_append_children($$, 2, $1, ccmmc_ast_new_id($2, CCMMC_KIND_ID_NORMAL, state->line_number)); } | type ID dim_fn { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_FUNCTION_PARAMETER, state->line_number); ccmmc_ast_append_children($$, 2, $1, ccmmc_ast_append_child( ccmmc_ast_new_id($2, CCMMC_KIND_ID_ARRAY, state->line_number), $3)); } ; dim_fn : DL_LBRACK expr_null DL_RBRACK { $$ = $2; } | dim_fn DL_LBRACK expr DL_RBRACK { $$ = ccmmc_ast_append_sibling($1, $3); } ; expr_null :expr { $$ = $1; } | { $$ = ccmmc_ast_new(CCMMC_AST_NODE_NUL, state->line_number); } ; block : decl_list stmt_list { $$ = ccmmc_ast_new(CCMMC_AST_NODE_BLOCK, state->line_number); ccmmc_ast_append_children($$, 2, ccmmc_ast_append_child( ccmmc_ast_new(CCMMC_AST_NODE_VARIABLE_DECL_LIST, state->line_number), $1), ccmmc_ast_append_child( ccmmc_ast_new(CCMMC_AST_NODE_STMT_LIST, state->line_number), $2)); } | stmt_list { $$ = ccmmc_ast_new(CCMMC_AST_NODE_BLOCK, state->line_number); ccmmc_ast_append_child($$, ccmmc_ast_append_child( ccmmc_ast_new(CCMMC_AST_NODE_STMT_LIST, state->line_number), $1)); } | decl_list { $$ = ccmmc_ast_new(CCMMC_AST_NODE_BLOCK, state->line_number); ccmmc_ast_append_child($$, ccmmc_ast_append_child( ccmmc_ast_new(CCMMC_AST_NODE_VARIABLE_DECL_LIST, state->line_number), $1)); } | { $$ = ccmmc_ast_new(CCMMC_AST_NODE_BLOCK, state->line_number); } ; decl_list : decl_list decl { $$ = ccmmc_ast_append_sibling($1, $2); } | decl { $$ = $1; } ; decl : type_decl { $$ = $1; } | var_decl { $$ = $1; } ; type_decl : TYPEDEF type id_list DL_SEMICOL { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_TYPE, state->line_number); ccmmc_ast_append_children($$, 2, $2, $3); } | TYPEDEF VOID id_list DL_SEMICOL { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_TYPE, state->line_number); ccmmc_ast_append_children($$, 2, ccmmc_ast_new_id("void", CCMMC_KIND_ID_NORMAL, state->line_number), $3); } ; var_decl : type init_id_list DL_SEMICOL { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_VARIABLE, state->line_number); ccmmc_ast_append_children($$, 2, $1, $2); } | ID id_list DL_SEMICOL { $$ = ccmmc_ast_new_decl( CCMMC_KIND_DECL_VARIABLE, state->line_number); ccmmc_ast_append_children($$, 2, ccmmc_ast_new_id($1, CCMMC_KIND_ID_NORMAL, state->line_number), $2); } ; type : INT { $$ = ccmmc_ast_new_id("int", CCMMC_KIND_ID_NORMAL, state->line_number); } | FLOAT { $$ = ccmmc_ast_new_id("float", CCMMC_KIND_ID_NORMAL, state->line_number); } ; id_list : ID { $$ = ccmmc_ast_new_id($1, CCMMC_KIND_ID_NORMAL, state->line_number); } | id_list DL_COMMA ID { $$ = ccmmc_ast_append_sibling($1, ccmmc_ast_new_id($3, CCMMC_KIND_ID_NORMAL, state->line_number)); } | id_list DL_COMMA ID dim_decl { $$ = ccmmc_ast_append_sibling($1, ccmmc_ast_append_child( ccmmc_ast_new_id($3, CCMMC_KIND_ID_ARRAY, state->line_number), $4)); } | ID dim_decl { $$ = ccmmc_ast_append_child( ccmmc_ast_new_id($1, CCMMC_KIND_ID_ARRAY, state->line_number), $2); } ; dim_decl : DL_LBRACK cexpr DL_RBRACK { $$ = $2; } | dim_decl DL_LBRACK cexpr DL_RBRACK { $$ = ccmmc_ast_append_sibling($1, $3); } ; cexpr : cexpr OP_ADD mcexpr { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_ADD, state->line_number); ccmmc_ast_append_children($$, 2, $1, $3); } /* This is for array declarations */ | cexpr OP_SUB mcexpr { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_SUB, state->line_number); ccmmc_ast_append_children($$, 2, $1, $3); } | mcexpr { $$ = $1; } ; mcexpr : mcexpr OP_MUL cfactor { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_MUL, state->line_number); ccmmc_ast_append_children($$, 2, $1, $3); } | mcexpr OP_DIV cfactor { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_DIV, state->line_number); ccmmc_ast_append_children($$, 2, $1, $3); } | cfactor { $$ = $1; } ; cfactor: CONST { $$ = ccmmc_ast_new( CCMMC_AST_NODE_CONST_VALUE, state->line_number); $$->value_const = $1; } | DL_LPAREN cexpr DL_RPAREN { $$ = $2; } ; init_id_list: init_id { $$ = $1; } | init_id_list DL_COMMA init_id { $$ = ccmmc_ast_append_sibling($1, $3); } ; init_id : ID { $$ = ccmmc_ast_new_id($1, CCMMC_KIND_ID_NORMAL, state->line_number); } | ID dim_decl { $$ = ccmmc_ast_append_child( ccmmc_ast_new_id($1, CCMMC_KIND_ID_ARRAY, state->line_number), $2); } | ID OP_ASSIGN relop_expr { $$ = ccmmc_ast_new_id($1, CCMMC_KIND_ID_WITH_INIT, state->line_number); ccmmc_ast_append_child($$, $3); } ; stmt_list : stmt_list stmt { $$ = ccmmc_ast_append_sibling($1, $2); } | stmt { $$ = $1; } ; stmt : DL_LBRACE block DL_RBRACE { $$ = $2; } | WHILE DL_LPAREN relop_expr DL_RPAREN stmt { $$ = ccmmc_ast_new_stmt(CCMMC_KIND_STMT_WHILE, state->line_number); ccmmc_ast_append_children($$, 2, $3, $5); } | FOR DL_LPAREN assign_expr_list DL_SEMICOL relop_expr_list DL_SEMICOL assign_expr_list DL_RPAREN stmt { $$ = ccmmc_ast_new_stmt(CCMMC_KIND_STMT_FOR, state->line_number); ccmmc_ast_append_children($$, 4, $3, $5, $7, $9); } | var_ref OP_ASSIGN relop_expr DL_SEMICOL { $$ = ccmmc_ast_new_stmt(CCMMC_KIND_STMT_ASSIGN, state->line_number); ccmmc_ast_append_children($$, 2, $1, $3); } | IF DL_LPAREN relop_expr DL_RPAREN stmt { $$ = ccmmc_ast_new_stmt(CCMMC_KIND_STMT_IF, state->line_number); ccmmc_ast_append_children($$, 3, $3, $5, ccmmc_ast_new(CCMMC_AST_NODE_NUL, state->line_number)); } | IF DL_LPAREN relop_expr DL_RPAREN stmt ELSE stmt { $$ = ccmmc_ast_new_stmt(CCMMC_KIND_STMT_IF, state->line_number); ccmmc_ast_append_children($$, 3, $3, $5, $7); } | ID DL_LPAREN relop_expr_list DL_RPAREN DL_SEMICOL { $$ = ccmmc_ast_new_stmt(CCMMC_KIND_STMT_FUNCTION_CALL, state->line_number); ccmmc_ast_append_children($$, 2, ccmmc_ast_new_id($1, CCMMC_KIND_ID_NORMAL, state->line_number), $3); } | DL_SEMICOL { $$ = ccmmc_ast_new(CCMMC_AST_NODE_NUL, state->line_number); } | RETURN DL_SEMICOL { $$ = ccmmc_ast_new_stmt(CCMMC_KIND_STMT_RETURN, state->line_number); } | RETURN relop_expr DL_SEMICOL { $$ = ccmmc_ast_new_stmt(CCMMC_KIND_STMT_RETURN, state->line_number); ccmmc_ast_append_child($$, $2); } ; assign_expr_list: nonempty_assign_expr_list { $$ = ccmmc_ast_new( CCMMC_AST_NODE_NONEMPTY_ASSIGN_EXPR_LIST, state->line_number); ccmmc_ast_append_child($$, $1); } | { $$ = ccmmc_ast_new(CCMMC_AST_NODE_NUL, state->line_number); } ; nonempty_assign_expr_list : nonempty_assign_expr_list DL_COMMA assign_expr { $$ = ccmmc_ast_append_sibling($1, $3); } | assign_expr { $$ = $1; } ; assign_expr : var_ref OP_ASSIGN relop_expr { $$ = ccmmc_ast_new_stmt( CCMMC_KIND_STMT_ASSIGN, state->line_number); ccmmc_ast_append_children($$, 2, $1, $3); } | relop_expr { $$ = $1; } ; relop_expr : relop_term { $$ = $1; } | relop_expr OP_OR relop_term { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_OR, state->line_number); ccmmc_ast_append_children($$, 2, $1, $3); } ; relop_term : relop_factor { $$ = $1; } | relop_term OP_AND relop_factor { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_AND, state->line_number); ccmmc_ast_append_children($$, 2, $1, $3); } ; relop_factor : expr { $$ = $1; } | expr rel_op expr { $$ = $2; ccmmc_ast_append_children($$, 2, $1, $3); } ; rel_op : OP_EQ { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_EQ, state->line_number); } | OP_GE { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_GE, state->line_number); } | OP_LE { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_LE, state->line_number); } | OP_NE { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_NE, state->line_number); } | OP_GT { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_GT, state->line_number); } | OP_LT { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_LT, state->line_number); } ; relop_expr_list : nonempty_relop_expr_list { $$ = ccmmc_ast_new( CCMMC_AST_NODE_NONEMPTY_RELOP_EXPR_LIST, state->line_number); ccmmc_ast_append_child($$, $1); } | { $$ = ccmmc_ast_new(CCMMC_AST_NODE_NUL, state->line_number); } ; nonempty_relop_expr_list: nonempty_relop_expr_list DL_COMMA relop_expr { $$ = ccmmc_ast_append_sibling($1, $3); } | relop_expr { $$ = $1; } ; expr : expr add_op term { $$ = $2; ccmmc_ast_append_children($$, 2, $1, $3); } | term { $$ = $1; } ; add_op : OP_ADD { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_ADD, state->line_number); } | OP_SUB { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_SUB, state->line_number); } ; term : term mul_op factor { $$ = $2; ccmmc_ast_append_children($$, 2, $1, $3); } | factor { $$ = $1; } ; mul_op : OP_MUL { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_MUL, state->line_number); } | OP_DIV { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_BINARY_OP, CCMMC_KIND_OP_BINARY_DIV, state->line_number); } ; factor : DL_LPAREN relop_expr DL_RPAREN { $$ = $2; } | OP_ADD DL_LPAREN relop_expr DL_RPAREN { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_POSITIVE, state->line_number); ccmmc_ast_append_child($$, $3); } | OP_SUB DL_LPAREN relop_expr DL_RPAREN { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_NEGATIVE, state->line_number); ccmmc_ast_append_child($$, $3); } | OP_NOT DL_LPAREN relop_expr DL_RPAREN { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_LOGICAL_NEGATION, state->line_number); ccmmc_ast_append_child($$, $3); } | CONST { $$ = ccmmc_ast_new(CCMMC_AST_NODE_CONST_VALUE, state->line_number); $$->value_const = $1; } | OP_ADD CONST { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_POSITIVE, state->line_number); CcmmcAst *const_node = ccmmc_ast_new( CCMMC_AST_NODE_CONST_VALUE, state->line_number); const_node->value_const = $2; ccmmc_ast_append_child($$, const_node); } | OP_SUB CONST { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_NEGATIVE, state->line_number); CcmmcAst *const_node = ccmmc_ast_new( CCMMC_AST_NODE_CONST_VALUE, state->line_number); const_node->value_const = $2; ccmmc_ast_append_child($$, const_node); } | OP_NOT CONST { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_LOGICAL_NEGATION, state->line_number); CcmmcAst *const_node = ccmmc_ast_new( CCMMC_AST_NODE_CONST_VALUE, state->line_number); const_node->value_const = $2; ccmmc_ast_append_child($$, const_node); } | ID DL_LPAREN relop_expr_list DL_RPAREN { $$ = ccmmc_ast_new_stmt( CCMMC_KIND_STMT_FUNCTION_CALL, state->line_number); ccmmc_ast_append_children($$, 2, ccmmc_ast_new_id($1, CCMMC_KIND_ID_NORMAL, state->line_number), $3); } | OP_ADD ID DL_LPAREN relop_expr_list DL_RPAREN { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_POSITIVE, state->line_number); CcmmcAst *func_node = ccmmc_ast_new_stmt( CCMMC_KIND_STMT_FUNCTION_CALL, state->line_number); ccmmc_ast_append_children(func_node, 2, ccmmc_ast_new_id($2, CCMMC_KIND_ID_NORMAL, state->line_number), $4); ccmmc_ast_append_child($$, func_node); } | OP_SUB ID DL_LPAREN relop_expr_list DL_RPAREN { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_NEGATIVE, state->line_number); CcmmcAst *func_node = ccmmc_ast_new_stmt( CCMMC_KIND_STMT_FUNCTION_CALL, state->line_number); ccmmc_ast_append_children(func_node, 2, ccmmc_ast_new_id($2, CCMMC_KIND_ID_NORMAL, state->line_number), $4); ccmmc_ast_append_child($$, func_node); } | OP_NOT ID DL_LPAREN relop_expr_list DL_RPAREN { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_LOGICAL_NEGATION, state->line_number); CcmmcAst *func_node = ccmmc_ast_new_stmt( CCMMC_KIND_STMT_FUNCTION_CALL, state->line_number); ccmmc_ast_append_children(func_node, 2, ccmmc_ast_new_id($2, CCMMC_KIND_ID_NORMAL, state->line_number), $4); ccmmc_ast_append_child($$, func_node); } | var_ref { $$ = $1; } | OP_ADD var_ref { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_POSITIVE, state->line_number); ccmmc_ast_append_child($$, $2); } | OP_SUB var_ref { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_NEGATIVE, state->line_number); ccmmc_ast_append_child($$, $2); } | OP_NOT var_ref { $$ = ccmmc_ast_new_expr(CCMMC_KIND_EXPR_UNARY_OP, CCMMC_KIND_OP_UNARY_LOGICAL_NEGATION, state->line_number); ccmmc_ast_append_child($$, $2); } ; var_ref : ID { $$ = ccmmc_ast_new_id($1, CCMMC_KIND_ID_NORMAL, state->line_number); } | ID dim_list { $$ = ccmmc_ast_new_id($1, CCMMC_KIND_ID_ARRAY, state->line_number); ccmmc_ast_append_child($$, $2); } ; dim_list : dim_list DL_LBRACK expr DL_RBRACK { $$ = ccmmc_ast_append_sibling($1, $3); } | DL_LBRACK expr DL_RBRACK { $$ = $2; } ; %% static void ccmmc_parser_error(yyscan_t scanner, CcmmcState *state, const char *mesg) { fprintf(stderr, "Error found in Line \t%zu\tnext token: \t%s\n", state->line_number, ccmmc_parser_get_text(scanner)); exit(1); } // vim: set sw=4 ts=4 sts=4 et: