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 process_node_group(parse_tree_nodes
& arguments
, parse_tree_nodes
& output
)
28 parse_tree_node new_node
;
29 operator_resolution(arguments
, new_node
);
30 output
.push_back(new_node
);
33 void parser::process_atomic_statement(lexeme_container
& lexemes
, std::size_t & offset
, parse_tree_nodes
& output
, bool allow_multi_statements
, lexeme_type::type terminator
)
35 bool got_last_group
= false;
36 lexeme_group::type last_group
;
38 parse_tree_nodes arguments
;
40 symbol_prefix::type prefix
= symbol_prefix::none
;
42 for(std::size_t & i
= offset
, end
= lexemes
.size(); i
< end
; i
++)
44 lexeme
& current_lexeme
= lexemes
[i
];
46 if(current_lexeme
.type
== terminator
)
51 else if(prefix
!= symbol_prefix::none
&& current_lexeme
.type
== lexeme_type::name
)
52 error("Invalid use of a symbol prefix");
54 switch(current_lexeme
.type
)
56 case lexeme_type::scope_operator
:
57 prefix
= symbol_prefix::scope_operator
;
60 case lexeme_type::class_operator
:
61 prefix
= symbol_prefix::class_operator
;
64 case lexeme_type::bracket_start
:
66 parse_tree_nodes content
;
67 if(got_last_group
&& last_group
== lexeme_group::argument
)
69 process_atomic_statement(lexemes
, offset
, content
, true, lexeme_type::bracket_end
);
72 call
.call_pointer
->arguments
= content
;
73 arguments
.push_back(call
);
77 process_atomic_statement(lexemes
, offset
, content
, false, lexeme_type::bracket_end
);
78 arguments
.push_back(content
[0]);
80 set_last_group(lexeme_group::argument
, last_group
, got_last_group
);
84 case lexeme_type::bracket_end
:
85 error("Unmatched closing bracket");
87 case lexeme_type::array_start
:
89 parse_tree_nodes elements
;
90 process_atomic_statement(lexemes
, offset
, elements
, true, lexeme_type::array_end
);
91 arguments
.push_back(parse_tree_node(elements
));
92 set_last_group(lexeme_group::argument
, last_group
, got_last_group
);
96 case lexeme_type::array_end
:
97 error("Unmatched curled brace");
99 case lexeme_type::call_operator
:
100 arguments
.push_back(parse_tree_node(parse_tree_node_type::call_operator
));
101 set_last_group(lexeme_group::call_operator
, last_group
, got_last_group
);
104 case lexeme_type::spaced_call_operator
:
105 arguments
.push_back(parse_tree_node(parse_tree_node_type::spaced_call_operator
));
106 set_last_group(lexeme_group::call_operator
, last_group
, got_last_group
);
109 case lexeme_type::iterator
:
110 arguments
.push_back(parse_tree_node(parse_tree_node_type::iterator
));
111 set_last_group(lexeme_group::argument
, last_group
, got_last_group
);
115 lexeme_group::type group
;
116 if(!get_lexeme_group(current_lexeme
.type
, group
))
117 error("Invalid lexeme type in statement (" + current_lexeme
.to_string() + ")");
121 case lexeme_group::argument
:
123 if(!allow_multi_statements
&& got_last_group
&& last_group
== lexeme_group::argument
)
124 error("Encountered two arguments without an operator between them");
126 parse_tree_node argument_node
;
127 lexeme_to_argument_node(current_lexeme
, argument_node
);
128 if(current_lexeme
.type
== lexeme_type::name
)
130 argument_node
.symbol_pointer
->type
= prefix
;
131 if(prefix
!= symbol_prefix::none
)
135 argument_node
.type
== parse_tree_node_type::binary_operator_node
&&
136 argument_node
.binary_operator_pointer
->type
== binary_operator_type::selection
138 error("Encountered a symbol prefix after a selection operator");
139 prefix
= symbol_prefix::none
;
142 arguments
.push_back(argument_node
);
144 if(allow_multi_statements
)
146 process_node_group(arguments
, output
);
148 got_last_group
= false;
154 case lexeme_group::unary_operator
:
155 if(got_last_group
&& last_group
== lexeme_group::argument
)
156 error("Encountered an argument followed by an unary operator without a binary operator between them");
157 add_unary_node(current_lexeme
, arguments
);
160 case lexeme_group::binary_operator
:
165 case lexeme_group::unary_operator
:
166 error("Encountered a unary operator followed by a binary operator");
168 case lexeme_group::binary_operator
:
169 if(current_lexeme
.type
== lexeme_type::subtraction
)
170 add_negation_lexeme(arguments
);
172 error("Encountered two sequential binary operators");
178 if(current_lexeme
.type
== lexeme_type::subtraction
)
179 add_negation_lexeme(arguments
);
181 error("Encountered a binary operator in the beginning of a statement");
184 parse_tree_node binary_operator_node
;
185 lexeme_to_binary_operator_node(current_lexeme
, binary_operator_node
);
186 arguments
.push_back(binary_operator_node
);
190 set_last_group(group
, last_group
, got_last_group
);
194 error("Empty statement");
196 if(last_group
!= lexeme_group::argument
)
197 error("An operator is missing an argument");
199 process_node_group(arguments
, output
);