1 #include <ail/file.hpp>
2 #include <ail/string.hpp>
3 #include <fridh/parser.hpp>
4 #include <fridh/lexer.hpp>
8 void call_check(std::size_t extremum_offset
)
10 if(extremum_offset
!= 1)
11 throw ail::exception("Invalid call offset encountered during operator resolution");
14 void visualise_parse_tree_nodes(parse_tree_nodes
& input
)
16 for(std::size_t i
= 0; i
< input
.size(); i
++)
17 std::cout
<< (i
+ 1) << ". " << input
[i
].to_string() << std::endl
;
20 void parser::operator_resolution(parse_tree_nodes
& input
, parse_tree_node
& output
)
28 bool got_an_operator
= false;
30 std::size_t extremum_offset
;
32 for(std::size_t i
= 0, end
= input
.size(); i
< end
; i
++)
34 parse_tree_node
& current_node
= input
[i
];
37 bool is_initialised_unary_node
=
38 current_node
.type
== parse_tree_node_type::unary_operator_node
&&
39 current_node
.unary_operator_pointer
->argument
.type
!= parse_tree_node_type::uninitialised
42 bool is_initialised_call_node
=
43 current_node
.type
== parse_tree_node_type::call
&&
48 is_initialised_unary_node
||
49 is_initialised_call_node
55 if(get_parse_tree_node_precedence(current_node
, precedence
))
60 precedence
> extremum
||
61 (is_right_to_left_operator(current_node
) && precedence
== extremum
)
64 got_an_operator
= true;
65 extremum
= precedence
;
70 catch(ail::exception
& exception
)
72 error(exception
.get_message());
77 error("Failed to perform operator resolution");
79 parse_tree_node
& operator_node
= input
[extremum_offset
];
80 std::size_t next_offset
= extremum_offset
+ 1;
81 switch(operator_node
.type
)
83 case parse_tree_node_type::unary_operator_node
:
85 std::size_t argument_offset
;
86 if(operator_node
.is_post_fix())
87 argument_offset
= extremum_offset
- 1;
89 argument_offset
= next_offset
;
91 if(argument_offset
>= input
.size())
92 error("Missing operator for unary argument");
94 parse_tree_unary_operator_node
& unary_operator_node
= *operator_node
.unary_operator_pointer
;
95 unary_operator_node
.argument
= input
[argument_offset
];
96 input
.erase(input
.begin() + argument_offset
);
100 case parse_tree_node_type::binary_operator_node
:
102 parse_tree_binary_operator_node
& binary_operator_node
= *operator_node
.binary_operator_pointer
;
104 if(extremum_offset
== 0)
105 error("Encountered a binary operator which lacks a left hand argument");
106 else if(next_offset
>= input
.size())
107 error("Encountered a binary operator which lacks a right hand argument");
110 left_side(input
.begin(), input
.begin() + extremum_offset
),
111 right_side(input
.begin() + next_offset
, input
.end());
113 operator_resolution(left_side
, binary_operator_node
.left_argument
);
114 operator_resolution(right_side
, binary_operator_node
.right_argument
);
116 output
= operator_node
;
121 case parse_tree_node_type::call
:
122 call_check(extremum_offset
);
123 operator_node
.call_pointer
->function
= input
[0];
124 input
.erase(input
.begin());
127 case parse_tree_node_type::call_operator
:
128 case parse_tree_node_type::spaced_call_operator
:
130 call_check(extremum_offset
);
131 operator_node
.is_call();
132 operator_node
.call_pointer
->function
= input
[0];
133 input
.erase(input
.begin());
135 parse_tree_node
& new_operator_node
= input
[0];
138 if(new_operator_node
.type
!= parse_tree_node_type::spaced_call_operator
&& next_offset
< input
.size())
140 new_operator_node
.call_pointer
->arguments
.push_back(input
[next_offset
]);
141 input
.erase(input
.begin() + next_offset
);
147 error("Invalid operator node type encountered during operator resolution");
150 operator_resolution(input
, output
);