erts/lib_src/yielding_c_fun/ycf_parser.c (1,338 lines of code) (raw):
/*
* %CopyrightBegin%
*
* Copyright Ericsson AB and Kjell Winblad 2019. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* %CopyrightEnd%
*/
/*
* Author: Kjell Winblad
*/
#include "ycf_yield_fun.h"
#include "ycf_utils.h"
#include "ycf_node.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void print_symbol_code(ycf_symbol* s);
ycf_parse_result parse_exp_statement(ycf_symbol* symbols);
ycf_parse_result fail_parse_result(){
ycf_parse_result r;
r.success = false;
r.next_symbol = NULL;
r.result = NULL;
return r;
}
ycf_parse_result success_parse_result(ycf_symbol* next,
ycf_node* result){
ycf_parse_result r;
r.success = true;
r.next_symbol = next;
r.result = result;
return r;
}
typedef struct {
ycf_node_list list;
ycf_symbol* next_symbol;
} parse_list_res;
typedef struct {
ycf_symbol_list list;
ycf_symbol* next_symbol;
} parse_symbol_list_res;
parse_list_res parse_list_generic(int number_of_parsers,
ycf_parse_result (*parsers[])(ycf_symbol*),
ycf_symbol* symbols,
bool use_break_symbol,
int nr_of_break_symbols,
ycf_symbol_type break_symbols[]){
parse_list_res r;
ycf_symbol* current = symbols;
int i;
r.list = ycf_node_list_empty();
while(current != NULL){
if(use_break_symbol){
bool is_break = false;
for(int i = 0; i < nr_of_break_symbols; i++){
if(break_symbols[i] == current->type){
is_break = true;
}
}
if(is_break){
break;
}
}
ycf_symbol* prev_current_symbol = current;
for(i = 0; i < number_of_parsers; i++){
ycf_parse_result res = parsers[i](current);
if(res.success){
ycf_node_list_append(&r.list, res.result);
current = res.next_symbol;
break;
}
}
if(prev_current_symbol == current){
break;
}
}
r.next_symbol = current;
return r;
}
parse_list_res parse_list(int number_of_parsers,
ycf_parse_result (*parsers[])(ycf_symbol*),
ycf_symbol* symbols){
return parse_list_generic(number_of_parsers,
parsers,
symbols,
false,
0,
NULL);
}
parse_list_res parse_list_break_symbol(int number_of_parsers,
ycf_parse_result (*parsers[])(ycf_symbol*),
ycf_symbol* symbols,
ycf_symbol_type break_symbol){
ycf_symbol_type break_s[1] = {break_symbol};
return parse_list_generic(number_of_parsers,
parsers,
symbols,
true,
1,
break_s);
}
parse_list_res parse_list_break_symbols(int number_of_parsers,
ycf_parse_result (*parsers[])(ycf_symbol*),
ycf_symbol* symbols,
int nr_of_break_symbols,
ycf_symbol_type break_symbols[]){
return parse_list_generic(number_of_parsers,
parsers,
symbols,
true,
nr_of_break_symbols,
break_symbols);
}
ycf_node* ycf_node_defenition_new(ycf_symbol_list type_spec,
ycf_symbol* id,
ycf_node_list array_brackets,
ycf_symbol* end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_variable_definition;
n->next = NULL;
n->u.definition.identifier = ycf_symbol_copy(id);
n->u.definition.type_specifiers = type_spec;
n->u.definition.array_brackets = array_brackets;
n->u.definition.end = ycf_symbol_copy(end);
return n;
}
ycf_node* ycf_node_defenition_with_init_new(ycf_node_definition def,
ycf_symbol_list expression,
ycf_symbol* end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_variable_definition_init;
n->next = NULL;
n->u.definition_init.definition = def;
n->u.definition_init.initializer_expression = expression;
n->u.definition_init.end = ycf_symbol_copy(end);
return n;
}
ycf_node* ycf_node_c_file_new(ycf_node_list content){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_c_file;
n->next = NULL;
n->u.c_file.content = content;
return n;
}
ycf_node* ycf_node_function_def_new(ycf_node_definition def_node,
ycf_node_list parameters,
bool ignore_param_ending,
ycf_symbol_list end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_function_declaration;
n->next = NULL;
n->u.function_definition.definition = def_node;
n->u.function_definition.parameters = parameters;
n->u.function_definition.ignore_param_ending = ignore_param_ending;
n->u.function_definition.end = end;
return n;
}
ycf_node* ycf_node_yield_new(ycf_symbol* yield_symbol,
ycf_symbol* end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_yield;
n->next = NULL;
n->u.yield.yield_symbol = ycf_symbol_copy(yield_symbol);
n->u.yield.end_symbol = ycf_symbol_copy(end);
return n;
}
ycf_node* ycf_node_consume_reds_new(ycf_symbol* consume_reds_symbol,
ycf_node_parentheses_expression nr_of_reds_expression,
ycf_symbol* end_symbol){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_consume_reds;
n->next = NULL;
n->u.consume_reds.consume_reds_symbol = ycf_symbol_copy(consume_reds_symbol);
n->u.consume_reds.nr_of_reds_expression = nr_of_reds_expression;
n->u.consume_reds.end_symbol = ycf_symbol_copy(end_symbol);
return n;
}
ycf_node* ycf_node_other_new(ycf_symbol* other_symbol){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_other;
n->next = NULL;
n->u.other.what = ycf_symbol_copy(other_symbol);
return n;
}
ycf_node* ycf_node_scope_new(ycf_symbol* start,
ycf_node_list declaration_nodes,
ycf_node_list other_nodes,
ycf_symbol* end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_code_scope;
n->next = NULL;
n->u.code_scope.start = ycf_symbol_copy(start);
n->u.code_scope.definition_nodes = declaration_nodes;
n->u.code_scope.other_nodes = other_nodes;
n->u.code_scope.end = ycf_symbol_copy(end);
return n;
}
ycf_node* ycf_node_function_new(ycf_node_function_definition fun_def,
ycf_node_code_scope body){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_function_definition;
n->next = NULL;
n->u.function.definition = fun_def;
n->u.function.body = body;
return n;
}
ycf_node* ycf_node_function_call_new(ycf_symbol_list neg_symbols,
ycf_symbol* ident,
ycf_symbol* paran_start,
ycf_node_list parameters,
ycf_symbol* paran_end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_function_call;
n->next = NULL;
n->u.function_call.neg_symbols = neg_symbols;
n->u.function_call.identifier = ident;
n->u.function_call.start_symbol = paran_start;
n->u.function_call.parameter_expressions = parameters;
n->u.function_call.end_symbol = paran_end;
return n;
}
ycf_node* ycf_node_paran_expression_new(ycf_symbol* start, ycf_node_expression expr, ycf_symbol* end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_parentheses_expression;
n->next = NULL;
n->u.parentheses_expression.start_symbol = start;
n->u.parentheses_expression.content = expr;
n->u.parentheses_expression.end_symbol = end;
return n;
}
ycf_node* ycf_node_expression_new(ycf_node_list expr){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_expression;
n->next = NULL;
n->u.expression.content = expr;
n->u.expression.end_symbol = NULL;
return n;
}
ycf_node* ycf_node_statement_new(ycf_node* expression,
ycf_symbol* end_symbol){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->type = ycf_node_type_statement;
n->next = NULL;
n->u.statement.expression = expression;
n->u.statement.end_symbol = end_symbol;
return n;
}
ycf_node* ycf_node_while_new(ycf_symbol* while_word,
ycf_node_parentheses_expression expression,
ycf_node* statement){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_while;
n->u.while_n.while_word = while_word;
n->u.while_n.expression = expression;
n->u.while_n.statement = statement;
return n;
}
ycf_node* ycf_node_do_while_new(ycf_symbol* do_word,
ycf_node* statm,
ycf_symbol* while_word,
ycf_node_parentheses_expression expression,
ycf_symbol* end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_do_while;
n->u.do_while.do_word = do_word;
n->u.do_while.statement = statm;
n->u.do_while.while_word = while_word;
n->u.do_while.expression = expression;
n->u.do_while.end = end;
return n;
}
ycf_node* ycf_node_for_new(ycf_symbol* for_word,
ycf_symbol* start_paran,
struct ycf_node* init,
ycf_node* stop_cond,
ycf_symbol* stop_cond_end,
ycf_node* end_exp,
ycf_symbol* end_paran,
ycf_node* statem){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_for;
n->u.for_n.for_word = for_word;
n->u.for_n.start_parentheses = start_paran;
n->u.for_n.init = init;
n->u.for_n.stop_cond = stop_cond;
n->u.for_n.stop_cond_end = stop_cond_end;
n->u.for_n.end_exp = end_exp;
n->u.for_n.end_parentheses = end_paran;
n->u.for_n.statement = statem;
return n;
}
ycf_node* ycf_node_switch_new(ycf_symbol* switch_word,
ycf_node_parentheses_expression expression,
ycf_node_code_scope scope){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_switch;
n->u.switch_n.switch_word = switch_word;
n->u.switch_n.expression = expression;
n->u.switch_n.scope = scope;
return n;
}
ycf_node* ycf_node_if_new(ycf_symbol* if_word,
ycf_node_parentheses_expression expression,
struct ycf_node* if_statem){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_if;
n->u.if_n.if_word = if_word;
n->u.if_n.expression = expression;
n->u.if_n.if_statement = if_statem;
return n;
}
ycf_node* ycf_node_if_else_new(ycf_node_if if_n,
ycf_symbol* else_word,
struct ycf_node* else_statement){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_if_else;
n->u.if_else.if_part = if_n;
n->u.if_else.else_word = else_word;
n->u.if_else.else_statement = else_statement;
return n;
}
ycf_node* ycf_node_fun_call_assignment_new(ycf_node_expression left_side,
ycf_symbol* assignment_symbol,
ycf_node_function_call fun_call){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_assignment_function_call;
n->u.function_call_assignment.left_side = left_side;
n->u.function_call_assignment.assignment_symbol = assignment_symbol;
n->u.function_call_assignment.fun_call = fun_call;
return n;
}
ycf_node* ycf_node_assignment_new(ycf_node_expression left_side,
ycf_symbol* assignment_symbol,
ycf_node_expression right_side,
ycf_symbol* end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_assignment;
n->u.a.left_side = left_side;
n->u.a.right_side = right_side;
n->u.a.assignment_symbol = assignment_symbol;
n->u.a.end = end;
return n;
}
ycf_node* ycf_node_comma_new(ycf_symbol* comma_symbol){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_comma;
n->u.comma.comma_symbol = comma_symbol;
return n;
}
ycf_node* ycf_node_array_bracket_new(ycf_symbol* start,
bool empty,
ycf_node_expression content,
ycf_symbol* end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_array_bracket;
n->u.array_bracket.start = start;
n->u.array_bracket.empty = empty;
n->u.array_bracket.content = content;
n->u.array_bracket.end = end;
return n;
}
ycf_node* ycf_node_macro_cmd_new(ycf_symbol* macro_symbol){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_macro_cmd;
n->u.macro_cmd.symbol = macro_symbol;
return n;
}
ycf_node* ycf_node_special_code_block_new(ycf_node_type type,
ycf_symbol* start,
ycf_node_if code,
ycf_symbol* end){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = type;
n->u.special_code_block.start = start;
n->u.special_code_block.code = code;
n->u.special_code_block.end = end;
return n;
}
ycf_node* ycf_node_goto_new(ycf_symbol* goto_symbol,
ycf_symbol* label_symbol,
ycf_symbol* end_symbol){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_goto;
n->u.goto_n.goto_symbol = goto_symbol;
n->u.goto_n.label_symbol = label_symbol;
n->u.goto_n.end_symbol = end_symbol;
return n;
}
ycf_node* ycf_node_return_new(ycf_symbol* return_symbol,
ycf_node* return_expression,
ycf_symbol* end_symbol){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_return_statement;
n->u.return_n.return_symbol = return_symbol;
n->u.return_n.return_expression = return_expression;
n->u.return_n.end_symbol = end_symbol;
return n;
}
ycf_node* ycf_node_period_field_access_new(ycf_symbol* period,
ycf_symbol* field_name){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_period_field_access;
n->u.period_field_access.period = period;
n->u.period_field_access.field_name = field_name;
return n;
}
ycf_node* ycf_pointer_field_access_new(ycf_symbol* pointer,
ycf_symbol* field_name){
ycf_node* n = ycf_malloc(sizeof(ycf_node));
n->next = NULL;
n->type = ycf_node_type_period_field_access;
n->u.pointer_field_access.pointer = pointer;
n->u.pointer_field_access.field_name = field_name;
return n;
}
parse_symbol_list_res parse_symbol_list(int nr_of_aloved_symbols,
ycf_symbol_type accept_symbols[],
ycf_symbol* symbols){
int i;
parse_symbol_list_res r;
ycf_symbol* current = symbols;
r.list = ycf_symbol_list_empty();
while (current != NULL){
ycf_symbol* prev_current = current;
for(i = 0; i < nr_of_aloved_symbols; i++){
if(current->type == accept_symbols[i]){
ycf_symbol_list_append(&r.list, ycf_symbol_copy(current));
current = current->next;
}
}
if(prev_current == current){
break;
}
}
r.next_symbol = current;
return r;
}
parse_symbol_list_res
parse_symbol_list_until(ycf_symbol* symbols, ycf_symbol_type end_symbol){
parse_symbol_list_res r;
ycf_symbol* current = symbols;
r.list = ycf_symbol_list_empty();
while (current->type != end_symbol){
ycf_symbol_list_append(&r.list, ycf_symbol_copy(current));
current = current->next;
}
r.next_symbol = current;
return r;
}
ycf_parse_result parse_expression_end_end_squarebracket(ycf_symbol* symbols);
ycf_parse_result parse_array_bracket(ycf_symbol* symbols){
if(symbols->type != ycf_symbol_type_open_square_bracket){
return fail_parse_result();
}
if(symbols->next->type == ycf_symbol_type_end_square_bracket){
ycf_node_expression empty = {.content = ycf_node_list_empty(), .end_symbol = NULL};
return success_parse_result(symbols->next->next,
ycf_node_array_bracket_new(symbols, true, empty, symbols->next));
}
ycf_parse_result square_bracket_content =
parse_expression_end_end_squarebracket(symbols->next);
if(!square_bracket_content.success){
return fail_parse_result();
}
return success_parse_result(square_bracket_content.next_symbol->next,
ycf_node_array_bracket_new(symbols,
false,
square_bracket_content.result->u.expression,
square_bracket_content.next_symbol));
}
ycf_parse_result parse_defenition_until_identifier(ycf_symbol* symbols,
ycf_symbol_type end_symbol_type){
ycf_symbol* current = symbols;
ycf_symbol_list type_specifier = ycf_symbol_list_empty();
ycf_symbol* ident = NULL;
ycf_node_list array_brackets;
/* Parse modifiers */
{
int nr_of_aloved_symbols = 4;
ycf_symbol_type accept_symbols[4];
accept_symbols[0] = ycf_symbol_type_static;
accept_symbols[1] = ycf_symbol_type_const;
accept_symbols[2] = ycf_symbol_type_inline;
accept_symbols[3] = ycf_symbol_type_volatile;
parse_symbol_list_res more =
parse_symbol_list(nr_of_aloved_symbols,
accept_symbols,
current);
ycf_symbol_list_concat(&type_specifier, &more.list);
current = more.next_symbol;
}
/* Parse first symbol */
if(current->type == ycf_symbol_type_identifier ||
current->type == ycf_symbol_type_void){
ycf_symbol_list_append(&type_specifier, ycf_symbol_copy(current));
current = current->next;
} else {
return fail_parse_result();
}
if(type_specifier.last->type == ycf_symbol_type_identifier){
/* Parse remaining identifiers if first symbol is ycf_symbol_type_identifier */
int nr_of_aloved_symbols = 2;
ycf_symbol_type accept_symbols[2];
accept_symbols[0] = ycf_symbol_type_identifier;
accept_symbols[1] = ycf_symbol_type_const;
parse_symbol_list_res more =
parse_symbol_list(nr_of_aloved_symbols,
accept_symbols,
current);
ycf_symbol_list_concat(&type_specifier, &more.list);
current = more.next_symbol;
}
{
/* Parse stars */
int nr_of_aloved_symbols = 1;
ycf_symbol_type accept_symbols[1];
accept_symbols[0] = ycf_symbol_type_star;
parse_symbol_list_res more =
parse_symbol_list(nr_of_aloved_symbols,
accept_symbols,
current);
ycf_symbol_list_concat(&type_specifier, &more.list);
current = more.next_symbol;
}
/* Handle ycf_symbol_type_identifier */
if(type_specifier.last->type == ycf_symbol_type_identifier){
ident = type_specifier.last;
ycf_symbol_list_remove(&type_specifier, type_specifier.last);
if (type_specifier.head == NULL) {
return fail_parse_result();
}
} else if (current->type != ycf_symbol_type_identifier){
return fail_parse_result();
} else {
ident = current;
current = current->next;
}
/* Handle array brackets */
{
ycf_parse_result (*parsers[])(ycf_symbol *) = {
parse_array_bracket
};
parse_list_res res = parse_list(1, parsers, current);
array_brackets = res.list;
current = res.next_symbol;
}
/* Parse end symbol */
if (current == NULL ||
current->type != end_symbol_type){
return fail_parse_result();
} else {
return success_parse_result(current->next,
ycf_node_defenition_new(type_specifier,
ident,
array_brackets,
current));
}
}
ycf_parse_result parse_defenition_no_init(ycf_symbol* symbols){
ycf_parse_result res = parse_defenition_until_identifier(symbols, ycf_symbol_type_semicolon);
return res;
}
ycf_parse_result parse_defenition_with_init(ycf_symbol* symbols){
ycf_parse_result dec = parse_defenition_until_identifier(symbols, ycf_symbol_type_equal_sign);
parse_symbol_list_res expression_list_res;
if(!dec.success){
return fail_parse_result();
}
expression_list_res =
parse_symbol_list_until(dec.next_symbol, ycf_symbol_type_semicolon);
return success_parse_result(expression_list_res.next_symbol->next,
ycf_node_defenition_with_init_new(dec.result->u.definition,
expression_list_res.list,
expression_list_res.next_symbol));
}
ycf_parse_result parse_defenition_comma(ycf_symbol* symbols){
ycf_parse_result res = parse_defenition_until_identifier(symbols, ycf_symbol_type_comma);
return res;
}
ycf_parse_result parse_defenition_end_paran(ycf_symbol* symbols){
ycf_parse_result res = parse_defenition_until_identifier(symbols, ycf_symbol_type_end_parenthesis);
return res;
}
ycf_parse_result parse_function_head(ycf_symbol* symbols,
ycf_symbol_type end_symbol,
bool exclude_end_symbol){
ycf_symbol* current = symbols;
ycf_parse_result def_res =
parse_defenition_until_identifier(current,
ycf_symbol_type_open_parenthesis);
if(!def_res.success){
return fail_parse_result();
}
current = def_res.next_symbol;
/* Parse function without parameters */
if(current->type == ycf_symbol_type_end_parenthesis &&
current->next->type == end_symbol){
ycf_symbol_list end = ycf_symbol_list_empty();
ycf_symbol* next_symbol;
ycf_node_list parameter_list = ycf_node_list_empty();
ycf_symbol_list_append(&end, ycf_symbol_copy(current));
if(!exclude_end_symbol){
next_symbol = current->next->next;
ycf_symbol_list_append(&end, ycf_symbol_copy(current->next));
} else {
next_symbol = current->next;
}
return success_parse_result(next_symbol,
ycf_node_function_def_new(def_res.result->u.definition,
parameter_list,
false,
end));
} else if(current->type == ycf_symbol_type_void &&
current->next->type == ycf_symbol_type_end_parenthesis &&
current->next->next->type == end_symbol){
ycf_symbol_list end = ycf_symbol_list_empty();
ycf_symbol* next_symbol;
ycf_node_list parameter_list = ycf_node_list_empty();
ycf_symbol_list_append(&end, ycf_symbol_copy(current));
ycf_symbol_list_append(&end, ycf_symbol_copy(current->next));
if(!exclude_end_symbol){
next_symbol = current->next->next->next;
ycf_symbol_list_append(&end, ycf_symbol_copy(current->next->next));
}else{
next_symbol = current->next->next;
}
return success_parse_result(next_symbol,
ycf_node_function_def_new(def_res.result->u.definition,
parameter_list,
false,
end));
}
/* Parse parameters */
int number_of_parsers = 2;
ycf_parse_result (*parsers[])(ycf_symbol *) = {
parse_defenition_comma,
parse_defenition_end_paran
};
parse_list_res param_list =
parse_list(number_of_parsers, parsers, current);
if(param_list.next_symbol == NULL ||
param_list.next_symbol->type != end_symbol){
return fail_parse_result();
}
/* Parse ending */
{
ycf_symbol_list end = ycf_symbol_list_empty();
ycf_symbol* next_symbol;
if(!exclude_end_symbol){
next_symbol = param_list.next_symbol->next;
ycf_symbol_list_append(&end, ycf_symbol_copy(param_list.next_symbol));
}else{
next_symbol = param_list.next_symbol;
}
return success_parse_result(next_symbol,
ycf_node_function_def_new(def_res.result->u.definition,
param_list.list,
false,
end));
}
}
ycf_parse_result parse_function_def(ycf_symbol* symbols){
return parse_function_head(symbols, ycf_symbol_type_semicolon, false);
}
ycf_parse_result parse_other(ycf_symbol* symbols){
ycf_symbol* what = symbols;
return success_parse_result(symbols->next,
ycf_node_other_new(what));
}
ycf_parse_result parse_goto(ycf_symbol* symbols){
ycf_symbol* goto_symbol = symbols;
if(goto_symbol->type != ycf_symbol_type_goto){
return fail_parse_result();
}
ycf_symbol* label_symbol = goto_symbol->next;
if(label_symbol->type != ycf_symbol_type_identifier){
return fail_parse_result();
}
ycf_symbol* end_symbol = label_symbol->next;
if(end_symbol->type != ycf_symbol_type_semicolon){
return fail_parse_result();
}
return success_parse_result(end_symbol->next,
ycf_node_goto_new(goto_symbol, label_symbol, end_symbol));
}
ycf_parse_result parse_comma(ycf_symbol* symbols){
if(symbols->type == ycf_symbol_type_comma){
return success_parse_result(symbols->next, ycf_node_comma_new(symbols));
} else {
return fail_parse_result();
}
}
ycf_parse_result parse_pointer_field_access_node(ycf_symbol* symbols){
ycf_symbol* pointer = symbols;
if(pointer->type != ycf_symbol_type_pointer_field_access){
return fail_parse_result();
}
ycf_symbol* field_name = pointer->next;
if(field_name->type != ycf_symbol_type_identifier){
return fail_parse_result();
}
return success_parse_result(field_name->next,
ycf_pointer_field_access_new(pointer, field_name));
}
ycf_parse_result parse_period_field_access_node(ycf_symbol* symbols){
ycf_symbol* p = symbols;
if(p->type != ycf_symbol_type_period){
return fail_parse_result();
}
ycf_symbol* field_name = p->next;
if(field_name->type != ycf_symbol_type_identifier){
return fail_parse_result();
}
return success_parse_result(field_name->next,
ycf_node_period_field_access_new(p, field_name));
}
ycf_parse_result parse_function_call(ycf_symbol* symbols);
ycf_parse_result parse_expression_generic(ycf_symbol* symbols,
bool use_end_symbol,
bool no_function_call_assignment,
int nr_of_end_symbols,
ycf_symbol_type end_symbols[]);
ycf_parse_result parse_paran_expression(ycf_symbol* symbols){
if(symbols->type != ycf_symbol_type_open_parenthesis){
return fail_parse_result();
}
ycf_symbol* start = symbols;
ycf_parse_result exp = parse_expression_generic(start->next,
true,
false,
1,
(ycf_symbol_type[]){ycf_symbol_type_end_parenthesis});
if(!exp.success || exp.next_symbol->type != ycf_symbol_type_end_parenthesis ){
return fail_parse_result();
}
return success_parse_result(exp.next_symbol->next,
ycf_node_paran_expression_new(start,
exp.result->u.expression,
exp.next_symbol));
}
ycf_parse_result parse_function_call_assignment(ycf_symbol* symbols);
ycf_parse_result parse_assignment(ycf_symbol* symbols);
ycf_parse_result parse_expression_generic(ycf_symbol* symbols,
bool use_end_symbol,
bool no_function_call_assignment,
int nr_of_end_symbols,
ycf_symbol_type end_symbols[]){
int number_of_parsers = (!no_function_call_assignment ? 1 : 0) + 5;
ycf_parse_result (*parsers[7])(ycf_symbol *);
if(!no_function_call_assignment){
parsers[0] = parse_function_call;
parsers[1] = parse_function_call_assignment;
parsers[2] = parse_paran_expression;
parsers[3] = parse_period_field_access_node;
parsers[4] = parse_pointer_field_access_node;
parsers[5] = parse_other;
}else{
parsers[0] = parse_function_call;
parsers[1] = parse_paran_expression;
parsers[2] = parse_period_field_access_node;
parsers[3] = parse_pointer_field_access_node;
parsers[4] = parse_other;
}
parse_list_res res = parse_list_break_symbols(number_of_parsers, parsers, symbols, nr_of_end_symbols,end_symbols);
if(res.list.head == NULL || (use_end_symbol &&
(res.next_symbol == NULL ||res.next_symbol->type != end_symbols[0]))){
return fail_parse_result();
}
return success_parse_result(res.next_symbol,
ycf_node_expression_new(res.list));
}
ycf_parse_result parse_expression(ycf_symbol* symbols){
return parse_expression_generic(symbols,
false,
false,
0 /* ignored */,
NULL);
}
ycf_parse_result parse_expression_end_comma(ycf_symbol* symbols){
return parse_expression_generic(symbols,
true,
false,
2,
(ycf_symbol_type[]){ycf_symbol_type_comma, ycf_symbol_type_end_parenthesis});
}
ycf_parse_result parse_expression_end_end_paren(ycf_symbol* symbols){
return parse_expression_generic(symbols,
true,
false,
1,
(ycf_symbol_type[]){ycf_symbol_type_end_parenthesis});
}
ycf_parse_result parse_expression_end_end_semicolon(ycf_symbol* symbols){
return parse_expression_generic(symbols,
true,
false,
1,
(ycf_symbol_type[]){ycf_symbol_type_semicolon});
}
ycf_parse_result parse_expression_end_end_squarebracket(ycf_symbol* symbols){
return parse_expression_generic(symbols,
true,
false,
1,
(ycf_symbol_type[]){ycf_symbol_type_end_square_bracket});
}
ycf_parse_result parse_function_call(ycf_symbol* symbols){
parse_symbol_list_res negs;
{
/* Parse neg symbols */
int nr_of_aloved_symbols = 1;
ycf_symbol_type accept_symbols[1];
accept_symbols[0] = ycf_symbol_type_neg;
negs =
parse_symbol_list(nr_of_aloved_symbols,
accept_symbols,
symbols);
}
ycf_symbol* ident = negs.next_symbol;
if(ident == NULL ||
ident->type != ycf_symbol_type_identifier){
return fail_parse_result();
}
ycf_symbol* paran_start = ident->next;
if(paran_start == NULL || paran_start->type != ycf_symbol_type_open_parenthesis){
return fail_parse_result();
}
int number_of_parsers = 3;
ycf_parse_result (*parsers[])(ycf_symbol *) = {
parse_comma,
parse_expression_end_comma,
parse_expression_end_end_paren
};
parse_list_res param_list_res =
parse_list_break_symbol(number_of_parsers,
parsers,
paran_start->next,
ycf_symbol_type_end_parenthesis);
if(param_list_res.next_symbol == NULL ||
param_list_res.next_symbol->type != ycf_symbol_type_end_parenthesis){
return fail_parse_result();
}
return success_parse_result(param_list_res.next_symbol->next,
ycf_node_function_call_new(negs.list,
ident,
paran_start,
param_list_res.list,
param_list_res.next_symbol));
}
ycf_parse_result parse_assignment(ycf_symbol* symbols) {
if(symbols->type != ycf_symbol_type_identifier){
return fail_parse_result();
}
if(symbols->next == NULL || symbols->next->type != ycf_symbol_type_equal_sign){
return fail_parse_result();
}
ycf_parse_result left_expression = parse_expression_generic(symbols,
false,
true,
3,
(ycf_symbol_type[]){
ycf_symbol_type_equal_sign,
ycf_symbol_type_semicolon,
ycf_symbol_type_end_parenthesis});
if(!left_expression.success){
return fail_parse_result();
}
ycf_symbol* equal_sign = left_expression.next_symbol;
if(equal_sign == NULL || equal_sign->type != ycf_symbol_type_equal_sign) {
return fail_parse_result();
}
if(equal_sign->next == NULL || equal_sign->next->type != ycf_symbol_type_identifier){
return fail_parse_result();
}
if(equal_sign->next->next == NULL || equal_sign->next->next->type != ycf_symbol_type_semicolon){
return fail_parse_result();
}
ycf_parse_result right_expression = parse_expression_generic(equal_sign->next,
false,
true,
3,
(ycf_symbol_type[]){
ycf_symbol_type_semicolon,
ycf_symbol_type_equal_sign,
ycf_symbol_type_end_parenthesis});
if(!right_expression.success ||
right_expression.next_symbol == NULL ||
right_expression.next_symbol->type != ycf_symbol_type_semicolon){
return fail_parse_result();
}
ycf_node* node = ycf_node_assignment_new(left_expression.result->u.expression,
ycf_symbol_copy(equal_sign),
right_expression.result->u.expression,
ycf_symbol_copy(right_expression.next_symbol));
return success_parse_result(right_expression.next_symbol->next,
node);
}
ycf_parse_result parse_function_call_assignment(ycf_symbol* symbols){
ycf_parse_result expression = parse_expression_generic(symbols,
true,
true,
3,
(ycf_symbol_type[]){ycf_symbol_type_equal_sign,
ycf_symbol_type_semicolon,
ycf_symbol_type_end_parenthesis});
if(!expression.success){
return fail_parse_result();
}
ycf_symbol* equal_sign = expression.next_symbol;
ycf_parse_result fun_call = parse_function_call(equal_sign->next);
if(!fun_call.success){
return fail_parse_result();
}
return success_parse_result(fun_call.next_symbol,
ycf_node_fun_call_assignment_new(expression.result->u.expression,
equal_sign,
fun_call.result->u.function_call));
}
ycf_parse_result parse_function_call_assignment_statement(ycf_symbol* symbols){
ycf_parse_result fun_call_ass = parse_function_call_assignment(symbols);
if(!fun_call_ass.success || fun_call_ass.next_symbol->type != ycf_symbol_type_semicolon){
return fail_parse_result();
}
return success_parse_result(fun_call_ass.next_symbol->next,
ycf_node_statement_new(fun_call_ass.result,
fun_call_ass.next_symbol));
}
ycf_parse_result parse_function_call_statement(ycf_symbol* symbols){
ycf_parse_result fun_call = parse_function_call(symbols);
if(!fun_call.success || fun_call.next_symbol->type != ycf_symbol_type_semicolon){
return fail_parse_result();
}
return success_parse_result(fun_call.next_symbol->next,
ycf_node_statement_new(fun_call.result,
fun_call.next_symbol));
}
ycf_parse_result parse_statement(ycf_symbol* symbols);
ycf_parse_result parse_cond_statement(ycf_symbol* symbols, ycf_symbol_type cond_keyword){
if(symbols->type != cond_keyword){
return fail_parse_result();
}
ycf_symbol* cond_word = symbols;
ycf_parse_result cond_exp = parse_paran_expression(cond_word->next);
if(!cond_exp.success){
return fail_parse_result();
}
ycf_parse_result cond_statement = parse_statement(cond_exp.next_symbol);
if(!cond_statement.success){
return fail_parse_result();
}
/* Return if node even though it might be something else */
return success_parse_result(cond_statement.next_symbol,
ycf_node_if_new(cond_word,
cond_exp.result->u.parentheses_expression,
cond_statement.result));
}
ycf_parse_result parse_if_statement(ycf_symbol* symbols){
return parse_cond_statement(symbols, ycf_symbol_type_if);
}
ycf_parse_result parse_if_else_statement(ycf_symbol* symbols){
ycf_parse_result if_statem = parse_if_statement(symbols);
if(!if_statem.success){
return fail_parse_result();
}
if(if_statem.next_symbol->type != ycf_symbol_type_else){
return fail_parse_result();
}
ycf_symbol* else_w = if_statem.next_symbol;
ycf_parse_result else_statement = parse_statement(else_w->next);
if(!else_statement.success){
return fail_parse_result();
}
return success_parse_result(else_statement.next_symbol,
ycf_node_if_else_new(if_statem.result->u.if_n,
else_w,
else_statement.result));
}
ycf_parse_result parse_while_statement(ycf_symbol* symbols){
ycf_parse_result cond_statem = parse_cond_statement(symbols, ycf_symbol_type_while);
if(!cond_statem.success){
return fail_parse_result();
}
return success_parse_result(cond_statem.next_symbol,
ycf_node_while_new(cond_statem.result->u.if_n.if_word,
cond_statem.result->u.if_n.expression,
cond_statem.result->u.if_n.if_statement));
}
ycf_parse_result parse_do_while_statement(ycf_symbol* symbols){
if(symbols->type != ycf_symbol_type_do){
return fail_parse_result();
}
ycf_symbol* do_word = symbols;
ycf_parse_result statement = parse_statement(do_word->next);
if(!statement.success || statement.next_symbol->type != ycf_symbol_type_while){
return fail_parse_result();
}
ycf_symbol* while_word = statement.next_symbol;
ycf_parse_result cond = parse_paran_expression(while_word->next);
if(!cond.success){
return fail_parse_result();
}
if(cond.next_symbol->type != ycf_symbol_type_semicolon){
return fail_parse_result();
}
return success_parse_result(cond.next_symbol->next,
ycf_node_do_while_new(do_word, statement.result, while_word,
cond.result->u.parentheses_expression, cond.next_symbol));
}
ycf_parse_result parse_for_statement(ycf_symbol* symbols){
if(symbols->type != ycf_symbol_type_for){
return fail_parse_result();
}
ycf_symbol* for_word = symbols;
if(for_word->next->type != ycf_symbol_type_open_parenthesis){
return fail_parse_result();
}
ycf_symbol* start_paran = for_word->next;
ycf_node* init = NULL;
ycf_parse_result init_res = parse_defenition_with_init(start_paran->next);
if(!init_res.success){
init_res = parse_defenition_no_init(start_paran->next);
}
if(!init_res.success){
init_res = parse_exp_statement(start_paran->next);
}
if(!init_res.success){
return fail_parse_result();
}
init = init_res.result;
ycf_node* stop_cond = NULL;
ycf_symbol* stop_cond_end = NULL;
if(init_res.next_symbol->type == ycf_symbol_type_semicolon){
stop_cond_end = init_res.next_symbol;
}else{
ycf_parse_result stop_cond_res = parse_expression_end_end_semicolon(init_res.next_symbol);
if(!stop_cond_res.success || stop_cond_res.next_symbol->type != ycf_symbol_type_semicolon){
return fail_parse_result();
}
stop_cond = stop_cond_res.result;
stop_cond_end = stop_cond_res.next_symbol;
}
ycf_node* end_exp = NULL;
ycf_symbol* end_exp_end = NULL;
if(stop_cond_end->next->type == ycf_symbol_type_end_parenthesis){
end_exp_end = stop_cond_end->next;
}else{
ycf_parse_result end_exp_res = parse_expression_end_end_paren(stop_cond_end->next);
if(!end_exp_res.success || end_exp_res.next_symbol->type != ycf_symbol_type_end_parenthesis){
return fail_parse_result();
}
end_exp = end_exp_res.result;
end_exp_end = end_exp_res.next_symbol;
}
ycf_parse_result for_statement = parse_statement(end_exp_end->next);
if(!for_statement.success){
return fail_parse_result();
}
return success_parse_result(for_statement.next_symbol,
ycf_node_for_new(for_word,
start_paran,
init,
stop_cond,
stop_cond_end,
end_exp,
end_exp_end,
for_statement.result));
}
ycf_parse_result parse_switch_statement(ycf_symbol* symbols){
ycf_parse_result cond_statem = parse_cond_statement(symbols, ycf_symbol_type_switch);
if(!cond_statem.success){
return fail_parse_result();
}
if(cond_statem.result->u.if_n.if_statement->type != ycf_node_type_code_scope){
return fail_parse_result();
}
return success_parse_result(cond_statem.next_symbol,
ycf_node_switch_new(cond_statem.result->u.if_n.if_word,
cond_statem.result->u.if_n.expression,
cond_statem.result->u.if_n.if_statement->u.code_scope));
}
ycf_parse_result parse_exp_statement(ycf_symbol* symbols){
if(symbols->type == ycf_symbol_type_semicolon){
/*Empty statement*/
return success_parse_result(symbols->next,
ycf_node_statement_new(ycf_node_expression_new(ycf_node_list_empty()),
symbols));
}
ycf_parse_result expression = parse_expression_end_end_semicolon(symbols);
if(!expression.success || expression.next_symbol->type != ycf_symbol_type_semicolon){
return fail_parse_result();
}
return success_parse_result(expression.next_symbol->next,
ycf_node_statement_new(expression.result,
expression.next_symbol));
}
ycf_parse_result parse_return_statement(ycf_symbol* symbols){
ycf_symbol* return_symbol = symbols;
if(return_symbol->type != ycf_symbol_type_return){
return fail_parse_result();
}
if(return_symbol->next->type == ycf_symbol_type_semicolon){
return success_parse_result(return_symbol->next->next,
ycf_node_return_new(return_symbol,
NULL,
return_symbol->next));
}
ycf_parse_result expression = parse_expression_end_end_semicolon(return_symbol->next);
if(!expression.success || expression.next_symbol->type != ycf_symbol_type_semicolon){
return fail_parse_result();
}
return success_parse_result(expression.next_symbol->next,
ycf_node_return_new(return_symbol,
expression.result,
expression.next_symbol));
}
ycf_parse_result parse_macro_command(ycf_symbol* symbols){
if(symbols->type == ycf_symbol_type_macro_command || symbols->type == ycf_symbol_type_macro_define){
return success_parse_result(symbols->next, ycf_node_macro_cmd_new(symbols));
} else {
return fail_parse_result();
}
}
ycf_parse_result parse_scope(ycf_symbol* symbols);
ycf_parse_result parse_special_code_block(ycf_symbol* symbols, char* code_block_name, ycf_node_type type){
ycf_symbol* start = symbols;
if(symbols->type != ycf_symbol_type_special_code_start ||
!ycf_symbol_is_text_eq(start,
ycf_string_new("/*special_code_start:%s*/", code_block_name))){
return fail_parse_result();
}
ycf_parse_result code = parse_if_statement(start->next);
if(!code.success){
return fail_parse_result();
}
ycf_symbol* end = code.next_symbol;
if(end->type != ycf_symbol_type_special_code_end){
return fail_parse_result();
}
return success_parse_result(end->next,
ycf_node_special_code_block_new(type,
start,
code.result->u.if_n,
end));
}
ycf_parse_result parse_on_save_yield_state(ycf_symbol* symbols){
return parse_special_code_block(symbols, "ON_SAVE_YIELD_STATE", ycf_node_type_on_save_yield_state_code);
}
ycf_parse_result parse_on_restore_yield_state(ycf_symbol* symbols){
return parse_special_code_block(symbols, "ON_RESTORE_YIELD_STATE", ycf_node_type_on_restore_yield_state_code);
}
ycf_parse_result parse_destroy_state_code(ycf_symbol* symbols){
ycf_parse_result res = parse_special_code_block(symbols, "ON_DESTROY_STATE", ycf_node_type_on_destroy_state_code);
return res;
}
ycf_parse_result parse_on_return_code(ycf_symbol* symbols){
ycf_parse_result res = parse_special_code_block(symbols, "ON_RETURN", ycf_node_type_on_return_code);
return res;
}
ycf_parse_result parse_on_destroy_state_or_return_code(ycf_symbol* symbols){
ycf_parse_result res = parse_special_code_block(symbols, "ON_DESTROY_STATE_OR_RETURN", ycf_node_type_on_destroy_state_or_return_code);
return res;
}
ycf_parse_result parse_consume_reds(ycf_symbol* symbols){
ycf_symbol* consume_reds_symbol = symbols;
if(consume_reds_symbol->type != ycf_symbol_type_consume_reds){
return fail_parse_result();
}
ycf_parse_result paran_expression =
parse_paran_expression(consume_reds_symbol->next);
if(!paran_expression.success){
return fail_parse_result();
}
if(paran_expression.next_symbol->type != ycf_symbol_type_semicolon){
return fail_parse_result();
}
return success_parse_result(paran_expression.next_symbol->next,
ycf_node_consume_reds_new(consume_reds_symbol,
paran_expression.result->u.parentheses_expression,
paran_expression.next_symbol));
}
ycf_parse_result parse_statement(ycf_symbol* symbols){
int number_of_parsers = 22;
ycf_parse_result (*parsers[])(ycf_symbol *) = {
parse_defenition_no_init,
parse_defenition_with_init,
parse_if_else_statement,
parse_if_statement,
parse_while_statement,
parse_do_while_statement,
parse_for_statement,
parse_switch_statement,
parse_scope,
parse_goto,
parse_return_statement,
parse_consume_reds,
parse_function_call_statement,
parse_function_call_assignment_statement,
parse_assignment,
parse_on_save_yield_state,
parse_on_restore_yield_state,
parse_on_return_code,
parse_on_destroy_state_or_return_code,
parse_destroy_state_code,
parse_macro_command,
parse_exp_statement
};
for(int i = 0; i < number_of_parsers; i++){
ycf_parse_result res = parsers[i](symbols);
if(res.success){
return res;
}
}
return fail_parse_result();
}
ycf_parse_result parse_scope(ycf_symbol* symbols){
ycf_symbol* current = symbols;
ycf_symbol* start;
if(current->type != ycf_symbol_type_open_curly_brace){
return fail_parse_result();
}
start = current;
current = current->next;
int number_of_parsers = 2;
ycf_parse_result (*parsers[])(ycf_symbol *) = {
parse_defenition_no_init,
parse_defenition_with_init
};
parse_list_res decs = parse_list(number_of_parsers, parsers, current);
current = decs.next_symbol;
/* parse rest */
number_of_parsers = 1;
ycf_parse_result (*rest_parsers[])(ycf_symbol *) = {
parse_statement
};
parse_list_res others =
parse_list_break_symbol(number_of_parsers,
rest_parsers,
current,
ycf_symbol_type_end_curly_brace);
current = others.next_symbol;
if (current == NULL) {
return fail_parse_result();
}
return success_parse_result(current->next, ycf_node_scope_new(start,
decs.list,
others.list,
current));
}
ycf_parse_result parse_function(ycf_symbol* symbols){
ycf_parse_result fun_head = parse_function_head(symbols, ycf_symbol_type_open_curly_brace, true);
if(!fun_head.success){
return fail_parse_result();
}
ycf_parse_result scope = parse_scope(fun_head.next_symbol);
if(!scope.success){
return fail_parse_result();
}
return success_parse_result(scope.next_symbol,
ycf_node_function_new(fun_head.result->u.function_definition,
scope.result->u.code_scope));
}
ycf_parse_result parse_c_file(ycf_symbol* symbols){
int number_of_parsers = 5;
ycf_parse_result (*parsers[])(ycf_symbol *) = {
parse_defenition_no_init,
parse_defenition_with_init,
parse_function_def,
parse_function,
parse_other
};
parse_list_res program_list =
parse_list(number_of_parsers, parsers, symbols);
if(program_list.next_symbol != NULL){
return fail_parse_result();
} else {
return success_parse_result(NULL,
ycf_node_c_file_new(program_list.list));
}
}
ycf_node* get_abstract_syntax_tree_root(ycf_symbol_list* symbols){
ycf_parse_result res = parse_c_file(symbols->head);
if(!res.success){
printf("ERROR: Could not parse file\n");
exit(1);
}
return res.result;
}
ycf_node* ycf_node_deep_copy(ycf_node *n) {
ycf_string_printable_buffer *b = ycf_string_printable_buffer_new();
ycf_node_print(n, b);
ycf_symbol_list symbols = ycf_symbol_list_from_text(b->buffer);
ycf_parse_result res;
if (n->type == ycf_node_type_c_file) {
res = parse_c_file(symbols.head);
} else if (n->type == ycf_node_type_variable_definition ||
n->type == ycf_node_type_variable_definition_init ||
n->type == ycf_node_type_other ||
n->type == ycf_node_type_code_scope ||
n->type == ycf_node_type_assignment ||
n->type == ycf_node_type_yield ||
n->type == ycf_node_type_statement ||
n->type == ycf_node_type_if ||
n->type == ycf_node_type_if_else ||
n->type == ycf_node_type_while ||
n->type == ycf_node_type_do_while ||
n->type == ycf_node_type_switch ||
n->type == ycf_node_type_for ||
n->type == ycf_node_type_assignment_function_call ||
n->type == ycf_node_type_on_save_yield_state_code ||
n->type == ycf_node_type_on_restore_yield_state_code ||
n->type == ycf_node_type_on_destroy_state_code ||
n->type == ycf_node_type_on_return_code ||
n->type == ycf_node_type_on_destroy_state_or_return_code ||
n->type == ycf_node_type_goto ||
n->type == ycf_node_type_return_statement ||
n->type == ycf_node_type_consume_reds) {
res = parse_statement(symbols.head);
} else if (n->type == ycf_node_type_function_declaration) {
res = parse_function_def(symbols.head);
} else if (n->type == ycf_node_type_function_definition) {
res = parse_function(symbols.head);
} else if (n->type == ycf_node_type_function_call) {
res = parse_function_call(symbols.head);
} else if (n->type == ycf_node_type_expression) {
res = parse_expression(symbols.head);
} else if (n->type == ycf_node_type_parentheses_expression) {
res = parse_paran_expression(symbols.head);
} else if (n->type == ycf_node_type_comma) {
res = parse_comma(symbols.head);
} else if (n->type == ycf_node_type_array_bracket) {
res = parse_array_bracket(symbols.head);
} else if (n->type == ycf_node_type_macro_cmd) {
res = parse_macro_command(symbols.head);
} else if (n->type == ycf_node_type_period_field_access) {
res = parse_period_field_access_node(symbols.head);
} else if (n->type == ycf_node_type_pointer_field_access) {
res = parse_pointer_field_access_node(symbols.head);
} else {
fprintf(stderr, "Unknown node type %d\n", n->type);
exit(1);
}
if(!res.success) {
fprintf(stderr, "An error has been detected in the function ycf_node_deep_copy\n");
exit(1);
}
return res.result;
}