1 #include <ail/file.hpp>
2 #include <ail/string.hpp>
3 #include <fridh/parser.hpp>
4 #include <fridh/lexer.hpp>
8 void set_last_group(lexeme_group::type new_last_group
, lexeme_group::type
& last_group
, bool & got_last_group
)
10 last_group
= new_last_group
;
11 got_last_group
= true;
14 void add_unary_node(lexeme
& current_lexeme
, parse_tree_nodes
& arguments
)
16 parse_tree_node unary_operator_node
;
17 lexeme_to_unary_operator_node(current_lexeme
, unary_operator_node
);
18 arguments
.push_back(unary_operator_node
);
21 void add_negation_lexeme(parse_tree_nodes
& arguments
)
23 add_unary_node(lexeme(lexeme_type::negation
), arguments
);
26 void visualise_nodes(parse_tree_nodes
& nodes
)
28 std::cout
<< "Parse tree nodes:" << std::endl
;
30 for(parse_tree_nodes::iterator i
= nodes
.begin(), end
= nodes
.end(); i
!= end
; i
++, counter
++)
31 std::cout
<< counter
<< ". " << i
->to_string() << std::endl
;
34 void parser::process_node_group(parse_tree_nodes
& arguments
, parse_tree_nodes
& output
)
36 std::cout
<< "process_node_group" << std::endl
;
37 visualise_nodes(arguments
);
38 parse_tree_node new_node
;
39 std::cout
<< "new_node:" << std::endl
;
40 std::cout
<< new_node
.to_string() << std::endl
;
41 operator_resolution(arguments
, new_node
);
42 std::cout
<< "operator_resolution returned:" << std::endl
;
43 std::cout
<< new_node
.to_string() << std::endl
;
44 output
.push_back(new_node
);
45 std::cout
<< "/process_node_group" << std::endl
;
48 void parser::process_atomic_statement(lexeme_container
& lexemes
, std::size_t & offset
, parse_tree_nodes
& output
, bool allow_multi_statements
, lexeme_type::type terminator
)
50 bool got_last_group
= false;
51 lexeme_group::type last_group
;
53 parse_tree_nodes arguments
;
55 symbol_prefix::type prefix
= symbol_prefix::none
;
57 for(std::size_t & i
= offset
, end
= lexemes
.size(); i
< end
; i
++)
59 lexeme
& current_lexeme
= lexemes
[i
];
61 if(current_lexeme
.type
== terminator
)
66 else if(prefix
!= symbol_prefix::none
&& current_lexeme
.type
!= lexeme_type::name
)
67 double_lexeme_error("Invalid use of a symbol prefix", i
);
69 switch(current_lexeme
.type
)
71 case lexeme_type::scope_operator
:
72 prefix
= symbol_prefix::scope_operator
;
75 case lexeme_type::class_operator
:
76 prefix
= symbol_prefix::class_operator
;
79 case lexeme_type::bracket_start
:
81 parse_tree_nodes content
;
82 if(got_last_group
&& last_group
== lexeme_group::argument
)
84 process_atomic_statement(lexemes
, offset
, content
, true, lexeme_type::bracket_end
);
87 call
.call_pointer
->arguments
= content
;
88 arguments
.push_back(call
);
92 process_atomic_statement(lexemes
, offset
, content
, false, lexeme_type::bracket_end
);
93 arguments
.push_back(content
[0]);
95 set_last_group(lexeme_group::argument
, last_group
, got_last_group
);
99 case lexeme_type::bracket_end
:
100 error("Unmatched closing bracket");
102 case lexeme_type::array_start
:
104 parse_tree_nodes elements
;
105 process_atomic_statement(lexemes
, offset
, elements
, true, lexeme_type::array_end
);
106 arguments
.push_back(parse_tree_node(elements
));
107 set_last_group(lexeme_group::argument
, last_group
, got_last_group
);
111 case lexeme_type::array_end
:
112 error("Unmatched curled brace");
114 case lexeme_type::call_operator
:
115 arguments
.push_back(parse_tree_node(parse_tree_node_type::call_operator
));
116 set_last_group(lexeme_group::call_operator
, last_group
, got_last_group
);
119 case lexeme_type::spaced_call_operator
:
120 arguments
.push_back(parse_tree_node(parse_tree_node_type::spaced_call_operator
));
121 set_last_group(lexeme_group::call_operator
, last_group
, got_last_group
);
124 case lexeme_type::iterator
:
125 arguments
.push_back(parse_tree_node(parse_tree_node_type::iterator
));
126 set_last_group(lexeme_group::argument
, last_group
, got_last_group
);
130 lexeme_group::type group
;
131 if(!get_lexeme_group(current_lexeme
.type
, group
))
132 single_lexeme_error("Invalid lexeme type in statement", i
);
136 case lexeme_group::argument
:
138 if(got_last_group
&& last_group
== lexeme_group::argument
)
140 if(allow_multi_statements
)
142 process_node_group(arguments
, output
);
144 got_last_group
= false;
147 double_lexeme_error("Encountered two arguments without an operator between them", i
);
150 parse_tree_node argument_node
;
151 lexeme_to_argument_node(current_lexeme
, argument_node
);
152 if(current_lexeme
.type
== lexeme_type::name
)
154 argument_node
.symbol_pointer
->type
= prefix
;
155 if(prefix
!= symbol_prefix::none
)
159 argument_node
.type
== parse_tree_node_type::binary_operator_node
&&
160 argument_node
.binary_operator_pointer
->type
== binary_operator_type::selection
162 double_lexeme_error("Encountered a symbol prefix after a selection operator", i
);
163 prefix
= symbol_prefix::none
;
166 //std::cout << "Pushing " << argument_node.to_string() << std::endl;
167 arguments
.push_back(argument_node
);
168 //visualise_nodes(arguments);
172 case lexeme_group::unary_operator
:
173 if(got_last_group
&& last_group
== lexeme_group::argument
)
174 double_lexeme_error("Encountered an argument followed by a unary operator without a binary operator between them", i
);
175 add_unary_node(current_lexeme
, arguments
);
178 case lexeme_group::binary_operator
:
184 case lexeme_group::unary_operator
:
185 double_lexeme_error("Encountered a unary operator followed by a binary operator", i
);
187 case lexeme_group::binary_operator
:
188 if(current_lexeme
.type
== lexeme_type::subtraction
)
189 add_negation_lexeme(arguments
);
191 double_lexeme_error("Encountered two sequential binary operators", i
);
197 if(current_lexeme
.type
== lexeme_type::subtraction
)
198 add_negation_lexeme(arguments
);
200 single_lexeme_error("Encountered a binary operator in the beginning of a statement", i
);
204 parse_tree_node binary_operator_node
;
205 lexeme_to_binary_operator_node(current_lexeme
, binary_operator_node
);
206 arguments
.push_back(binary_operator_node
);
210 case lexeme_group::post_fix_operator
:
213 if(last_group
!= lexeme_group::argument
)
214 single_lexeme_error("Encountered a post fix operator after a non-argument", i
);
217 single_lexeme_error("A post fix operator requires a previous argument", i
);
219 add_unary_node(current_lexeme
, arguments
);
220 set_last_group(lexeme_group::argument
, last_group
, got_last_group
);
224 set_last_group(group
, last_group
, got_last_group
);
228 error("Empty statement");
230 if(last_group
!= lexeme_group::argument
)
231 error("An operator is missing an argument");
233 std::cout
<< "Bottom" << std::endl
;
234 visualise_nodes(arguments
);
236 process_node_group(arguments
, output
);