A few parser cleanups

This commit is contained in:
Jason Turner 2016-04-16 12:04:18 -06:00
parent 57aa874c6e
commit f3f84594ee
3 changed files with 74 additions and 92 deletions

View File

@ -32,22 +32,24 @@ namespace chaiscript
/// Types of AST nodes available to the parser and eval /// Types of AST nodes available to the parser and eval
enum class AST_Node_Type { Error, Id, Eol, Fun_Call, Arg_List, Variable, Equation, Var_Decl, enum class AST_Node_Type { Id, Fun_Call, Arg_List, Equation, Var_Decl,
Comparison, Addition, Subtraction, Multiplication, Division, Modulus, Array_Call, Dot_Access, Array_Call, Dot_Access,
Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range, Lambda, Block, Def, While, If, For, Inline_Array, Inline_Map, Return, File, Prefix, Break, Continue, Map_Pair, Value_Range,
Inline_Range, Try, Catch, Finally, Method, Attr_Decl, Shift, Equality, Bitwise_And, Bitwise_Xor, Bitwise_Or, Inline_Range, Try, Catch, Finally, Method, Attr_Decl,
Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl, Constant Logical_And, Logical_Or, Reference, Switch, Case, Default, Ternary_Cond, Noop, Class, Binary, Arg, Global_Decl, Constant
}; };
enum class Operator_Precidence { Ternary_Cond, Logical_Or, Logical_And, Bitwise_Or, Bitwise_Xor, Bitwise_And, Equality, Comparison, Shift, Addition, Multiplication };
namespace namespace
{ {
/// Helper lookup to get the name of each node type /// Helper lookup to get the name of each node type
const char *ast_node_type_to_string(AST_Node_Type ast_node_type) { const char *ast_node_type_to_string(AST_Node_Type ast_node_type) {
static const char * const ast_node_types[] = { "Internal Parser Error", "Id", "Eol", "Fun_Call", "Arg_List", "Variable", "Equation", "Var_Decl", static const char * const ast_node_types[] = { "Id", "Fun_Call", "Arg_List", "Equation", "Var_Decl",
"Comparison", "Addition", "Subtraction", "Multiplication", "Division", "Modulus", "Array_Call", "Dot_Access", "Array_Call", "Dot_Access",
"Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range", "Lambda", "Block", "Def", "While", "If", "For", "Inline_Array", "Inline_Map", "Return", "File", "Prefix", "Break", "Continue", "Map_Pair", "Value_Range",
"Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl", "Shift", "Equality", "Bitwise_And", "Bitwise_Xor", "Bitwise_Or", "Inline_Range", "Try", "Catch", "Finally", "Method", "Attr_Decl",
"Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg", "Constant"}; "Logical_And", "Logical_Or", "Reference", "Switch", "Case", "Default", "Ternary Condition", "Noop", "Class", "Binary", "Arg", "Constant"};
return ast_node_types[static_cast<int>(ast_node_type)]; return ast_node_types[static_cast<int>(ast_node_type)];

View File

@ -146,19 +146,19 @@ namespace chaiscript
} }
static const std::array<AST_Node_Type, 11> &create_operators() { static const std::array<Operator_Precidence, 11> &create_operators() {
static const std::array<AST_Node_Type, 11> operators = { { static const std::array<Operator_Precidence, 11> operators = { {
AST_Node_Type::Ternary_Cond, Operator_Precidence::Ternary_Cond,
AST_Node_Type::Logical_Or, Operator_Precidence::Logical_Or,
AST_Node_Type::Logical_And, Operator_Precidence::Logical_And,
AST_Node_Type::Bitwise_Or, Operator_Precidence::Bitwise_Or,
AST_Node_Type::Bitwise_Xor, Operator_Precidence::Bitwise_Xor,
AST_Node_Type::Bitwise_And, Operator_Precidence::Bitwise_And,
AST_Node_Type::Equality, Operator_Precidence::Equality,
AST_Node_Type::Comparison, Operator_Precidence::Comparison,
AST_Node_Type::Shift, Operator_Precidence::Shift,
AST_Node_Type::Addition, Operator_Precidence::Addition,
AST_Node_Type::Multiplication Operator_Precidence::Multiplication
} }; } };
return operators; return operators;
} }
@ -170,7 +170,7 @@ namespace chaiscript
const std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> &m_alphabet = create_alphabet(); const std::array<std::array<bool, detail::lengthof_alphabet>, detail::max_alphabet> &m_alphabet = create_alphabet();
const std::vector<std::vector<std::string>> &m_operator_matches = create_operator_matches(); const std::vector<std::vector<std::string>> &m_operator_matches = create_operator_matches();
const std::array<AST_Node_Type, 11> &m_operators = create_operators(); const std::array<Operator_Precidence, 11> &m_operators = create_operators();
std::shared_ptr<std::string> m_filename; std::shared_ptr<std::string> m_filename;
std::vector<AST_NodePtr> m_match_stack; std::vector<AST_NodePtr> m_match_stack;
@ -881,11 +881,11 @@ namespace chaiscript
{ {
string_type &match; string_type &match;
typedef typename string_type::value_type char_type; typedef typename string_type::value_type char_type;
bool is_escaped; bool is_escaped = false;
bool is_interpolated; bool is_interpolated = false;
bool saw_interpolation_marker; bool saw_interpolation_marker = false;
bool is_octal; bool is_octal = false;
bool is_hex; bool is_hex = false;
const bool interpolation_allowed; const bool interpolation_allowed;
string_type octal_matches; string_type octal_matches;
@ -893,11 +893,6 @@ namespace chaiscript
Char_Parser(string_type &t_match, const bool t_interpolation_allowed) Char_Parser(string_type &t_match, const bool t_interpolation_allowed)
: match(t_match), : match(t_match),
is_escaped(false),
is_interpolated(false),
saw_interpolation_marker(false),
is_octal(false),
is_hex(false),
interpolation_allowed(t_interpolation_allowed) interpolation_allowed(t_interpolation_allowed)
{ {
} }
@ -1034,13 +1029,11 @@ namespace chaiscript
if (*s == '{') { if (*s == '{') {
//We've found an interpolation point //We've found an interpolation point
if (cparser.is_interpolated) {
//If we've seen previous interpolation, add on instead of making a new one
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(match, start.line, start.col, const_var(match))); m_match_stack.push_back(make_node<eval::Constant_AST_Node>(match, start.line, start.col, const_var(match)));
if (cparser.is_interpolated) {
//If we've seen previous interpolation, add on instead of making a new one
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, "+"); build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, "+");
} else {
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(match, start.line, start.col, const_var(match)));
} }
//We've finished with the part of the string up to this point, so clear it //We've finished with the part of the string up to this point, so clear it
@ -1091,13 +1084,12 @@ namespace chaiscript
return cparser.is_interpolated; return cparser.is_interpolated;
}(); }();
if (is_interpolated) {
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(match, start.line, start.col, const_var(match))); m_match_stack.push_back(make_node<eval::Constant_AST_Node>(match, start.line, start.col, const_var(match)));
if (is_interpolated) {
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, "+"); build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, "+");
} else {
m_match_stack.push_back(make_node<eval::Constant_AST_Node>(match, start.line, start.col, const_var(match)));
} }
return true; return true;
} else { } else {
return false; return false;
@ -1302,13 +1294,12 @@ namespace chaiscript
if (Arg(false)) { if (Arg(false)) {
retval = true; retval = true;
while (Eol()) {} while (Eol()) {}
if (Char(',')) {
do { while (Char(',')) {
while (Eol()) {} while (Eol()) {}
if (!Arg(false)) { if (!Arg(false)) {
throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename);
} }
} while (Char(','));
} }
} }
build_match<eval::Arg_List_AST_Node>(prev_stack_top); build_match<eval::Arg_List_AST_Node>(prev_stack_top);
@ -1328,13 +1319,12 @@ namespace chaiscript
if (Arg()) { if (Arg()) {
retval = true; retval = true;
while (Eol()) {} while (Eol()) {}
if (Char(',')) {
do { while (Char(',')) {
while (Eol()) {} while (Eol()) {}
if (!Arg()) { if (!Arg()) {
throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename);
} }
} while (Char(','));
} }
} }
build_match<eval::Arg_List_AST_Node>(prev_stack_top); build_match<eval::Arg_List_AST_Node>(prev_stack_top);
@ -1355,13 +1345,11 @@ namespace chaiscript
if (Equation()) { if (Equation()) {
retval = true; retval = true;
while (Eol()) {} while (Eol()) {}
if (Char(',')) { while (Char(',')) {
do {
while (Eol()) {} while (Eol()) {}
if (!Equation()) { if (!Equation()) {
throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename); throw exception::eval_error("Unexpected value in parameter list", File_Position(m_position.line, m_position.col), *m_filename);
} }
} while (Char(','));
} }
} }
@ -1385,25 +1373,21 @@ namespace chaiscript
} else if (Map_Pair()) { } else if (Map_Pair()) {
retval = true; retval = true;
while (Eol()) {} while (Eol()) {}
if (Char(',')) { while (Char(',')) {
do {
while (Eol()) {} while (Eol()) {}
if (!Map_Pair()) { if (!Map_Pair()) {
throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename); throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename);
} }
} while (Char(','));
} }
build_match<eval::Arg_List_AST_Node>(prev_stack_top); build_match<eval::Arg_List_AST_Node>(prev_stack_top);
} else if (Operator()) { } else if (Operator()) {
retval = true; retval = true;
while (Eol()) {} while (Eol()) {}
if (Char(',')) { while (Char(',')) {
do {
while (Eol()) {} while (Eol()) {}
if (!Operator()) { if (!Operator()) {
throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename); throw exception::eval_error("Unexpected value in container", File_Position(m_position.line, m_position.col), *m_filename);
} }
} while (Char(','));
} }
build_match<eval::Arg_List_AST_Node>(prev_stack_top); build_match<eval::Arg_List_AST_Node>(prev_stack_top);
} }
@ -2142,36 +2126,33 @@ namespace chaiscript
while (Operator_Helper(t_precedence, oper)) { while (Operator_Helper(t_precedence, oper)) {
while (Eol()) {} while (Eol()) {}
if (!Operator(t_precedence+1)) { if (!Operator(t_precedence+1)) {
throw exception::eval_error("Incomplete " throw exception::eval_error("Incomplete '" + oper + "' expression",
+ std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression",
File_Position(m_position.line, m_position.col), *m_filename); File_Position(m_position.line, m_position.col), *m_filename);
} }
switch (m_operators[t_precedence]) { switch (m_operators[t_precedence]) {
case(AST_Node_Type::Ternary_Cond) : case(Operator_Precidence::Ternary_Cond) :
if (Symbol(":")) { if (Symbol(":")) {
if (!Operator(t_precedence+1)) { if (!Operator(t_precedence+1)) {
throw exception::eval_error("Incomplete " throw exception::eval_error("Incomplete '" + oper + "' expression",
+ std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression",
File_Position(m_position.line, m_position.col), *m_filename); File_Position(m_position.line, m_position.col), *m_filename);
} }
build_match<eval::Ternary_Cond_AST_Node>(prev_stack_top); build_match<eval::Ternary_Cond_AST_Node>(prev_stack_top);
} }
else { else {
throw exception::eval_error("Incomplete " throw exception::eval_error("Incomplete '" + oper + "' expression",
+ std::string(ast_node_type_to_string(m_operators[t_precedence])) + " expression",
File_Position(m_position.line, m_position.col), *m_filename); File_Position(m_position.line, m_position.col), *m_filename);
} }
break; break;
case(AST_Node_Type::Addition) : case(Operator_Precidence::Addition) :
case(AST_Node_Type::Multiplication) : case(Operator_Precidence::Multiplication) :
case(AST_Node_Type::Shift) : case(Operator_Precidence::Shift) :
case(AST_Node_Type::Equality) : case(Operator_Precidence::Equality) :
case(AST_Node_Type::Bitwise_And) : case(Operator_Precidence::Bitwise_And) :
case(AST_Node_Type::Bitwise_Xor) : case(Operator_Precidence::Bitwise_Xor) :
case(AST_Node_Type::Bitwise_Or) : case(Operator_Precidence::Bitwise_Or) :
case(AST_Node_Type::Comparison) : case(Operator_Precidence::Comparison) :
{ {
bool folded = false; bool folded = false;
const auto size = m_match_stack.size(); const auto size = m_match_stack.size();
@ -2205,10 +2186,10 @@ namespace chaiscript
break; break;
case(AST_Node_Type::Logical_And) : case(Operator_Precidence::Logical_And) :
build_match<eval::Logical_And_AST_Node>(prev_stack_top, oper); build_match<eval::Logical_And_AST_Node>(prev_stack_top, oper);
break; break;
case(AST_Node_Type::Logical_Or) : case(Operator_Precidence::Logical_Or) :
build_match<eval::Logical_Or_AST_Node>(prev_stack_top, oper); build_match<eval::Logical_Or_AST_Node>(prev_stack_top, oper);
break; break;

View File

@ -1,7 +1,6 @@
assert_equal(`==`, `==`); assert_equal(`==`, `==`);
assert_not_equal(`==`, `<`); assert_not_equal(`==`, `<`);
assert_equal(`<`.get_arity(), 2); assert_equal(`<`.get_arity(), 2);
assert_equal(`+`.get_annotation(), "Multiple method dispatch function wrapper.");
assert_equal(get_arity.get_contained_functions().size(), 0); assert_equal(get_arity.get_contained_functions().size(), 0);
assert_equal(get_arity.get_arity(), 1); assert_equal(get_arity.get_arity(), 1);
assert_equal(get_arity.get_param_types().size(), 2); assert_equal(get_arity.get_param_types().size(), 2);