mirror of
https://github.com/ChaiScript/ChaiScript.git
synced 2025-12-07 17:26:55 +08:00
A few parser cleanups
This commit is contained in:
parent
57aa874c6e
commit
f3f84594ee
@ -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)];
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user